Jeomxon's Tech Note

원하는 스택 바꾸기 - protostar 본문

System/ProtoStar

원하는 스택 바꾸기 - protostar

저문(jeomxon) 2019. 11. 15. 22:33

이번 실습을 통하여 원하는 스택에 접근하여 값을 바꾸는 행위를 해보려고 한다.

먼저 stack1.c의 코드를 보자

 

stack1.c

gedit을 통해서 stack1.c를 보았다. 사실 이전의 다른 변수 덮어씌우기랑 다른 점은 argument를 1개 받으면 error메시지를 출력하도록 작성되어있는 코드라는 점이다.

따라서 실행을 할 때 단순히 "./실행파일명" 만 입력할 것이 아니라 "./실행파일명 다음전달해줄인자"의 형식으로 작성해 주어야하는 것이 옳다.

 

위 코드도

gcc -z execstack -no-pie -w -o stack1 stack1.c 

위의 gcc 명령어로 컴파일 해준다.

 

그리고 코드를 보면 알 수 있듯 if문의 조건이 현재 0으로 초기화 되어있는 modified의 값을 조작하여 0x61626364로 만들어 줘야한다는 사실을 알 수 있다.

그럼 gdb를 사용하여 어셈블리코드를 먼저 보도록 하자.

 

먼저 메인함수의 일부분을 나타낸 위의 이미지가 있다. 어셈코드를 보면 먼저 cmp즉 compare부분을 찾을 수 있다.(+79)

비교를 하고 있으므로 아까 if문 안의 조건인 modified == 0x61626364인 것을 금방 알 수 있다.

따라서 eax가 modified변수임을 알 수도 있다.

그 윗줄에 보면 eax의 위치가 rbp-0x4이니깐 즉 modified의 위치가 된다.

 

그리고 strcpy(+71)도 찾을 수 있는데 여기서 그 위에 있는 +65와 +68의 

이런 내용들을 볼 수 있다. 여기서 rsi를 rdi로 복사하는 strcpy이기 때문에 rsi는 argv[1], rdi는 buffer라는 사실을 알 수 있다. 여기서 우리는 buffer가 rax로 부터 왔다는 것도 알 수 있으므로 rax의 주소는 rbp-0x50이라는 사실을 알 수 있다.

그럼 이제 해결에 가까워졌다고 볼 수 있다.

 

print/d라는 명령어를 통해서 16진수를 10진수로 바꾸어준다.

그러면 buffer와 modified의 위치의 차이를 볼 수 있다. (이 차이를 계산해야하는 이유는 modified의 시작 위치부터 값을 정확하게 입력해주기 위해서이다.)

10진수로 바꾸었을 때 76의 차이가 나므로 76개를 채우고 나머지를 0x61626364로 만들어주면 된다.

 

이후 위처럼 파이썬 코드를 이용해서 A라는 문자 76개를 만들어준다. 그리고 복사를 해둔다.

다시 gdb디버거를 통해 stack1을 보도록 한다.

 

아까의 메인 함수에서 if의 조건문인 cmp함수가 있는 +79에 브레이크 포인트를 걸고 run을 해보려고 한다.

 

브레이크 포인트를 걸고 run을 하는데 유의할 점은 처음에 말한 것처럼 인자를 1개를 받으면 오류메시지를 출력하도록 코드가 작성되어있기 때문에 run이후 스페이스바를 한번 눌러주고 그 뒤에 두번째 전달인자를 통해서 작업을 해야한다.

 

//0x61626364에 대해서는 16진수의 ASCII 코드에 대해서 알아야 하는데 ASCII 코드표를 통해서 a = 0x61, b = 0x62,

c = 0x63, d = 0x64라는 것을 알 수 있다. 그리고 dcba로 적어주는 이유는 스택의 구조때문이다. 위를 이해하려면 스택의 구조에 대해서 조금 공부할 필요가 있다. 

 

다음 브레이크 포인트가 잘 걸렸는지 확인한 후에 eax의 레지스터 값을 확인해보면 정상적으로 0x61626364로 바뀐 것을 알 수가 있다. 이제 continue명령어를 통해서 제대로 값이 나오는지 확인해보자.

 

우리가 원하는 메시지를 출력할 수 있게 되었다!!

'System > ProtoStar' 카테고리의 다른 글

변수 덮어씌우기(modified) - protostar  (0) 2019.11.15