CTF Writeup

2020 Layer7 CTF Writeup - MISC

LittleDev0617 2020. 11. 19. 21:03

def stage1():
    try:
        data1, data2 = getData()
        filterFunction(data1)
        filterFunction(data2)
        filterSyscall(data1)
        filterSyscall(data2)
        return data1, data2
    except:
        fail("STAGE1")

def stage2(data1, data2):
    with open(PATH + b"bin1", "wb") as f:
        f.write(data1)
    with open(PATH + b"bin2", "wb") as f:
        f.write(data2)
    res1 = sup.check_output([b"file", PATH + b"bin1"])
    res2 = sup.check_output([b"file", PATH + b"bin2"])
    
    if IS_ELF_FILE_MSG%1 not in res1 :
        fail("STAGE2")
    if IS_ELF_FILE_MSG%2 not in res2 :
        fail("STAGE2")

    if IS_NOT_STRIPPED not in res1 :
        fail("STAGE2")
    if IS_NOT_STRIPPED not in res2 :
        fail("STAGE2")


def stage3():
    res1 = sup.check_output([b"md5sum", PATH + b"bin1"]).split(b" ")[0]
    res2 = sup.check_output([b"md5sum", PATH + b"bin2"]).split(b" ")[0]
    if res1 != res2 :
        fail("STAGE3")

def stage4():
    try:
        sup.call([b"chmod", b"+x", PATH + b"bin1"])
        sup.call([b"chmod", b"+x", PATH + b"bin2"])
        res1 = sup.check_output([PATH + b"bin1"])
        res2 = sup.check_output([PATH + b"bin2"])
        if res1 == res2 :
            fail("STAGE4")
    except:

stage1 에서는 두 바이너리에 sys, exec, scanf 등등과 같은 함수가 쓰이는지, 또 syscall 을 하는지 검사를 한다. stage2 에서는 두 바이너리가 64bit elf, dynamic link, not stripped 됐는지 확인한다. stage3 에서는 두 파일의 md5 sum 이 같은지 확인하고, stage4 에서는 두 파일의 실행 결과가 다른지 확인한다.

여기서 md5 sum은 같은데 실행 결과가 달라야 한다가 문제같아보이는데 간단하게 main 함수의 argv[0] 인자를 통해 현재 실행되는 파일명을 puts 함수로 출력해주면 두 파일의 실행 결과가 다르게 나올 것이다.

#include <stdio.h>

int main(int argc,char* argv[])
{
	puts(argv[0]);
	return 0;
}
from pwn import *
from base64 import *
import subprocess as sup

p = remote('211.239.124.243', 18608)

f1 = open('./bin1','rb')
f2 = open('./bin2','rb')

b1 = f1.read()
b2 = f2.read()

b1 = b64encode(b1)
b2 = b64encode(b2)

p.sendlineafter(':',str(len(b1)))
p.sendlineafter(':',str(len(b2)))
p.send(b1)
p.send(b2)

f1.close()
f2.close()

p.interactive()