본문 바로가기

Bomb Lab

[Bomb Lab] Phase2

<Bomb Lab이란?>

https://studyforall.tistory.com/98

 

[Bomb Lab]Bomb Lab이란?

Bomb Lab은 컴퓨터 사이언스로 유명한 카네기 멜론 대학교에서 만든 실습 프로그램이다. 이 프로그램을 통해 디버거 사용법을 익히고 바이너리 분석을 연습해볼 수 있다. 폭탄을 터뜨리지 않고 안

studyforall.tistory.com

 

실습 환경에 대해서는 위의 게시물 하단에 적어놓았다.

 

phase1에 이어 이제 phase2를 시작해본다.

disassemble phase_2 명령어를 입력하여 phase_2 함수를 처음부터 끝까지 어셈블리 코드로 출력해보았다.

첫인상은 비교(cmp)와 분기(je, jmp)가 많다는 것이다.

안전지대를 확인해보자.

<+64>까지 도달하면 <explode_bomb>을 실행할 가능성이 없어지므로 안전지대라고 볼 수 있다.

그리고 <+50>에서 무조건 <+64>로 jump하므로 <+50>도 안전지대라고 볼 수 있다.

 

다음으로는 read_six_numbers 함수를 분석해보자.

특정 함수를 실행한 직후 어떤 레지스터를 참조한다면 그 함수의 실행결과로 해당 레지스터에 어떤 값을 설정해놓았을 확률이 높다.

read_six_numbers 함수를 실행한 직후 rsp에 있는 값에 대해 연산을 수행하므로 이 부분을 염두에 두자.

 

disassemble read_six_numbers를 입력해보았다.

가장 눈에 띠는 함수는 <+56>에 있는 explode_bomb이다.

폭탄을 터뜨리지 않으려면 <+56>을 밟지 않고 <+61>까지 가야하고

그러려면 <+54>에서 jump해야 한다.

jg이므로 앞선 cmp문에서 전자가 후자보다 큰 값을 가지고 있어야 한다.

즉, eax가 0x5보다 큰 값인 6 이상의 값을 가지고 있어야 한다.

 

<+46>에 sscanf 함수가 있는데 보통 이런 상황에서는

-이런 상황이란 sscanf 함수 다음에 eax가 연산에 사용되는 경우-

 sscanf 가 받은 입력값의 개수가 eax에 들어가는 경우가 많다.

 

따라서 sscanf 함수에 6개 이상의 인자를 줘야하는 것으로 추측해볼 수 있다.

게다가 이 함수의 이름이 read_six_numbers인 것으로 미루어봤을 때

이 함수에 6개의 숫자를 주어야 하는 것으로 추측해볼 수 있다.

 

바로 동적분석을 해보자.

먼저 b *read_six_numbers로 bp를 걸었다.

run으로 프로그램 실행 후 phase1에 대한 정답을 입력하여 phase2로 넘어왔다.

앞에서 추측한 것을 바탕으로 임의의 6개의 숫자를 입력하였다.

*숫자를 6개로 읽게 하려면 각 숫자 사이에 공백을 입력해야 한다.

 

phase1에서 함수에 준 argument는 rdi와 rsi를 통해 전달됨을 학습했다.

역시나 입력값이 rdi에 들어있다.

ni를 입력하며 rdi의 값의 변화를 살펴보았다.

 

한줄씩 실행하다보면 sscanf 실행 직후인 <+51> 지점에 왔을 때 rdi 값이 바뀌는 것을 확인할 수 있다.

우선 여기까지 탐색하고 finish 명령어를 입력해서 read_six_numbers 함수에서 빠져나왔다.

 

내가 입력한 '1 2 3 4 5 6'은 어디로 갔을까?

read_six_numbers 실행 후 다음 명령어에서 rsp 레지스터를 연산에 사용했다.

rsp는 스택의 가장 윗부분을 가리키는 레지스터이다.

그래서 [STACK] 영역을 확인해보았다.

 

[STACK] 영역에 1,3,5가 보인다.

내가 입력한 값일까?

확인을 위해 examine 명령어를 입력해보았다.

 

x/6wd $rsp의 의미는 다음과 같다.

$rsp를 기준으로 word단위의 데이터 6개decimal(10진수)examine(출력해서 검토) 하겠다.

출력된 값을 보니 해당 주소에 있는 값들이 내가 입력한 값이 맞다.

이제 이 값을 어떻게 연산하는지 로직분석을 해보자.

 

분석의 목표는 어떤 숫자 6개를 입력해야 flow를 <+50>지점으로 이끌 수 있는가를 찾는 것이다.

다시 disassemble phase_2 하여 정적분석을 한다.

이번에는 read_six_numbers 이후에 rsp에 들어있는 입력값을 어떤 식으로 다루는지를 상세하게 분석할 것이다.

분석 결과를 설명하기 편하게 코드를 4개의 구역으로 나누어봤다.

read_six_numbers 함수 실행 후 처음으로 실행되는 구역은 A구역이다.

 

<A구역>

rsp에 들어있는 8byte(DWORD)가 1이어야 폭탄을 피할 수 있다.

폭탄을 피하면 D구역으로 간다.

 

<D구역>

rbx에 두번째 숫자 주소를 입력하고 rbp에는 여섯번째 숫자 다음 주소 즉, 끝부분의 주소를 입력한다.

그리고 B구역으로 간다.

 

<B구역>

eax에 rbx 바로 이전 숫자를 입력하고 그것을 두 배한 뒤, rbx와 비교한다.

같아야 폭탄을 피할 수 있다.

따라서 두번째 숫자는 첫번째 숫자를 두배한 값인 2가 되어야 한다.

폭탄을 피하면 C구역으로 간다.

 

<C구역>

rbx가 다음 숫자를 가리키도록 한다.

rbx가 끝부분에 도달하지 않았으면 다시 B구역으로 가서 반복한다.

끝부분에 도달했으면 안전지대인 <+50>을 실행한다.

 

즉 이 알고리즘에 따르면 6개의 숫자는 1로 시작해서 두 배씩 커지는 숫자여야한다.

 

따라서 1 2 4 8 16 32를 입력하면 폭탄을 해체할 수 있다.

폭탄을 해체했다.

'Bomb Lab' 카테고리의 다른 글

[Bomb Lab] phase4  (0) 2024.05.10
[Bomb Lab] Phase3  (0) 2024.03.24
[Bomb Lab] Phase1  (0) 2024.03.24
[Bomb Lab]Bomb Lab이란?  (1) 2024.03.24