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,强比较好像不行,给出两个加密后会等于这个格式的字符串QNKCDZO和s878926199a
参考链接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,这符合它们对于 {{ }} 的处理方式
尝试了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() 函数返回一包含本地数字及货币格式信息的数组。
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开头