CTF/리버싱

[Space Heroes CTF] Cape Kennedy - 리버싱 / Python

SecurityMan 2022. 4. 10. 06:30

쉬움 난이도로 분류되었던 리버싱 문제

하지만 쉽지않았다.. 의외의 복병으로 아주 머리아프게 했던 문제였다.

반응형


문제 설명을 보면 이 프로그램의 유효한 입력값을 찾으라고 한다.

그리고 괄호 안에 이건 테마가 있는 CTF니 정답은 랜덤이 아니다 라고 써 놓은것이 보인다.

처음에 이 괄호안에 있는 문장을 대수롭지 않게 생각했는데

아주 중요한 문구였다.

문제파일로 주어진 moon.py를 다운받아서 열어본다.

import sys

def main():
  if len(sys.argv) != 2:
    print("Invalid args")
    return

  password = sys.argv[1]
  builder = 0
  
  for c in password:
    builder += ord(c)
  
  if builder == 713 and len(password) == 8 and (ord(password[2]) == ord(password[5])):
    if (ord(password[3]) == ord(password[4])) and ((ord(password[6])) == ord(password[7])):
        print("correct")
    else:
        print("incorrect")
  else:
    print("incorrect")

if __name__ == "__main__":
  main()


moon.py는 짧은 파이썬 코드로 작성되어있다.

가장 먼저 sys.argv로 argument의 갯수가 2인지 검증한다.


커맨드라인으로 moon.py를 실행시킬때 moon.py 만 입력하면

Invalid args 라는 에러가 난다.

moon.py를 입력하고 한칸 띄운뒤에 아무글자를 입력해야 첫번째 조건문을 통과하게 된다.

moon.py 1 이라고 입력했을때,

argv[0] = moon.py
argv[1] = 1


이런식으로 값이 들어가기때문에 sys.argv의 길이가 2가 되는것이다.

다음으로 argv[1]에 있는 값을 password 변수에 담아준다.

그리고 나서 password 변수에 있는 문자열의 각 자리 아스키코드의 합을 구하게 된다.(ord 함수)

그 합이 713인지 먼저 검증하고, password가 8글자인지 확인한다.

그런다음 password의 3번째 글자와 6번째 글자 / 4번째 글자와 5번째 글자 / 7번째 글자와 8번째 글자가 같은지 확인한다.

이렇게 모든 조건이 다 맞아떨어지면 correct가 출력되고,

그렇지 않으면 incorrect가 출력되게 된다.

처음에 문제를 풀때는 '이런 조건을 만족시키는 문자가 몇개나 되겠어?' 라고 생각하고

일단 파이썬으로 코드를 짰다.

password = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'

for i in range(len(password)):
    for j in range(len(password)):
        for k in range(len(password)):
            for l in range(len(password)):
                for m in range(len(password)):
                    word = ''
                    word += password[i] + password[j] + password[k] + password[l] + password[m]

                    a = ord(password[i])
                    b = ord(password[j])
                    c = ord(password[k])
                    d = ord(password[l])
                    e = ord(password[m])
                    sum1 = a+b+c+c+d+d+e+e

                    if sum1 == 713:
                        print(password[i] + password[j] + password[k] + password[l] + password[m], sum1)
                        break


password에 들어갈 수 있는 영문자들을 모두 입력해놓고

aaaaaaaa 부터 ZZZZZZZZ 까지 차례대로 문자열을 생성한 뒤에

조건에 만족시키는 문자열이 나올때마다 출력시키는 코드이다.


위에서 짠 코드를 실행시키고 출력값을 data라는 이름의 파일에 저장해보았다.


data 파일을 열어보고 깜짝놀랐는데,

저 조건을 만족하는 단어가 무려 1,955,142개나 있었다...

아무래도 이건 아니다 싶었고

맨 처음에 봤던 테마가 있는 CTF 라는 문구를 떠올렸다.

바로 구글에 문제 제목인 Cape Kennedy 를 검색해보았다.


수많은 검색결과 중에 위키피디아에 있는 Kennedy Space Center 문서를 들어가봤다.


문서를 쭉 내리다 보니 Apollo 라는 단어가 눈에 들어왔다.

문제의 조건처럼 3번째 글자와 6번째 글자가 'o'로 같았고,

4번째 글자와 5번째 글자가 'l' 로 같았다.

문제는 두 글자가 모자라다는 건데


문서를 조금 더 내리다가 Apollo11 이라는 단어를 발견했다.


바로 moon.py Apollo11 로 검증을 해봤고

correct가 뜬것을 확인할 수 있었다.

플래그는 shctf{Apollo11} 이었다.

반응형