본문으로 바로가기

Codegate 2017 prequals angrybird Write Up

category 해킹/Write Up 2017. 3. 20. 16:10

0. introduce

이건 정말 생각보다 정말 힘들게 풀었다. 그 이유는 여러 국내 angrybird Write Up를 찾아보면 바이너리 초반부에 나오는 여러가지 연산문들을 그냥  nop으로 처리후 angr로 풀었는데, 실제로 익스를할때는 그게아니였다. 그래서 조금 애를먹었는데 덕분에 angr사용법과 바이너리패치방법에대해서 자세히 공부할 수 있는 기회가 된 것 같다.


1. binary

64비트 리눅스 바이너리이다. 이 문제는 nc포트가 주어지지않은 리버싱 문제이기때문에 보호기법은 상관이 없다.


2. Solve

바이너리 처음부분을 보면 바이너리가 실행되자마자 exit함수가 호출되면서 끝난다. 그렇기 때문에 프로그램을 정상적으로 실행해주기 위해서 exit를 nop으로 패치한다.


exit를 해제하고나면 초반 루틴을 지나서 다음과같이 입력값을 특정식으로 비교하는 조건문이 나온다.


자세히보면 그런 방식의 조건문이 무수히 많이 존재한다. 그렇기때문에 이것을 angr로 풀어줄 수 있다고 생각했다.

하지만 이상태로 바이너리를 실행시키면 다음과 같이 된다.


그렇기때문에 처음에 나오는 조건문을 다시 확인해 보았다.



보면 3개의 함수가 있고 그 아래에 fgets함수로 문자열을 입력받는란이있다.

먼저 첫번째 함수를 보겠다.


첫번째 함수를 보면 리턴값을 1이아니라 21로 수정하라고한다.

mov eax, 21로 바이너리 패치를 한다.



그리고 두번째 함수에서 스택확인을 하는데 이건 어떤 이유에서 하는지 모르겠다.

nop처리를 안하면 여기서 Segmentation fault가 나므로 nop처리해서 넘겨준다.



이 부분이 문제풀이의 핵심이다. 보면 offset off_606038은 libc_start_main의 got주소값이다. 여기 구문을 보면 그 값을 불러와서 hello인제 검사하고 아니면 종료한다. 이부분을 그냥 nop으로 처리하게되면 angr가 제대로 작동을 하지 않는다.

그러므로 여기서부터는 여러개의 풀이로 나뉜다.

1. 바이너리 패치로 libc_start_main 의 got부분에 hello문자열을 넣는다.

2. angr나 파이썬 모듈을 이용하여 프로그램을 실행시키고 난후에 got부분의 값을 hello로 수정한다.


나는 1번의 방법을 선택하였다. 하지만 2번의 방법도 궁금해서 찾아보았는데 훨씬 더 빠르게 flag를 찾을 수 있었다. 

이런식으로 바이너리 패치 이후에 angr를 돌렸다.


SOURCE - 1

(https://github.com/LYoungJoo/CTF-Write-Up/blob/master/2017_CodeGate_Prequals%20Write%20Up/angrybird/angr1.py)


FLAG - 1


두번째로는 가장 빠르고 쉽게 풀 수 있는 방법이다.

바로 angr에 project.factory.blank_state(addr =) 코드를 이용해서 문제를 바로 푸는것이다.

angr 메뉴얼을 확인해보면 

blank_state(**kwargs)

Returns a mostly-uninitialized state object. All parameters are optional.


Parameters:

addr – The address the state should start at instead of the entry point.

.....

.....

다음과같이 나온다. 그러므로 시작지점을 실제로 연산이 이루어지는 0x4007ed로 두고 시작하면 문제를 바로 해결할 수 있다.

( 바이너리 패치를 하지않으면 Im_so_cute&pretty_Ԃ@ 이런식으로 출력되므로 기본 연산 검증 구문들을 nop으로 처리하고 바이너리 패치 한뒤에 돌려주면 된다. <retrun 21은 처리해줘야함> )


SOURCE - 2

(https://github.com/LYoungJoo/CTF-Write-Up/blob/master/2017_CodeGate_Prequals%20Write%20Up/angrybird/angr2.py)


# 하지만 조금 의심스러운 점은 libc_start_main의 got부분이 hello가 아닌데 왜 제대로된 결과값이 출력되는지는 잘 모르겠다. 그리고 이 방법은 패치를 잘못하면 Im_so_cute&pretty 까지는 제대로나오는데 그 뒤에 flag가 제대로 출력되지 않으므로 권장하지 않는 방법이다.


세 번째로는 angr에서 코드패치를 하는 법이다. 

김승환님의 라이트업에서 방법을 따왔다. (KSHMK - WriteUP)


SOURCE - 3

(https://github.com/LYoungJoo/CTF-Write-Up/blob/master/2017_CodeGate_Prequals%20Write%20Up/angrybird/angr3.py)


확실히 3번째 방법이 정확하게 flag를 얻을 수 있다. (마찬가지로 got값에 hello를 넣어주는 패치 이외에 모든 패치를 한 상황)

'해킹 > Write Up' 카테고리의 다른 글

Pwnabletw start Write Up  (0) 2017.04.04
Pwnablekr coin1 Write Up  (0) 2017.03.29
Codegate 2017 prequals RamG-thunder Write Up  (0) 2017.03.11
Codegate 2017 prequals messenger Write Up  (0) 2017.03.11
XiomaraCTF 2017 Xor Tool Write Up  (0) 2017.02.27