<pre style="font-size:14px;white-space:pre-wrap;">Hi,
Description:</pre>
<pre style="font-size:14px;white-space:pre-wrap;">
<pre style="white-space:pre-wrap;">1、When dnsmasq received malformed dns request packets as a DNS forwarder, it forwards the packets to the upstream name server without proper verification.</pre>
</pre>
<pre style="font-size:14px;white-space:pre-wrap;">2、When the DNS forwarder iteratively queries the malicious domain name server, it returns some malformed dns packets, and dnsmasq returns the packet to the client without proper verification, which will give the user a distrust or malicious data. </pre>
<pre style="font-size:14px;white-space:pre-wrap;">Other authoritative dns servers have done correct verification.
Steps to reproduce:
1、Turn on a fake upstream name server, it will only change the flag of the received DNS packet to 0x8180 and return it to the packet sender(dnsmasq).
You can do the above by the python script:
https://643684107.oss-cn-beijing.aliyuncs.com/dnsmasq/dns_server.py
</pre>
<pre style="font-size:14px;white-space:pre-wrap;">Download it and run like this:
python3 dns_server.py 5353<span style="font-family:宋体, arial, Verdana, sans-serif;"></span></pre>
<pre style="font-size:14px;white-space:pre-wrap;">2、start dnsmasq. The configuration options are as follows:
```
port=5353
no-daemon
no-resolv
server = 127.0.0.1
bind-interfaces
no-hosts
```
3、Send the corresponding dns request, the specific construction method of the dns request packet is as follows:
Set the the fifth 4-bytes to 0x00e3(or other numbers except 0x0000), which represents the number of Authority RRs is 0x00e3, and set the authoritative nameservers section to empty.
You can do the above by these two files:</pre>
<pre style="font-size:14px;white-space:pre-wrap;">https://643684107.oss-cn-beijing.aliyuncs.com/dnsmasq/dns_request.py
https://643684107.oss-cn-beijing.aliyuncs.com/dnsmasq/request
</pre>
<pre style="font-size:14px;white-space:pre-wrap;">
<pre style="white-space:pre-wrap;">Download them and run like this:
python3 dns_request.py request 5353
</pre>
<pre style="white-space:pre-wrap;">Then the fake upstream name server will show this:</pre>
<pre style="white-space:pre-wrap;">UDP: Received 32 bytes from ('127.0.0.1', 44486)
0000 DE 0C 01 00 00 01 00 00 00 E3 00 00 06 63 65 72 .............cer
0010 74 30 31 07 65 78 61 6D 70 6C 65 00 00 25 00 01 t01.example..%..
UDP: Sending 32 bytes to ('127.0.0.1', 44486)
0000 DE 0C 81 80 00 01 00 00 00 E3 00 00 06 63 65 72 .............cer
0010 74 30 31 07 65 78 61 6D 70 6C 65 00 00 25 00 01 t01.example..%..
UDP: Done
<div>
</div>
We can find that dnsmasq don't find the request packet is malformed and it forward it to the fake upstream name server.
</pre>
<pre style="white-space:pre-wrap;">Then the client will show this:</pre>
<pre style="white-space:pre-wrap;">Sending DNS query to 127.0.0.1:5353
DNS query data:
0000 31 32 01 00 00 01 00 00 00 E3 00 00 06 63 65 72 12...........cer
0010 74 30 31 07 65 78 61 6D 70 6C 65 00 00 25 00 01 t01.example..%..
Received DNS response from 127.0.0.1:5353
DNS response data:
0000 31 32 81 80 00 01 00 00 00 E3 00 00 06 63 65 72 12...........cer
0010 74 30 31 07 65 78 61 6D 70 6C 65 00 00 25 00 01 t01.example..%..
</pre>
<pre style="white-space:pre-wrap;">We can find that dnsmasq return a malformed dns packet to the client. The flag and the Authority RRs is not changed.
In contrast, Bind(a DNS resolver like Unbound) resturns the correctly formatted dns packet:</pre>
<pre style="white-space:pre-wrap;">Sending DNS query to 127.0.0.1:7777
DNS query data:
0000 31 32 01 00 00 01 00 00 00 E3 00 00 06 63 65 72 12...........cer
0010 74 30 31 07 65 78 61 6D 70 6C 65 00 00 25 00 01 t01.example..%..
Received DNS response from 127.0.0.1:7777
DNS response data:
0000 31 32 81 01 00 01 00 00 00 00 00 00 06 63 65 72 12...........cer
0010 74 30 31 07 65 78 61 6D 70 6C 65 00 00 25 00 01 t01.example..%..
</pre>
<pre style="white-space:pre-wrap;">Thanks
M1ngkvv1nd</pre>
<pre style="white-space:pre-wrap;">Zhejiang University</pre>
<div>
<br>
</div>
</pre>