Iron_golem
id : gate
pwd : gate
코드는 간단합니다.
strcpy를 통해 argv[1]를 buffer에 복사합니다.
Shell code를 넣고 return 해주면 간단히 풀릴것 같습니다만
될리가 없습니다.
Fake ebp를 쓰라는 힌트가 있습니다.
[#M_Fedora core 3 바뀐점|Fedora core 3 바뀐점|
Fedora core 3으로 넘어오면서 바뀐점들을 알아보겠습니다.
1. Exec shield
/proc/self/maps를 보면 memory의 권한을 확인할 수 있습니다.
실행 권한인 x가 있는 영역이 적습니다.
Redhat 원정대에서 공격할 때 주로 사용하던 shell code는 stack에 올라갑니다.
Fedora core 3에서의 stack 영역을 보겠습니다.
위의 주소를 /proc/self/maps에 표시된 권한과 비교해보면 x가 없는 것을 확인할 수 있습니다.
Stack에 shell code를 넣고 shell을 획득하는 방법은 이제 통하지 않습니다.
아왜
2. ASLR (Address Space Layout Randomization)
이름 그대로 memory의 layout이 계속 바뀝니다.
Stack의 buffer 주소가 매 실행마다 바뀝니다.
0xfef17100 이었다가
0xfefa0e50이 되었습니다.
그냥 계속 바뀝니다.
3. ASCII armor
Library들의 주소를 0x00으로 시작하도록 해놨습니다.
인자값을 전달할 때 0x00이 들어있으면 string이 끝난 것으로 인식하므로
연속적인 함수 호출이 불가능합니다.
아왜
주소가 고정된 library 내부의 함수로 RTL로 풀도록 하겠습니다.
system()을 쓰고싶지만 system()은 내부에서 uid를 재설정 해주기 때문에
Single pointer를 parameter로 받는 execl()을 이용하도록 하겠습니다.
execl()의 주소는 0x007a5720입니다.
하지만 execl() 시작 부분을 보면 stack frame을 바꾸는 명령이 존재합니다.
execl() 시작 부분으로 바로 return 시켜버리면
공격하기 위해 설정하게 될 fake ebp의 값이 의미없게 되어버립니다.
그러므로 stack frame 설정이 끝난 execl+3의 주소로 return 해주면 됩니다.
execl+3의 주소는 0x007a5723입니다.
ret는 위의 값으로 조작하면 됩니다.
이제 execl()에 넘길 parameter를 조작해야 됩니다.
Parameter는 memory 상에서 정적인 값을 찾아서 쓰도록 하겠습니다.
GOT(Global Offset Table)을 이용하도록 하겠습니다.
GOT와 PLT의 개념을 모르시면 다음 글을 읽고 오세요.
->
.got.plt section의 시작 주소는 0x08049618입니다.
.got.plt의 주소를 따라가 보면 0x0804954c가 있는 것을 볼 수 있습니다.
0x0804954c를 따라가 봅니다.
0x00000001이 있습니다.
execl이 실행 할 프로그램의 이름을 \x01로 설정하면 됩니다.
Shell을 실행하는 프로그램을 만들어 줍니다.
해당 프로그램의 이름이 \x01이 되어야 하므로
컴파일 한 프로그램에 link를 걸어줍니다.
이제 공격 코드를 구성하도록 하겠습니다.
iron_golem의 main()을 보면 처음에 0x108 (264) 만큼 stack을 확보합니다.
Dummy는 264-byte로 해줍니다.
Fake ebp로 이용할 .got.plt의 주소는 0x08049618입니다.
다만 main()이 종료될 때 leave와 ret로 인해 8-byte가 더해집니다.
8-byte가 더해진 값이 .got.plt의 주소인 0x08049618가 되어야 하므로
0x08049610으로 fake ebp를 설정해주면 됩니다.
마지막으로 ret는 앞서 구한 execl+3의 주소인 0x007a5723으로 해줍니다.
Exploit code
Low addr
dummy (264-byte) |
fake ebp (.got.plt) |
ret (execl + 3) |
High addr
공격해봅니다.
공격에 성공했습니다.
_M#]