-
DnsChess
DnsChess (elf 파일)
문제설명
주어진 파일은 총 3개다.
- ChessAI.so
- ChessUI
- capture.pcap
각 파일을 실행시켜서 알아보니까, .so파일의 경우에는 AI가 어떻게 움직이는 지 알려주는 그런 행동양식을 가지고 있는 파일이고, ChessUI의 경우에는 체스판에 대한 UI를 구현해 두었다. 그리고 .pcap파일에는 패킷정보가 있는 데, 모두 DNS 프로토콜을 이용한 것들이었다. 아마도 문제이름이 DnsChess 인건 이것때문인듯...
그래서, Message.txt 파일을 읽어보니 어떤 트래픽이 발견됬는 데, 올바르게 움직여라...? 이런식으로 써져있었음.
잘모르겠고 풀어보도록 하자...
필요한 툴
-
IDA pro
-
WireShark
-
ubuntu
Solution
먼저 .pcap파일을 열어보았다.
눈에 띄는 것은 info 부분이다.
Standard query response 0x6dc5 A knight-g1-f3.game-of-thrones.flare-on.com A 127.252.212.90 NS ns1.game-of-thrones.flare-on.com A 127.0.0.1 OPT
라고 쓰여있었는 데, knight-g1-f3 이라고 써져있는 게 아마 knight가 g1에서 f3으로 움직인 게 아닐까...? 싶다.
다음은 ChessUI 파일을 IDA로 확인해 보았다.
사실 UI 부분에서 많은 시간을 쏟긴 하였지만, 딱히 건진 것은 없었기에 간단히 언급만 하고 지나가겠다.
코드를 잘 살펴보면, 위 처럼 이름 지을 수 있다. 게임을 시작하는 과정, load하는 과정, AI가 thinking 하는 과정등으로 정리를 할 수 있지만, UI는 단순히 게임의 UI를 구현해둔 것으로 얻을수 있는 것이 없었다.
고민을 하다가 열어본 것이 ChessAI.so이다. .so파일의 경우에는 항상 libc.so 류만 받아보았기에 IDA로 열어볼 생각을 하지 못했으나, IDA로 디컴파일이 되더라...
ChessAI.so파일을 열어보면, 여러 함수들이 있는 데, 그중 getNextMove라는 함수가 있었다. 이 함수가 가장 많은 정보들을 가지고 있었다. 아래 코드를 살펴보자.
코드를 보면 dest에 piece를 고르고, 위치를 dest에 붙이고, 또 붙이고 마지막으로 .game-of ~~ 이런 식으로 만드는 것을 볼 수 있다. 이때, 이 텍스트는 위에서 보았던 것이랑 익숙한 텍스트이다.
.pcap파일에서 볼 수 있었던 것이다. 이를 gethostbyname을 통해서 호스트 정보(structure hostent에 대해 알면 좋다.)를 받아오고, 그중 h_addr_list 부분을 통해서 ip주소를 받아온다.
이후 몇차례에 걸쳐서 strange와 flare_on_text를 잘 조작해준다.
저 텍스트가 수상해서 봤더니
flare_on_text라는 곳은 @flare-on... 의 아스키코드였고, strange의 경우에는 어떤 xor하기 전 flag를 담고 있는 듯 하였다.
그래서 파이썬 스크립트를 짜서, xor과정을 거치면 어떤 식으로 flag가 생기는 지 알아보았다.
import subprocess pcap = subprocess.check_output("cat capture.pcap") length = [6,4,6,6,4,6,6,4,4,6,4,5,4,4,4,5,6,6,4,6,4,4,5,5,5,4,6,4,6,6,5,6,6,4,6,6,4,4,4] period = [0,0,0,0,342,344,346] #4 text / 5text(queen) / 6text flareon = [0x40, 0x66, 0x6C, 0x61, 0x72, 0x65, 0x2D, 0x6F, 0x6E, 0x2E, 0x63, 0x6F, 0x6D] strange = [0x79, 0x5A, 0xB8, 0xBC, 0xEC, 0xD3, 0xDF, 0xDD, 0x99, 0xA5, 0xB6, 0xAC, 0x15, 0x36, 0x85, 0x8D, 0x9, 0x8, 0x77, 0x52, 0x4D, 0x71, 0x54, 0x7D, 0xa7, 0xa7, 0x8, 0x16, 0xFD, 0xD7,0x41,0x20] addr = [] location= 289 addr.append(pcap[location:location + 4]) for i in range(len(length)): location = location + period[length[i]] addr.append(pcap[location:location+4]) answer = [0] * 30 print("length of strange : "+str(len(strange)) , "length of addr : "+ str(len(addr))) for i in range(len(addr)): if addr[i][3]&1 : continue temp = addr[i][2] & 0xf answer[2*temp] = addr[i][1] ^ strange[2*temp] answer[2*temp+1] = addr[i][1] ^ strange[2*temp+1] ''' print("Num :"+str(i) +"\ttemp:" + str(temp) + "\tValue:" + hex(answer[2*temp]) +" " + hex(answer[2*temp+1]) + "\taddr[i][1]:"+hex(addr[i][1]) + "\tstrange:" + hex(strange[2*temp])+ " " + hex(strange[2*temp+1])) ''' for j in range(len(flareon)): answer.append(flareon[j]) for i in range(len(answer)): print(chr(answer[i]),end='')
위처럼 짜게 되면 출력값으로
[Running] python -u ".\solution.py" length of strange : 32 length of addr : 40 LooksLikeYouLockedUpTheLookupZ@flare-on.com
이 나온다.
flag: LooksLikeYouLockedUpTheLookupZ@flare-on.com
P.S...
전에 리버싱 관련해서 찾아보다가 유용해 보이는 module을 적어놨었는 데, 그걸 처음으로 사용했음.
subprocess 모듈 앞으로 사용할 일이 많을 것 같다. 사용법이 궁금하면 클릭
그리고 처음에는 so파일을 디컴파일할 생각을 안하고, UI파일을 열심히 분석해보았는 데, 도저히 답이 안나와서 찾아보니, .so파일도 사실 디컴파일이 되더군...
항상 .so파일은 libc밖에 받은 적이 없어서 열어볼 생각조차 안했는 데 이렇게 주어지면 IDA로 열어보아야 한다...
정말 UI는 순수하게 체스판 UI를 구현할 목적으로 설계된 것으로 숨겨진 flag나 그런 것들은 하나도 없더라...
'Writeup > Wargame_Writeup' 카테고리의 다른 글
[Flare-on 2019] Snake (0) 2020.01.21 [Flare-on 2019] Demo (0) 2020.01.21 [pwnable.kr] flag (0) 2020.01.12 [Flare-on 2019] Flarebear (0) 2020.01.09 [Flare-on 2019] Memecat Battlestation Write-up (0) 2020.01.09 댓글