촉촉한초코칩

Bomb Lab Phase 1-3 본문

Study/System

Bomb Lab Phase 1-3

햄친구베이컨 2024. 3. 24. 13:09
명령어

 

Bomb.c

  • 6가지 phase 함수 존재 
    read_line(), phase(), phase_defused()가 반복됨
  • read_line() : 사용자 입력값을 받는다.
  • phase() : 입력값 검증
  • phase_defused() : phase()를 무사히 통과하면 폭탄이 해체된다. 

 

break문 해제하는 방법

  • info break
  • delete 번호

 

함수 들어가기

  • step into, si

 

함수에 들어가서 다음 명령어 실행하기

  • ni 

 

examine (명령어 : x) : 가상 메모리에 존재하는 임의 주소의 값 확인하기  

  • o (octal), x(hex), d(decimal), u(unsigned decimal), t(binary), f(float), a(address), i(instruction), c(char), s(string), and z(hex, zero padded on the left), Size letter are b(byte), h(halfword), w(word), g(giant, 8 bytes)
  • x/10gx  $rsp : rsp부터 80바이트씩 hex 형식으로 출력
  • x/5i $rip : rip부터 5줄의 어셈블리 명령어 출력
  • x/6wd $rsp : rsp부터 1byte씩 6개의 10진수 출력??

 

main 함수 분석 

puts > read_line > phase_1 > phase_defused > puts > read_line > phase_2 > ... 반복되는 것을 확인할 수 있다.  

 

phase_1 

 

phase_1 분석 

  • strings_not_equal 함수를 실행하고 test 명령어에서 eax끼리 xor 연산을 수행한다. 
  • 만약 eax가 0이라면 그 23번째 줄이 실행되고 폭탄을 피할 수 있게 된다. 

strings_not_equal() 함수 분석 

  • 입력받은 문자열을 비교하는 구문들 같다.
  • 우선 이 함수를 통해 eax값이 나오므로 eax가 0이 되도록 하는 입력값을 찾으면 된다. 
  • 함수에 break 를 걸고 실행해본다.

  • * rdi, rsi : 함수 호출 시 함수에 매개변수를 전달하는데 사용된다. (rdi : 첫번째, rsi : 두번째 인자) 
  • 주석문을 보면 내가 입력한 hello문자가 보이고, 그 아래에 두번째 인자값을 받는 부분에는 Border...의 문자열이 보인다. 
  • 이 문자열을 입력값으로 넣어본다.

  • break를 걸었던 함수 다음을 실행해보면 (continue) phase_1이 풀렸다는 것을 알 수 있다.

 

phase_2 

 

phase_2 분석

  • 이번에는 read_six_numbers() 함수를 통해 6개의 숫자를 입력받는 걸로 추측해볼 수 있다.
  • 그리고 rsp와 1을 비교하여 두 값이 같다면 52번째 줄을 실행하고, 같지 않다면 폭탄이 실행된다. 
  • 그 외에도 32번째 줄에 eax와 rbx를 비교하는 문, 45번째 줄에 rbx와 rbp를 비교하는 문 등 빠져나오는 부분이 있다. 

read_six_numbers() 함수 분석 

  • 51번째 줄에 eax와 0x5를 비교하여 eax가 5보다 크다면 빠져나오는 비교문이 있다. 
    > 입력 개수를 뜻하는 것 같다. 
  • 일단 해당 함수에 break를 걸고 숫자 6개를 입력해본다. 
  • 그리고 rsp를 확인해보았는데 알 수 없는 값들이 들어가있다.
  • 마지막에 rsp에 어떤 값이 들어가있는지 확인해보기 위해 65번째 줄에 break를 걸고 다시 실행해본다. 

phase_2 

  • 우선 첫번째 비교문에서 rsp가 1이여야 폭탄을 피하므로 첫번째 값은 1이 맞다. 그리고 52번째로 이동한다. 
  • 52번째 : rsp에 4를 더하고 그 값을 rbx에 넣는다.    (int 형이므로 4 bytes)
    즉, rbx에는 다음 숫자가 들어가있다.  
  • 57번째 : rsp에 18을 더한 값을 rbp에 넣는다.         
  • 27번째로 이동 : rbx에 4를 뺀 값을 eax에 넣는다.
    rbx에는 다음 숫자가 들어가있었는데 4를 다시 뺀다는 것은 eax에는 현재 숫자가 들어간다는 뜻
  • 30번째 : eax에 eax를 더한다.
    현재 숫자 + 현재 숫자 
  • 32번째 : rbx와 eax를 비교하여 같으면 41로 이동한다. 
    다음 숫자 = 현재숫자+현재숫자
  • 그렇다면, 1, 2, 4, 8, 16, 32 순서로 늘어난다는 것을 의미한다. 

 

phase_3

 

phase_3 분석

  • 입력 함수를 실행하기 전에 eax에 0을 넣고, eax와 1을 비교한다. 만약 eax가 더 크다면 39번째 줄로 이동한다. 
  • 39번  rsp 에 8을 더한 값과 7을 비교해서 rsp가 더 크다면 106으로 이동한다. 폭탄!
  • 그렇다면 cmp 수행 전 eax에 어떤 값이 있는지 알아보기 위해 29번째 줄에 break문을 걸고 실행한다. 

  • 여러 값을 입력해도 2가 되는 것을 보면 최대 2개를 읽어오는 것 같다. 
  • 그리고 39번째 줄에서 rsp+8은 7보다 크면 안 되기 때문에 39를 실행한 후에 44번째 줄에 break를 걸어서 rsp+8의 값을 확인해본다.  

  • 7보다 작기 때문에 해당 비교문은 넘어간다. 
  • 계속해서 ni를 입력하면서 실행해본다.

  • eax에 rsp+8한 값을 넣는다. > 즉 첫번째 입력한 값
  • rax*8+0x402470으로 이동한다. 
    사진에서 보면 바로 다음 줄이긴 한데 계산해보면 400fb9가 나오긴 한다. 

  • eax에 0x137 값을 넣고 그 값을 rsp+0xc와 비교해서 같다면 넘어간다. 
  • 16진수인 137을 10진수로 변환하면 311이 나온다. 
  • 즉 1 311을 입력하면 폭탄이 해체된다. 

  • 처음에 rsp를 비교하는 부분에서 7보다 크면 폭탄이 커지므로, 첫번째 입력 값은 0, 1, 2, 3, 4, 5, 6, 7이 올 수 있다.
  • 각각의 경우의 수에 맞는 값을 구해보면 아래처럼 나온다. 
    (일단 입력값이 1개보다 커야 하므로 두번째 입력값은 아무 값이나 넣는다.)

0일 때 0xcf > 207
2일 때 2c3 > 707
3일 때 100 > 256
4일 때 185 > 389
5일 때 ce > 206
6일 때 2aa > 682
7일 때 147 > 327

하나하나 입력하고 나서야 안 건데.. phase_3 코드를 보니 mov 하는 곳이 있었다.
총 8개인 걸 보니 이 숫자를 더해서 10진수로 변환하면 될 듯