bomb lab: phase_1 문제 풀이
시스템 프로그래밍의 과목에서 밤랩 하나만 제대로 해도 정말 편하겠다는 생각이 들어서, 오늘부터 차근히 하니씩 풀어볼 예정이다. 우선 처음 phase_2까지는 보고 한 번 풀어볼 예정이다. 아직 감이 덜 잡혀있기 때문에..
제일 먼저 기본적인 명령어만 정리해보고 넘어가겠다.
1. disas main(혹은 보고싶은 함수): 그 대상에 대한 내용을 쭉 보여준다.
2. r : 답을 입력할 때 r 명령어를 치고 문제에 대한 답을 입력해준다. 브레이크 포인트를 걸어두자!
3. b (걸어둘 대상): 브레이크 포인트를 걸어준다.
4. b: 모든 break 포인트를 풀어준다.
5. info break: 걸어놓았던 모든 break 포인트를 보여준다.
이정도면 이번 장에서 사용하는 명령어는 모두 모아놓은 것 같다. 이제 본격적으로 문제를 보자.
먼저 밤랩을 서버에 넣고, 밤랩 실행 파일을 만든다. 만들고 나서 gdb를 이용하여 밤랩에 들어오게 되면, (gdb)로 대기 상태가 되는데, 여기서 disas main을 하여 main을 쭉 보여주게 된다. 그리고나서 그 내용들을 쭉 보다보면, phase_1이라고 써있는 곳이 있다. 그러면 또 disas를 사용하여 phase_1을 열어본다.
문제 해석을 간단하게 해 보겠다.
+9 : 함수 <strings_not_equal>을 call 해온다
+ 14: test로 파라미터를 넣어본다
+16 : 같으면 +23으로 간다(폭탄이 터지지 않는다)
+18: 다르면 폭탄이 터지게 된다!
<간단한 어셈블리어>
1. je:
jump if Equal의 줄임말. 같다면~이라는 뜻, ==과 같다.
2. jne:
jump if not zero의 줄임말. !=의 의미이다. 같지 않다면~ 이라는 뜻.
-> jne는 다시 말해서 zf가 0인경우 실행된다.
3. test a b :
두 인자를 and연산자를 이용해 비교한다. 주로 참, 거짓을 판별할 때 사용되어진다.
-> 예를들어 0과 0은 0, 0과 1은 0, 1과 1은 1이기 때문에 0인지 아닌지 판별할 때 사용한다.
결론적으로, 파라미터에 들어간 문자열들이 같으면 괜찮고, 다르면 터진다는 뜻!
여기서 참고로, 브레이크 포인트를 거는 방법은 위와 같다.
이렇게 브레이크 포인트를 걸어놓으면 실수해서 답을 잘못 쳐서 폭탄이 터지는 일을 방지할 수 있다.
한번 걸어놓은 브레이크 포인트는 자동으로 소실되는 것이 아니라 내가 해제를 해 주어야 한다.
아까 위에서 strings_not_equal의 함수가 어떠한 역할인지 짐작해보았으니 이번에는 이 함수를 분석해보록 하자.
우선 함수에 브레이크 포인트를 걸어두고, c 명령어를 사용하여 계속 본다.
함수를 열어보니 매우 많은데, 어떤걸 봐야될지 모르겠다. 그래서 어떻게 보는지 찾아보니, 우선 rdi와 rsi에 집중하라고 하더라. 이유는 처음에 모르고 풀었는데, 어셈블리어를 보니 이해가 갔다.
mov 명령이란?
-> 데이터를 복사하는 명령어이다. move라고 착각하여 이동시킨다고 생각했는데, 복사하는 명령어이다.
제한사항: 레지스터에서는 같은 사이즈의 데이터끼리만 복사가 가능하고, 메모리에서 메모리로 복사가 안되기 때문에
레지스터를 통해서 복사해야한다.
-> 형태는 move eax, ebx의 형태를 가지고 있으며 이는 'ebx의 값을 eax로 복사한다.'라는 뜻이다.
이걸 보면 push로 인해 무언가가 스택에 넣어지고(아마도 받은 파라미터들) 그것들의 값을 복사하여 값을 처리하는 것을 보아하니, 이 둘은 받아진 파라미터들이 아닐까 하고 생각이 되었다. 그러면 이것들을 확인하여 같은지 다른지 확인하고, 답으로 같은 문장을 입력하면 끝나겠다! 라는 생각을 했다. 그래서 이것을 어떻게 볼것인지 고민했다.
받아진 레지스터의 정보를 볼 수 있는 명령어는 i r이다. 이렇게 해서 봤더니.. 무슨 숫자가 난무한다.
하지만 아까 rdi와 rsi를 보아야 한다고 했기 때문에 이 부분에만 집중해서 봤다. 이게 16진수인데, 이걸 변환을 어떻게 시키나 했는데, 이것 또한 역시 변환시키는 명령어가 있다고 한다.
x/s $rdi 명령어를 했더니, 이것을 변환시켜 "d"가 나왔다. 아까 내가 실행시켰을 때 들어갔던 문자열이 보였다. 너무 신기했다! 그다음 또 x/s $rsi를 해 보았다. 그랬더니 저러한 문장이 밖으로 나왔다. 그렇다면, 이 문장을 답에 입력을 시키면? 문제가 풀릴 것 같았다.
문제를 풀기에 앞서, 아까 언급했던 브레이크 포인트를 확인 후 모두 지웠다. 답을 입력할 때 방해가 된다고 생각해서..
사실 지금 생각해보면 그냥 두 번 눌렀어도 될 뻔 하기는 했지만 어쨌든 명령어를 하나 더 알았으니 됐다.
이렇게 해서 r을 입력하고, 아까 봤던 문장을 입력해주었더니 1단계 문제를 풀었다. 대충 어떻게 하는지 감이 잡혔다!
다음 문제도 열심히 풀어볼 예정이다.