일반적으로 프로그램의 메모리 부분에 쓰기가 실행되도록 충분한 데이터를 삽입해야합니다. 이를 수행하는 방법은 오버플로가있는 프로그램의 구조에 전적으로 의존합니다.
프로그램이 ASM 목록에 의해 지정된 경우에, 상상 :
[SECTION .text]
global _start
_start:
;;...
jmpagain:
jmp next
uname db "username"
next:
mov eax,uname
;;...
jmp jmpagain
"username"
가 주소 명령 포인터 방문에 바로 인접한 메모리에있는 문자열입니다. 프로그램이 경계를 확인하지 않고 메모리 영역에 데이터를 쓰는 경우 코드를 덮어 쓰고 명령 포인터가 next
함수를 다시 방문 할 때마다 컴퓨터는 해당 메모리 부분에서 오버 플로우 된 모든 데이터를 실행하려고합니다. 익스플로잇하는 글자가 문자열의 시작 부분에서 시작하고 쉘 코드를 삽입 할 수있는 충분한 공간을 제공하는 조건에서 쓰기를 멈 추면 입력에서 쉘 코드에 "username"
과 동일한 길이의 바이트 문자열을 추가합니다. 그런 다음 쉘 코드의 시작 부분은 next
레이블의 주소에 있습니다.
그러나 이것은 기본 원리에 대한 간단한 예제 데모입니다. 사실 포인터 포인터가 방문하는 메모리 영역에 데이터를 가져 오는 것은 훨씬 까다로울 수 있습니다. 문제가있는 명령 파일에 액세스 할 수 있다면 디버그하고 메모리를 덤프하고 메모리 영역을 어떻게 기록하여 버퍼에 오버플로하여 IP 도달 가능 메모리를 확보해야하는지 확인할 수 있습니다.
셸 코드는 명령 포인터가 전달하는 메모리로 만들 필요가있을뿐만 아니라 예상 된 방식으로 실행되도록 해당 메모리에 올바르게 정렬되어야한다는 점을 다시 한 번 강조하는 것이 중요합니다. 명령 포인터가 첫 번째 명령의 시작 부분이 아닌 코드 중간에있는 경우에는 분명히 예상대로 수행하지 않을 것입니다.