execve shellcode 제작 및 입력

NanSu·2022년 11월 4일
0

System Hacking

목록 보기
1/1

<운영체제 : Ubuntu 18.04, shellcode : 32bit>

1. Shellcode 제작

1.1 shellcode.c


라인은 한줄로 매우 간단하다. execve함수는 현재 실행 중인 프로세스를 새로운 프로세스로 덮어쓴다. shellcode.c에서는 쉘을 load하여 덮어쓴다.

1.2 shellcode


shellcode.c를 32bit 파일로 컴파일한다. shellcode실행시 정상적으로 쉘이 뜬다.

1.3 shellcode.asm


pwngdb로 *execve+1에 break point를 찍고 디버깅한다. call하기 전에 레지스터를 어떻게 설정하는지 알 수 있다. edx에 0, ecx에 0, ebx에 "/bin/sh"의 주소를 넣는다. 그리고 call하기 전에 eax를 0xb로 설정하는데 이것은 execve의 syscall number다. 이 정보를 바탕으로 어셈블리 코드를 작성할 수 있다.

xor 연산을 통해 edx, ecx, eax를 먼저 0으로 만든다. 0을 만들 때 mov를 사용하지 않고 xor을 사용하는 이유는 쉘코드에 null문자(\x00)를 포함시키지 않기 위해서다. 쉘코드에 null문자가 존재하면 문자열의 끝으로 인식해 도중에 끊길 가능성이 존재하기 때문이다. line 7-9에선 스택에 /bin//sh\x00을 push한다. 이때 //를 사용하는 이유는 push하는 데이터를 4바이트로 맞추기 위해서다. 32bit에서 스택은 4바이트 단위로 구분되므로 데이터를 push할 때는 4바이트가 편하다. 이후 ebx에 문자열의 주소를 넣고 eax를 0xb로 설정한다. 모든 설정이 끝났으므로 시스템콜만 하면 된다. int 0x80으로 시스템콜을 한다. int는 인터럽트고 0x80은 인터럽트 번호로 시스템콜 인터럽트를 의미한다.

1.4 shellcode.bin


nasm로 elf형식의 shellcode.o을 만든다. shellcode.o의 opcode를 objdump로 볼 수 있다. -d 옵션을 주면 텍스트 섹션을 디어셈블하여 출력한다.

xxd는 파일의 hex dump를 만들어 출력해준다. xxd로 shellcode.o를 보면 쉘코드 실행에 필요한 opcode외에 elf파일 형식에 필요한 부분들이 존재한다.

objcopy로 shellcode.o의 section .text에서 쉘코드에 필요한 opcode만 추출할 수 있다. shellcode.bin을 xxd로 출력하면 objdump로 확인했던 section .text의 opcode만 존재하는 것을 확인할 수 있다.

2. shellcode 입력

2.1 read_buf


32바이트를 read로 입력받고 shellcode로 buf에 저장된 코드를 실행한다. buf에 shellcode.bin를 입력하면 쉘을 실행하게 된다.

shellcode.c를 컴파일할 때 -z execstack 옵션이 필요하다. 이것은 NX-bit라는 메모리 보호 기법을 끄는 것이다. NX-bit가 켜져있으면 stack에 있는 코드에 실행 권한이 없다. buf는 stack에 존재하므로 buf에 입력한 shellcode.bin을 실행하기 위해선 stack에 실행 권한이 있어야 한다.

2.2 read_buf_exploit.py


pwntools를 이용해 exploit을 만든다. cat shellcode.bin을 shell에서 실행하고 출력된 코드를 payload로 만들어 read_buf에 입력한다. cat에서 23바이트를 입력받는 이유는 shellcode.bin가 23바이트이기 때문이다. shellcode.bin은 쉘 실행에 필요한 코드외에 아무것도 존재하지 않는다.

read_buf_exploit.py를 python3로 실행시키면 쉘을 띄울 수 있다.

profile
난수입니다!

0개의 댓글