2021.01.06


W3Challs - Striptease (Reversing, 11pts)


[그림 1] 프로그램 실행 화면


이전 문제와 마찬가지로 ELF 파일을 리버싱하는 문제이다. 우선 칼리에서 해당 프로그램을 실행해보는데… ‘le mot de pass est : pasbon’이라는 문자열만 띄울 뿐이었다. 혹시나 인자가 부족해서 그런가 싶어서 인자들도 좀 넣어봤지만 별 의미는 없었다. 저 문자열은 암호화 된 것 같지는 않고 영어가 아닌 다른 언어로 쓰인 것 같아 번역기를 써보기로 했다.

[그림 2] 암호는..?


프랑스어로 ‘암호는 pasbon’이라고 쓰인 문자열이었다. 아마도 암호라는건 플래그를 의미하는 것일 것이다. 다만 ‘pasbon’ 만으로는 플래그가 되지는 않을 것이고 뭔가 변형을 하거나 다른 문자열과 합쳐서 온전한 플래그가 될 것이다.

아무튼 본격적인 분석을 위해 먼저 gdb로 보려했지만 뭔 짓을 했는지 뭘 보려고 해도 볼 수가 없어서 하는 수 없이 바로 기드라에 던졌다.

[그림 3] main 함수 중 일부


기드라에서 보니, 우선 함수가 딱 하나밖에 안잡힐 정도로 굉장히 작은 프로그램이었다. 덕분에 메인 함수를 찾을 수고를 덜었지만, 문제는 만만치 않았다.

[그림 3]에서 볼 수 있는 부분은 프로그램 내 데이터를 XOR 연산을 통해 수정하는 루틴인데, 수정하는 부분이 프로그램의 코드 영역이라는 것이 문제다.

즉, 우선 [그림 3]의 반복문을 통해 반복문 이후의 코드를 수정한다는 것인데 그렇다면 우선 이 반복문을 먼저 돌려볼 필요가 있다. gdb가 제대로 일을 했다면 저번 문제처럼 반복문이 돌아간 후의 메모리를 보면 됐을텐데, 이번엔 그럴 수가 없으니 코드를 짜서 봐야한다.

[그림 4] 데이터 추출


[그림 4]와 같이 헥스 에디터를 이용해 드래그한 부분의 데이터를 가져온 뒤 기드라에서 보여준 코드를 모방해서 반복문을 만든다. 그리고 그 결과를 바이너리 형태로 볼 수 있게 별도의 파일을 만들어 그곳에 저장하게 했다. 내가 만든 코드는 아래와 같다.

array = bytearray([0x2F, 0x7A, 0xC1, 0xC8, 0xCB, 0xCE, 0x6A, 0xD5, 0xD7, 0xDA,
         0xDD, 0x08, 0xFE, 0xE6, 0xE9, 0xEC, 0x83, 0x97, 0xD5, 0x95,
         0x94, 0x8A, 0x22, 0x61, 0x6D, 0x2B, 0x7E, 0x70, 0x67, 0x64,
         0x3A, 0x78, 0x53, 0x57, 0x06, 0x13, 0x0C, 0x5F, 0x53, 0x46,
         0x5A, 0x54, 0x50, 0x4B, 0x44, 0xD7, 0x14, 0xC4, 0xA1, 0xE9,
         0x4A, 0x59, 0x5C, 0x5F, 0xAF, 0xE5, 0x80, 0x53, 0x6E, 0x71,
         0x74, 0xCF, 0x7E, 0x7D, 0x80, 0x83, 0x3D, 0x88, 0x8C, 0x8F,
         0x92, 0x7D, 0x86, 0x9B, 0x9E, 0xA1, 0xC8, 0xC2, 0x8A, 0xC0,
         0xDF, 0xC7, 0x96, 0xDD, 0xD9, 0x9F, 0xB2, 0xA4, 0xBB, 0xB8,
         0xEE, 0xB4, 0xA7, 0xA3, 0xFA, 0xE7, 0xC0, 0x88, 0x8F, 0x9B,
         0x85, 0x84, 0x9D, 0x80, 0xF2, 0x6B, 0xA0, 0x8B, 0xF4, 0xB2,
         0x16, 0x0E, 0x11, 0x14, 0xDA, 0x9A, 0x8D, 0x9B, 0x23, 0x26,
         0x29, 0x2C, 0x97, 0x33, 0x35, 0x38, 0x3B, 0xF3, 0xC1, 0x00])

IV = 0xBC

for i in range(0x81):
    uVar6 = IV + 3
    if uVar6 > 0xFF:
        uVar6 = uVar6 - 0xFF

    uVar4 = uVar6 ^ array[i]
    IV = uVar6

    array[i] = uVar4

f = open('11pts_.bin', 'wb')
f.write(array)
f.close()

코드가 제대로 돌아갔다면 130바이트짜리 파일이 생성될 것이다. 해당 파일을 열어보면 아래 [그림 5]와 같은 형태를 갖는데…

[그림 5] 수정된 데이터


놀랍게도 읽을 수 있는 문자열 두개가 보인다. 그 중 하나는 맨 처음에 봤던 ‘le mot de pass est : pasbon’이고, 나머지 하나는 검은 선으로 칠해놓은 부분에 쓰여져있다. 만약 내 예상대로 두 문자열을 합한 것이 플래그라면, 문제는 이미 풀린 셈이다.

그래서 플래그를 입력하러 갔더니, 아래와 같은 설명을 볼 수 있었다.

[그림 6] wrong password


‘pasbon’의 뜻이 ‘wrong password’라는데, 그렇다면 두 문자열을 합치는 것이 아니라 그냥 또 다른 문자열이 바로 플래그가 될 것이다. 기다릴 것 없이 입력을 했더니 11점을 얻을 수 있었다!

[그림 7] 풀이 완료!


뭔가 얻어걸린 듯이 푼 것 같지만 일단 풀기는 풀었으니 다행이다.