天天看点

CTF-Web8(涉及python脚本requests模块)8.天下武功唯快不破

8.天下武功唯快不破

CTF-Web8(涉及python脚本requests模块)8.天下武功唯快不破
CTF-Web8(涉及python脚本requests模块)8.天下武功唯快不破

结合注释及题目名称,我们猜想可能和提交数据的速度有关

首先看源码发现他给的提示:

CTF-Web8(涉及python脚本requests模块)8.天下武功唯快不破

和post的参数有关,那就看看报文吧:

CTF-Web8(涉及python脚本requests模块)8.天下武功唯快不破

发现了一个FLAG参数是用base64编码的,解码后内容是:P0ST_THIS_T0_CH4NGE_FL4G:Hrd54sRiP,试验了几次发现:后的字符是随机的,既然他提示的是快速post提交参数key,那么我们写python代码得到数据提交上去就可以得到flag了,接下来直接写py脚本构造请求头,脚本如下:(注:key:value==> 键:值)

CTF-Web8(涉及python脚本requests模块)8.天下武功唯快不破

拓展思考:

如果考虑更全面的话,脚本如下:

# coding:utf8
import requests
import base64
url = "http://ctf4.shiyanbar.com/web/10.php" # 目标URL
s = requests.Session() # 获取 Session
response = s.get(url) # 打开链接
head = response.headers # 获取响应头
flag = base64.b64decode(head['flag']).split(':')[1] # 获取相应头中的Flag
postData = {'key': flag} # 构造Post请求体
result = s.post(url=url, data=postData) # 利用Post方式发送请求 
# (注意要在同一个Session中 , 有的时候还需要设置Cookies , 但是此题不需要)
print result.text # 打印响应内容           

大致的执行过程就是获取报头中FLAG字段的内容,用base64解码,然后作为key的值构造post请求,最后打印请求响应的内容,即flag,运行结果如下:

CTF-Web8(涉及python脚本requests模块)8.天下武功唯快不破

但这道题很有意思的是,他其实可以不用session,貌似出题人在后台没有用session控制访问(注:不懂的具体可学习php中session来控制页面的访问权限),应该是通过ip的判断实现的用户区分,我做了一个小测试:当获取到一个key值后构造post请求最大的延时时间是3s

CTF-Web8(涉及python脚本requests模块)8.天下武功唯快不破

 想了想他的后台操作应该是这样的:客户端get请求该地址,服务端收到请求会随机生成一个的字符串,加密后作为返回报文的FLAG字段,即base64加密的key值,。同时,后台会将加密前的该值存入数据库,这里会有一个时间判断,超过3s会从数据库中删除,若客户端在3s内获取key值并将他作为参数post后,后台会从数据库中取出进行匹配,匹配成功将会获取flag,但是,从数据库中取出时需要分辨是哪个用户在什么时候存入的(同一个用户可以做连续多次的get请求),所以这里在数据库中的一定有一个ip字段做索引,即做请求操作的ip与对应生成的随机字符串存入数据库,当用户post后会根据该用户的ip来取对应的字符串,与post的字符串做匹配,这样,就可以不用session来控制访问了

  还有一道类似的题,但需要使用session来访问:http://web.sniperoj.cn:10003/

  首先还是抓包看看:

CTF-Web8(涉及python脚本requests模块)8.天下武功唯快不破

可以看到报文里有一个hint和get_flag字段,意思就是将get_flag解密后作为sinperOJ的值,提交post请求获取返回的内容,把get_flag解密后也是随机字符串,但是,他和上面那道题有一个明显的不同,他的最大时间限制大约是24小时,所以,可以推测应该是用了session来控制访问,于是还是和之前的套路一样,写一个脚本来跑,把之前的稍微改一下:

CTF-Web8(涉及python脚本requests模块)8.天下武功唯快不破

运行结果:

CTF-Web8(涉及python脚本requests模块)8.天下武功唯快不破

补充:(来自:https://www.cnblogs.com/huchong/p/7349886.html)

函数:split()

Python中有split()和os.path.split()两个函数,具体作用如下:

split():拆分字符串。通过指定分隔符对字符串进行切片,并返回分割后的字符串列表(list)

os.path.split():按照路径将文件名和路径分割开

一、函数说明

1、split()函数

语法:str.split(str="",num=string.count(str))[n]

参数说明:

str:   表示为分隔符,默认为空格,但是不能为空('')。若字符串中没有分隔符,则把整个字符串作为列表的一个元素

num:表示分割次数。默认为 -1, 即分隔所有。如果存在参数num,则仅分隔成 num+1 个子字符串,并且每一个子字符串可以赋给新的变量

[n]:   表示选取第n个分片

注意:当使用空格作为分隔符时,对于中间为空的项会自动忽略

2、os.path.split()函数

语法:os.path.split('PATH')

参数说明:

  1. PATH指一个文件的全路径作为参数:
  2. 如果给出的是一个目录和文件名,则输出路径和文件名
  3. 如果给出的是一个目录名,则输出路径和为空文件名

二、实例

1、常用实例

CTF-Web8(涉及python脚本requests模块)8.天下武功唯快不破
CTF-Web8(涉及python脚本requests模块)8.天下武功唯快不破

2、去掉换行符

CTF-Web8(涉及python脚本requests模块)8.天下武功唯快不破

3、分离文件名和路径

CTF-Web8(涉及python脚本requests模块)8.天下武功唯快不破

4、一个超级好的例子

CTF-Web8(涉及python脚本requests模块)8.天下武功唯快不破