!Underflow
[*] 'C:\\Users\\26597\\Desktop\\exploit-me'
Arch: amd64-64-little
RELRO: No RELRO
Stack: No canary found
NX: NX unknown - GNU_STACK missing
PIE: No PIE (0x400000)
Stack: Executable
RWX: Has RWX segments
Stripped: No
IDA打开
int print_flag()
{
return printf("%s", "ACECTF{buff3r_0v3rfl3w}");
}
jumPIEng
C:\Users\26597>nc 34.131.133.224 12346
Main function address: 0x556dc188c1a9
nc连接
返回main函数的地址
发现和附件main函数地址不同
猜测有偏移
多次连接发现main函数的地址一直在变
但始终都会与附件main函数保持固定偏移
比如0x556dc188c1a9 0x559be7ec11a9
结尾都是1a9
而附件main函数地址为11a9
在进行一般加减后发现想要重定向到某个函数就只改后四位(实际解题只用改后三位)
根据附件里函数
.text:0000000000001262 ; __unwind {
.text:0000000000001262 push rbp
.text:0000000000001263 mov rbp, rsp
.text:0000000000001266 sub rsp, 60h
.text:000000000000126A mov rax, fs:28h
.text:0000000000001273 mov [rbp+var_8], rax
.text:0000000000001277 xor eax, eax
.text:0000000000001279 lea rax, s ; "Error: Could not locate 'flag.txt'"
.text:0000000000001280 mov rdi, rax ; s
.text:0000000000001283 call _puts
.text:0000000000001288 lea rax, modes ; "r"
.text:000000000000128F mov rsi, rax ; modes
.text:0000000000001292 lea rax, filename ; "flag.txt"
.text:0000000000001299 mov rdi, rax ; filename
.text:000000000000129C call _fopen
.text:00000000000012A1 mov [rbp+stream], rax
.text:00000000000012A5 cmp [rbp+stream], 0
.text:00000000000012AA jnz short loc_12BD
.text:00000000000012AC lea rax, aRedirectionFai ; "Redirection failed."
.text:00000000000012B3 mov rdi, rax ; s
.text:00000000000012B6 call _puts
.text:00000000000012BB jmp short loc_12FE
.text:00000000000012BD ; ---------------------------------------------------------------------------
所以找到需要输入的后三位:262
连上根据实际main函数地址输入对应重定向的地址就好了
nc 34.131.133.224 12346
Main function address: 0x556dc188c1a9
Enter a redirection address (e.g.- 0x33012a): 0x556dc188c262
0x556dc188c262
Redirecting to address 0x556dc188c262!
Error: Could not locate 'flag.txt'
Flag: ACECTF{57up1d_57up1d_h4rry}
Running Out of Time
main函数:
int __fastcall main(int argc, const char **argv, const char **envp)
{
unsigned int v3; // eax
FILE *v4; // rax
int v5; // eax
char Buffer[44]; // [rsp+20h] [rbp-30h] BYREF
int v8; // [rsp+4Ch] [rbp-4h]
_main();
v3 = time(0LL);
srand(v3);
v8 = rand() % 100;
printf("Provide the correct value: ");
v4 = __iob_func();
fgets(Buffer, 32, v4);
v5 = atoi(Buffer);
if ( v5 == v8 )
p3xr9q_t1zz();
else
puts("Incorrect. Please try again.");
return 0;
}
p3xr9q_t1zz函数:
int p3xr9q_t1zz()
{
_BYTE v1[27]; // [rsp+20h] [rbp-20h]
char v2; // [rsp+3Bh] [rbp-5h]
unsigned int i; // [rsp+3Ch] [rbp-4h]
v1[0] = 29;
v1[1] = 27;
v1[2] = 71;
v1[3] = 25;
v1[4] = 117;
v1[5] = 31;
v1[6] = 29;
v1[7] = 26;
v1[8] = 90;
v1[9] = 90;
v1[10] = 25;
v1[11] = 78;
v2 = 42;
printf("Success! Here is your output: ");
for ( i = 0; i <= 0xB; ++i )
putchar(v2 ^ v1[i]);
return putchar(10);
}
像伪随机漏洞
就是用当前时间戳作为种子来生成随机数
不过这个题没给连接
纯单机交互
直接让ai写个爆破脚本,随机数的值也不大
就0~99
所以只要运气足够好,就能秒出正确返回值
import random
import subprocess
def main():
# 目标程序的路径
target_program_path = r"D:\python\pythonProject\Running_Out_Of_Time.exe"
print("开始暴力破解...")
while True:
# 1. 生成随机数
random_number = random.randint(0, 99) # 假设随机数范围是 [0, 99]
print(f"尝试随机数: {random_number}")
# 2. 运行目标程序,并捕获其输出
try:
process = subprocess.Popen(
[target_program_path],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
shell=False
)
# 3. 将随机数输入到目标程序
output, error = process.communicate(input=f"{random_number}\n", timeout=10)
# 4. 检查目标程序的输出
if "Success" in output or "success" in output:
print(f"找到正确的随机数: {random_number}")
print("目标程序回显内容:")
print(output.strip())
break
else:
print("目标程序输出:", output.strip())
except Exception as e:
print(f"运行目标程序时出错: {e}")
break
if __name__ == "__main__":
main()
运行结果:
D:\python\pythonProject\.venv\Scripts\python.exe "D:\python\pythonProject\Running Out of Time.py"
开始暴力破解...
尝试随机数: 99
找到正确的随机数: 99
目标程序回显内容:
Provide the correct value: Success! Here is your output: 71m3_570pp3d
进程已结束,退出代码为 0
拿到flag
ACECTF{71m3_570pp3d}