본문으로 바로가기

[pwnable.kr] flag 풀이, write-up

category Wargame/pwnable.kr 2018. 11. 2. 13:27

pwnable.kr --- flag



flag 문제는 flag 파일을 reversing 해서 flag를 찾으라는 문제이다.


문제 설명을 보면 아래와 같다.





칼리 리눅스가 아닌 우분투를 사용하고, 모든 툴이 다 설치 되어 있지 않기 때문에 elf 파일임에도 불구하고 window와 linux 환경을 바꿔가며 풀이를 진행했다.


windows 환경에서 chrome의 http://pwnable.kr/bin/flag를 통해 flag 파일을 다운 받았고

linux 환경에서는 wget http://pwnable.kr/bin/flag을 통해 flag 파일을 다운 받았다.


처음 문제풀이를 시작할 때 우분투에서 gdb를 통해 분석하려고 했는데 뭔가 이상했다.




sysbol을 읽을 수 없다... IAT가 깨진것인가?? 혹시 패킹이??



간단한 reversing 문제라고 생각하고 접근할 때, 내가 가장 먼저 하는것은 어떤 언어로 작성 되어있는지, packing이 되어있는지 여부이다.

elf 파일 또한 exe 처럼 판별 가능할 지 모르겠지만, 우선 시도해봤다.


언어 확인과, packing 여부를 알기 위해 exeinfo를 사용했다.





아주 간단한 UPX packer로 packing 되어 있음을 확인할 수 있다.


또한 내가 하는 짓은 PEViewer를 통해 구조를 보는 것이다.




UPX가 보이고, ELF 임을 확인할 수 있다.



UPX packer는 간단히 github에서 다운 받을 수 있다.


UPX packer가 없다면 아래 홈페이지에 접속해서 설치하도록 하자.


https://upx.github.io/



UPX를 unpacking 하는 법은 아래와 같다.


upx -d [파일명] 


upx -d [파일명] -o [unpacking 된 파일을 다른 이름으로 저장할 파일명]





패킹이 풀린 후 다시 한번 exeinfo와 PEViewer를 통해 바뀐 점을 살펴보자.





Packing이 풀린것을 확인할 수 있다.




unpacking 이전의 UPX도 사라졌고 unpacking이 잘 되었음을 확인할 수 있다


그렇다면 이제 unflag를 gdb로 분석해보자.





이전과는 다르게 unflag 파일의 symbols을 읽어 들이고, disas main이 가능하다.


대충 pseudo code를 작성하면 아래와 같이 작성할 수 있다.

compile 할 때 dummy가 자동으로 생성될 수 있기 때문에 hard coding 하였다.



1
2
3
4
5
6
7
8
9
int main()
{
    puts(*0x496658);
    rdi = malloc(100);                                                                
    rsi = 0x6c2070;
    strcpy(rdi, rsi);
 
    return 0;
}
cs



puts를 통해 출력하는 문자열이 무엇인지 확인해야한다.





어딘가에 flag에 저장되어 있고 그것을 malloc에 strcpy() 할 것이다.


rsi(source), rdi(destination) 중 rsi를 찾아야한다.


rip는 다음 실행될 code text의 주소이다.


즉 rip+0x2c0ee5 = 0x40118b + 0x2c0ee5 = 0x6c2070이다.


0x6c2070이 가리키는 문자열이 flag일 것이다.




0x6c2070은 0x00496628을 가리키고 있고, 내용은 위와 같다.


flag 획득 성공!!!