admin[hctf 2018]
unicode欺骗、flask session伪造、条件竞争
对源文件的分析学习
code.py
random.sample
多用于截取列表的指定长度的随机数,但是不会改变列表本身的排序:
1 | list = [0,1,2,3,4] |
string.digits
digits方法的作用是生成字符串,包括0-9
string.ascii_letters
a-z A-Z
原来验证码是这样生成的(好神奇
1 | def gene_text(): |
PIL库使用
PIL.image
1)新建图片对象
im = Image.new(‘RGB’,(width, height),’white’)
如果不给color变量赋值,图像内容被设置为0,为黑色
2)预览
im.show()
PIL.ImageDraw
1)新建draw对象
draw=ImageDraw.Draw(im)
2)绘制字符串
draw.text((5+random.randint(-3,3)+23*item, 5+random.randint(-3,3)),
text=code[item], fill=rndColor(),font=font )
第一个参数为绘制开始坐标,第二个参数为需要绘制的文字内容,第三个参数为颜色
高斯模糊
对图像进行模糊处理 使用ImageFilter类
ImageFilter:Python中的图像滤波,主要对图像进行平滑、锐化、边界增强等滤波处理。
im = im.filter(ImageFilter.GaussianBlur(radius=1.5))
高斯模糊 GaussianBlur(radius=2)
Image.save
1 | img.save(img_name, quality=95) |
有些时候往往需要图片的大小不能变化太大或不能太小。所以在使用此方式时可以加入参数。quality参数: 保存图像的质量,值的范围从1(最差)到95(最佳)。 默认值为75,使用中应尽量避免高于95的值; 100会禁用部分JPEG压缩算法,并导致大文件图像质量几乎没有任何增益。
routes.py
and/or
学习出处:https://www.cnblogs.com/yonyong/p/9166067.html
and和or比较的结果不是布尔值,而是比较值之一
and
从左到右演算表达式,如果比较的值都为真,and返回最后一个值
如果某个值为假,and返回第一个假值
or
使用 or 时,在布尔上下文中从左到右演算值,就像 and 一样。如果有一个值为真,or 立刻返回该值 如果所有的值都为假,or 返回最后一个假值 注意 or 在布尔上下文中会一直进行表达式演算直到找到第一个真值,然后就会忽略剩余的比较值
故config.py中
SECRET_KEY = os.environ.get('SECRET_KEY') or 'ckj123'
如果环境变量为空,那么key值将成为’ckj123’
BytesIO
Python在内存中读写数据,用到的模块是StringIO和BytesIO
os.environ.get()
os.environ.get()是python中os模块获取环境变量的一个方法
nodeprep.prepare
nodeprep.prepare函数 nodeprep是从twisted模块中导入的from twisted.words.protocols.jabber.xmpp_stringprep import nodeprep
看师傅博客说 在requirements.txt文件中,发现这里用到的twisted版本是Twisted==10.2.0,而官网最新版本为19.2.0(2019/6/2),版本差距过大可以判断有漏洞(原来如此
学习出处:https://hu3sky.github.io/2019/02/07/hctf/
nodeprep.prepare()
这个函数会把大写转换为小写 并且nodeprep.prepare()会做如下转换
假如有一个ᴬ字符 第一次调用函数时会造成ᴬ->A,第二次调用时会A->a
解题
学习出处:
https://www.cnblogs.com/wangtanzhi/p/11861820.html
https://blog.csdn.net/weixin_44677409/article/details/100733581
1.unicode欺骗
注册一个ᴬdmin账号 此时第一次调用nodeprep.prepare()账号变为
Admin() 此时进行登录,再次调用nodeprep.prepare(),页面显示Hello Admin,此时应已变成admin,修改密码再次调用,修改admin密码 再进行登录
2.flask session伪造
学习出处:https://www.leavesongs.com/PENETRATION/client-session-security.html
大概分为这几步:
- json.dumps 将对象转换成json字符串,作为数据
- 如果数据压缩后长度更短,则用zlib库进行压缩
- 将数据用base64编码
- 通过hmac算法计算数据的签名,将签名附在数据后,用“.”分割
这里还有师傅写的解密的脚本,都记录一下
1 | #!/usr/bin/env python3 |
拿到secret_key以后,伪造session重发即可拿到flag
还根据师傅的博客学习到利用解密session绕过验证码, 不过这道题里的session直接给了验证码hh
3.条件竞争
threading.Thread类
创建线程thread=threading.Thread(target=function_name, args=(function_parameter1, function_parameterN))
function_name: 需要线程去执行的方法名
args: 线程执行方法接收的参数,该属性是一个元组,如果只有一个参数也需要在末尾加逗号。
启动创建的线程thread.start()
requests模块
不带参数get请求r=requests.get('')
带参数的get请求r=requests.get('',params=url_params)
其中字典传递参数url_params={‘key’:’value’}
post请求r=requests.post('')
带参数的post请求r=requests.post(url,data=params)
params同样为字典传递参数
r=requests.post(url,data=params)

r.text输出结果:
1 | { |
- 本文标题:admin[hctf 2018]
- 本文作者:y4ny4n
- 创建时间:2020-09-16 21:20:45
- 本文链接:https://y4ny4n.cn/2020/09/16/2018/
- 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!