很有趣的問題,突然跟我同事在想要怎麼快速做一個假的DNS (Domain Name Server)? 不就follow
鳥哥的教學,用 bind 架一個就好了?
有想過寫在 /etc/hosts,但發現 nslookup 並不會去查詢 hosts file
Anyway, geek 就喜歡搞怪,喜歡繞道而行,喜歡自己造輪子...
=> 想到用 netcat 當 dns proxy,把 dns query redirect 給 8.8.8.8,但遇到 special 的 domain name 時,就自己 return。
Step1: 測試 dns proxy
$ sudo nc -v -u -l -s 127.0.0.1 -p 53 -e 'nc -u 8.8.8.8 53'
$ nslookup - 127.0.0.1
> yahoo.com
Server: 10.32.100.199
Address: 10.32.100.199#53
Non-authoritative answer:
Name: yahoo.com
Address: 209.191.122.70
Name: yahoo.com
Address: 72.30.38.140
Name: yahoo.com
Address: 98.139.183.24
>
It's work!
想看整個過程,開三個session
$ mkfifo fifo1 fifo2
$ sudo nc -u -l -s 127.0.0.1 -p 53 -c -x > fifo1 < fifo2
Received 27 bytes from the socket
00000000 E2 20 01 00 00 01 00 00 00 00 00 00 05 79 61 68 . ...........yah
00000010 6F 6F 03 63 6F 6D 00 00 01 00 01 oo.com.....
Sent 75 bytes to the socket
00000000 E2 20 81 80 00 01 00 03 00 00 00 00 05 79 61 68 . ...........yah
00000010 6F 6F 03 63 6F 6D 00 00 01 00 01 C0 0C 00 01 00 oo.com..........
00000020 01 00 00 09 80 00 04 62 8B B7 18 C0 0C 00 01 00 .......b........
00000030 01 00 00 09 80 00 04 D1 BF 7A 46 C0 0C 00 01 00 .........zF.....
00000040 01 00 00 09 80 00 04 48 1E 26 8C .......H.&.
$ nc -u 8.8.8.8 53 -x < fifo1 > fifo2
Sent 27 bytes to the socket
00000000 E2 20 01 00 00 01 00 00 00 00 00 00 05 79 61 68 . ...........yah
00000010 6F 6F 03 63 6F 6D 00 00 01 00 01 oo.com.....
Received 75 bytes from the socket
00000000 E2 20 81 80 00 01 00 03 00 00 00 00 05 79 61 68 . ...........yah
00000010 6F 6F 03 63 6F 6D 00 00 01 00 01 C0 0C 00 01 00 oo.com..........
00000020 01 00 00 09 80 00 04 62 8B B7 18 C0 0C 00 01 00 .......b........
00000030 01 00 00 09 80 00 04 D1 BF 7A 46 C0 0C 00 01 00 .........zF.....
00000040 01 00 00 09 80 00 04 48 1E 26 8C .......H.&.
$ nslookup - 127.0.0.1
> yahoo.com
Server: 10.32.100.199
Address: 10.32.100.199#53
Non-authoritative answer:
Name: yahoo.com
Address: 98.139.183.24
Name: yahoo.com
Address: 209.191.122.70
Name: yahoo.com
Address: 72.30.38.140
>
Step 2: 截取 dns query
$ sudo nc -u -l -s 127.0.0.1 -p 53 > fake_query
$ nslookup - 127.0.0.1
> yahoo.com
Step 3: 用 fake_query 去 get response
$ cat fake_query | nc -u 8.8.8.8 53 > fake_response
Step 4: 把 fake_response 內的 ip 換成特定的 ip
(這一步還沒做)
Step 5: Start fake dns
$ mkfifo fifo1 fifo2
$ sudo nc -u -l -s 127.0.0.1 -p 53 -c > fifo1 < fifo2 &
$ sh filter.sh < fifo1 > fifo2
filter.sh 裡面會截取 current query id,然後 replace fake response 裡面的
#!/bin/sh
QID=
COUNT=0
cat - | while read -n 1 byte
do
if [ $COUNT -lt 2 ]; then
QID+=$byte
fi
if [ $COUNT -eq 2 ]; then
echo -n $QID$(cut -b 3- fake_response)
fi
COUNT=`expr $COUNT + 1`
done
結果
$ nslookup - 127.0.0.1
> yahoo.com
;; Got bad packet: bad compression pointer
51 bytes
65 9c 81 80 01 03 05 79 61 68 6f 6f 03 63 6f 6d
01 01 c0 0c 01 01 01 ad 04 d1 bf 7a 46 c0 0c 01
01 01 ad 04 48 1e 26 8c c0 0c 01 01 01 ad 04 62
8b b7 18
>
Oh no~ 還是有問題,初估應該是 dns packet header 哪邊需要動態更改...
Alright! 是該停止這浪費時間的行為了...
參考資料
想利用 shell script 做到這些事情代價真大,以下是必需了解的:
- 以 hex mode 顯示 binary file
hexdump -C file
while read -n 1 byte; do
ord=$(printf "%b" "${byte:-\000}" |
od -t x1 |
{ read offset hex; echo $hex; })
echo "$ord"
done
#!/bin/sh
cat - | while read LINE
do
echo ${LINE}
done
try ls -al | script.sh