힌트를 보면 PLT라고 합니다.
ret는 strcpy로 돌려줘야하고
ret 뒤에는 "AAAA"로 채워버립니다.
PLT에 대한 개념을 모르시면 다음 글을 읽고 오세요.
->
strcpy()로 return 하라고 하니 strcpy() 주소를 찾아봅니다.

0x08048410입니다.
memset()을 통해 "AAAA"로 덮어씌우는 부분은
nightmare 종료 후 돌아가는 strcpy()가 종료된 후 return 할 주소가 됩니다.
그러므로 strcpy()를 이용해 "AAAA"를 조작하면 됩니다.
"AAAA"의 주소는 buffer에서 48만큼 떨어져있습니다.
buffer의 주소를 찾아봅니다.
buffer에 접근하는 strcpy() 근처를 찾아봅니다.


buffer의 시작 주소는 0xbffffab0입니다.
"AAAA"의 주소는 0xbffffae0입니다.
"AAAA"의 위치에 return 할 주소를 덮어씌워주면 됩니다.
system()을 이용하도록 하겠습니다.

system()의 주소는 0x40058ae0입니다.
libc.so.6 내부의 "/bin/sh"의 주소를 찾습니다.
전에 만들어놨던 프로그램으로 찾습니다.

"/bin/sh"의 주소는 0x400fbff9입니다.
공격 코드를 말로 설명하자니 깁니다.
Stack 구조를 보겠습니다.
Stack 구조
Low addr
buffer (40-byte) |
sfp (4-byte)
|
ret (to strcpy) |
ret (to system) ("AAAA") |
&ret (to system) |
&RTL attack code (4-byte)
|
&system() |
ret (4-byte)
|
&"/bin/sh" (4-byte)
|
High addr
공격해봅니다.

안됩니다.
아왜
실행주소 길이 때문일겁니다.
주소를 당겨서 다시 공격해봅니다.

공격에 성공했습니다.