前言
在開始本文之前,先來介紹一下相關內容,大家都知道一些防護SSRF漏洞的代碼一般使用正則來判斷訪問IP是否為內部IP,比如下面這段網上比較常見的正則:
1
2
3
4
5
|
if re.match(r "^192\.168(\.([2][0-4]\d|[2][5][0-5]|[01]?\d?\d)){2}$" , ip_address) or \ re.match(r "^172\.([1][6-9]|[2]\d|3[01])(\.([2][0-4]\d|[2][5][0-5]|[01]?\d?\d)){2}$" , ip_address) or \ re.match(r "^10(\.([2][0-4]\d|[2][5][0-5]|[01]?\d?\d)){3}$" , ip_address): raise Execption( "inner ip" ) |
很明顯這個正則有很多問題,可以有多種方式繞過,比如
1. 利用八進制IP地址繞過
2. 利用十六進制IP地址繞過
3. 利用十進制的IP地址繞過
4. 各種進制組合形成的IP繞過
一般我們常見都是10進制表示的IP,其實系統是可以識別其他進制表示的IP,比如8進制,16進制,或者它們的組合
所以,我們在測試系統是否有SSRF漏洞的時候,有時候需要嘗試各種進制的IP組合,看看是否能繞過系統的防護,于是就有了本文的這個小程序,用于自動生成各種進制形式的IP,以幫助我們進行安全測試,下面話不多說了,來一起看看詳細的介紹:
實例源碼
程序代碼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
#!/usr/bin/env python # -*- coding:utf8 -*- """ 各種進制的IP表示及其它們的組合 """ import socket import struct import itertools def ip_split_by_comma_oct(ip): """ :param ip: :return: """ parsed_result = set () ip_split = str (ip).split( '.' ) ip_split_oct = [ oct ( int (_)) for _ in ip_split] parsed_result.add( '.' .join(ip_split_oct)) return parsed_result def ip_split_by_comma_hex(ip): """ :param ip: :return: """ parsed_result = set () ip_split = str (ip).split( '.' ) ip_split_hex = [ hex ( int (_)) for _ in ip_split] parsed_result.add( '.' .join(ip_split_hex)) return parsed_result def combination_oct_int_ip(ip): """ :param ip: :return: """ result = set () parsed_result = set () ip_split = str (ip).split( '.' ) oct_2 = list (itertools.combinations([ 0 , 1 , 2 , 3 ], 2 )) oct_3 = list (itertools.combinations([ 0 , 1 , 2 , 3 ], 3 )) for n, _ in enumerate (ip_split): _tmp = oct ( int (_)) _delete = ip_split[:n] + ip_split[n + 1 :] _delete.insert(n, _tmp) result.add( tuple (_delete)) for _ in oct_2: _tmp_ip = ip_split[:] _tmp1 = oct ( int (ip_split[_[ 0 ]])) _tmp2 = oct ( int (ip_split[_[ 1 ]])) del _tmp_ip[_[ 0 ]] del _tmp_ip[_[ 1 ] - 1 ] _tmp_ip.insert(_[ 0 ], _tmp1) _tmp_ip.insert(_[ 1 ], _tmp2) result.add( tuple (_tmp_ip)) for _ in oct_3: _tmp_ip = ip_split[:] _tmp1 = oct ( int (ip_split[_[ 0 ]])) _tmp2 = oct ( int (ip_split[_[ 1 ]])) _tmp3 = oct ( int (ip_split[_[ 2 ]])) del _tmp_ip[_[ 0 ]] del _tmp_ip[_[ 1 ] - 1 ] del _tmp_ip[_[ 2 ] - 2 ] _tmp_ip.insert(_[ 0 ], _tmp1) _tmp_ip.insert(_[ 1 ], _tmp2) _tmp_ip.insert(_[ 2 ], _tmp3) result.add( tuple (_tmp_ip)) for _ in result: parsed_result.add( '.' .join(_)) return parsed_result def combination_hex_int_ip(ip): """ :param ip: :return: """ result = set () parsed_result = set () ip_split = str (ip).split( '.' ) hex_2 = list (itertools.combinations([ 0 , 1 , 2 , 3 ], 2 )) hex_3 = list (itertools.combinations([ 0 , 1 , 2 , 3 ], 3 )) for n, _ in enumerate (ip_split): _tmp = hex ( int (_)) _delete = ip_split[:n] + ip_split[n + 1 :] _delete.insert(n, _tmp) result.add( tuple (_delete)) for _ in hex_2: _tmp_ip = ip_split[:] _tmp1 = hex ( int (ip_split[_[ 0 ]])) _tmp2 = hex ( int (ip_split[_[ 1 ]])) del _tmp_ip[_[ 0 ]] del _tmp_ip[_[ 1 ] - 1 ] _tmp_ip.insert(_[ 0 ], _tmp1) _tmp_ip.insert(_[ 1 ], _tmp2) result.add( tuple (_tmp_ip)) for _ in hex_3: _tmp_ip = ip_split[:] _tmp1 = hex ( int (ip_split[_[ 0 ]])) _tmp2 = hex ( int (ip_split[_[ 1 ]])) _tmp3 = hex ( int (ip_split[_[ 2 ]])) del _tmp_ip[_[ 0 ]] del _tmp_ip[_[ 1 ] - 1 ] del _tmp_ip[_[ 2 ] - 2 ] _tmp_ip.insert(_[ 0 ], _tmp1) _tmp_ip.insert(_[ 1 ], _tmp2) _tmp_ip.insert(_[ 2 ], _tmp3) result.add( tuple (_tmp_ip)) for _ in result: parsed_result.add( '.' .join(_)) return parsed_result def combination_hex_int_oct_ip(ip): """ :param ip: :return: """ result = set () parsed_result = set () ip_split = str (ip).split( '.' ) hex_3 = list (itertools.combinations([ 0 , 1 , 2 , 3 ], 3 )) for n1, n2, n3 in hex_3: _tmp_ip = ip_split[:] _tmp_2 = oct ( int (_tmp_ip[n2])) _tmp_3 = hex ( int (_tmp_ip[n3])) del _tmp_ip[n2] del _tmp_ip[n3 - 1 ] _tmp_ip.insert(n2, _tmp_2) _tmp_ip.insert(n3, _tmp_3) result.add( tuple (_tmp_ip)) for _ in result: parsed_result.add( '.' .join(_)) return parsed_result if __name__ = = '__main__' : ip = '10.1.100.1' ip_int = struct.unpack( '!L' , socket.inet_aton(ip))[ 0 ] ip_oct_no_comma = oct (ip_int) ip_hex_no_comma = hex (ip_int) ip_oct_by_comma = ip_split_by_comma_oct(ip) ip_hex_by_comma = ip_split_by_comma_hex(ip) all_result = ip_oct_by_comma | ip_hex_by_comma | combination_oct_int_ip(ip) | combination_hex_int_ip(ip) | combination_hex_int_oct_ip(ip) for _ip in all_result: print _ip |
代碼很容易看懂,首先生成純8進制表示的IP、純16進制表示的IP,然后在分別生成10進制和8進制混合組成的IP,16進制和10進制混合組成的IP, 16進制8進制10進制混合組成的IP,最后輸出各種組合的結果
在使用其他腳本或者工具遍歷測試這個腳本的結果,看看是否能繞過SSRF的防護
部分截圖:
比如生成10.1.100.1 這個IP的其他各種進制形式:
總結
工具雖然簡單,但卻能給我們的滲透測試帶來方便,其實工作中有很多可以總結沉淀的地方,都可以形成工具化,不僅能方便以后工作,還能有助于我們知識的沉淀,加快我們自身實力提升。也希望大家以后也能多多分享。
好了,以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對服務器之家的支持。
原文鏈接:http://www.freebuf.com/sectool/140982.html