반응형
<흐름 파악하기 (자세한 설명은 그 뒤에)>
- Higher Language Version -
#include <stdio.h>
int main(
execve("/bin/sh", NULL, NULL)
)
쉘 코드를 만들기전에 우리가 원하는 쉘코드를 생각해볼 필요가 있습니다.
C언어를 배우신 분이라면 위 코드는 익숙하실 겁니다.
위 코드를 실행하게되면 /bin/sh 프로그램 흐름으로 바뀌게 될 것입니다. 하나의 악마의 목적이라고 할 수 있죠(해킹에 있어서). execve는 완벽하다고도 합니다. 왜냐하면 누군가가 성공적으로 exploit을 성공하면 root privileges(루트 권한) 을 던져주기 때문입니다.
execve는 null terminated pointers to string literals로서 3개의 인자를 가집니다.
그러나 위 코드에서 보듯이 문자열 리터럴과 NULL을 사용하는데 잘 작동합니다.
위 사진을 보는바와 같이 shell.c 프로그램은 /bin/sh 와 같이 동작합니다.
This is your shell : D ROFL
Making Our shell program in Assembly !
이제 assembly section으로 들어가 봅시다.
벌써 포기하고 싶으신 분들이 생길 것 같습니다. 아직 갈 길이 남았으니 조금만 더 힘냅시다 !
처음 두 라인 .section .data 와 .section .text를 보겠습니다.
Data and Text Section
우선 깊은 내용을 다루기에는 힘들겠지만, 이것을 공부하는 우리는 적어도 메모리 구조에 대해서 공부를 했을 것입니다. 이러한 코드가 데이터 및 텍스트 섹션이라는 것은 알고 계실것이라 생각됩니다. 데이터 섹션은 우리가 초기화 된 변수를 어셈블러에 선언한 것입니다. 하지만 이것을 전적으로 무시하셔도 됩니다. 우리는 쉘코드를 위해서 이 섹션을 사용하지 않기 때문이죠. 그러나 우리는 문자열 리터럴 /bin/sh를 저장하는 프로그램을 사용할 것입니다. 반대로 Text Section은 우리한테 엄청 중요한 부분입니다. 이 섹션은 프로세서 한테 직접적으로 명령하는 코드를 우리는 위치시킬 수 있기 때문입니다. 이것을 payload(페이로드)라고 흔히 부르지요. .global _start와 start를 보면, 이 것은 아셈블러한테 start symbol이 global하고 _start에서 프로그램을 시작한다고 말해줍니다. 왜 이런 부분이 필요하냐고 생각도 하실 수도 있는데, 이러한 형식은 프로그래밍 관점에서 아주 중요합니다.
Syscall
우리가 작성한 execve처럼 직접적으로 함수를 부르는 것 대신에, 우리는 sycalls 라는 것을 사용할 것입니다. 32bit 어셈블리 프로그래밍을 해보셨다면 $0x80을 알고 계실 것입니다. 지금은 시스템이 잠시 동안 시스템을 호출하고 시스템 인자로 특정 레지스터를 전달하는 것을 아시면 되겠습니다. 이러한 경우는 libc의 execve 함수 인자로 들어가게 됩니다.
syscall을 호출할 때, %rax는 syscall number를 가지게 되는데, 이는 우리가 적어넣은 숫자를 의미합니다. 예를 들어 1은 exit, 59는 execve 등등. 이어지는 인자는 %rdi, %rsi, %rdx에 들어갑니다.
설명 끝. 2부에서 계속 !
반응형
'[ ★ ]Study > PWNABLE' 카테고리의 다른 글
[Tip] pwntool 함수 offset/plt/got 주소 찾기(pwntools) (0) | 2018.11.06 |
---|---|
Double Free Bug(DFB) (0) | 2017.09.18 |
Use After Free 취약점 (0) | 2017.09.16 |
system call table 정리 (0) | 2017.09.16 |
shellcode 만들기 2부 (0) | 2017.09.16 |
댓글