2019 De1CTF web wp
0x01 SSRF Me
关键词:哈希长度扩展攻击 首先进入网页发现是python源代码,其中发现一些比较重要的路由
@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
index函数打开code.txt展示为主页,getSign函数将随机生成的16位key和param和action拼接最后采用md5加密得到sign,waf屏蔽掉了gopher和file伪协议
@app.route("/geneSign", methods=['GET', 'POST'])
def geneSign():
param = urllib.unquote(request.args.get("param", ""))
action = "scan"
return getSign(action, param)
geneSign路由下可以通过GET方式传入param变量,action固定为scan,调用getSign函数
@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())
De1ta路由下通过Cookie传入action和sign值,通过GET方法传入param值,建立Task类的对象task,调用对象task中的Exec方法生成结果
关键函数Exec:
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
类中若checkSign为True则进入分支,分支中识别action为scan则执行将param代表的文件写入result.txt,而action=read的时候将result.txt中的代码进行读出并打印在页面上。
故我们需要获取flag,则需要获取param=flag.txt并且action=read这种情况下的sign,很明显在代码中并无可能实现,因为在生成sign的时候默认action为scan。因而我们需要采取哈希长度扩展攻击。
知识点:哈希长度扩展攻击 ==> 《白帽子讲web安全》(p275)
-
哈希长度扩展攻击:
-
md5原理:

-
衍生出对于已知hash值hash(salt)和salt长度但未知salt值的情况下可以知道hash(salt padding append)的值,其中padding为根据salt长度产生的填充,append为任意数据 -
由于md5在对原始数据进行512bit一组的分组后,采用初始向量(4*32bit)进行加密,每一轮的加密结果(128bit)分割为四组作为下一轮加密的初始向量,因而对于hash(salt),我们通过填充padding从而让hash(salt)成为下一轮加密append的初始向量,从而完成对hash(salt padding append)的计算 -
可以采用工具hashpump
-
使用方式:

- 其中Key Length指增加data之前的所有内容长度
采用哈希长度扩展攻击,利用hashpump计算出需要填充的字节数,在这个情况下,我们需要操作的变量为action,我们需要将action的scan变为read,因而我们通过哈希长度扩展攻击获得我们所需要的md5值,即sign
最终我们用burpSuite抓包发送请求获取flag
