함수를 호출합니다.
대신 코드는 엄청 짧아졌습니다.
함수 내부에는 strcpy가 아닌 strncpy가 있습니다.
strncpy의 함수 원형을 찾아보면 다음과 같습니다.
기본 역할은 strcpy와 동일합니다만 복사하는 size가 정해져 있습니다.
하지만 위의 코드에서 buffer는 40-byte인데 복사하는 길이는 41-byte입니다.
코드를 뜯어보면 뭔가 힌트가 나올듯 합니다.
problem_child()를 disassemble 해봤습니다.
strncpy를 call 하기 전에 41, src, buffer를 차례로 넘기는 것을 확인할 수 있습니다.
Stack frame의 개념을 모르시면 다음 글을 읽고 오세요.
-> http://slimv.tistory.com/entry/Stack-frame
buffer에 접근하는 problem_child+27에 Break point를 걸고 eax를 확인해 보겠습니다.
problem_child의 Stack frame이 보입니다.
그리고 sfp의 끝부분이 42로 덮어씌워진 것을 확인할 수 있습니다.
이를 이용해 leave 명령이 실행 될 때 프로그램의 흐름을 바꿀 수 있습니다.
main에서 shell code 쪽으로 return 하도록 조작하면 될 듯 합니다.
main 함수에서 problem_child를 call하는 부분 뒤쪽을 봅니다.
Stack을 정리하고, sfp를 설정하고, ret를 설정합니다.
problem_child가 종료된 직후 esp에서 8-byte 떨어진 주소에 ret 값을 갖고 있도록 조작하면 됩니다.
계산하기 귀찮으니 그냥 spray를 쓰겠습니다.
Stack 구조
Low addr
buffer (40-byte, main에서 사용할 sfp, ret) |
sfp (4-byte, buffer 시작 주소) |
ret
|
...
sfp (4-byte) |
ret (4-byte)
|
High addr
shell code의 위치를 확인하기 위해 argv[1]에 접근하는 main+44에 Break point를 걸고 edx를 확인합니다.
nop slide가 보입니다.
중간쯤에 떨어지게 0xbffffc19에 떨어뜨리면 되겠습니다.
공격에 성공했습니다.