어셈블리어와 x86-64 명령어
- x86 문법 구조 = 명령어(동사) + 피연산자(목적어) = Opcode + operand
- 데이터 이동: mov dst, src/lea dst, src
- 산술 연산: add, sub, inc, dec
- 논리 연산: and, or, xor, neg의 비트 연산
- 비교 연산: cmp-같으면 ZF플래그 설정, test-두 피연산자에 and 비트 연산해 모두 0이면 ZF플래그 설정
- 분기: jmp-rip를 점프, je-직전에 비교한 두 피연산자가 같으면 점프, jg-직전에 비교한 두 연산자 중 전자가 더 크면 점프
- 스택: push, pop
- 프로시저: call-프로시저를 부르는 행위, leave-스택프레임 정리, ret-return address로 반환
- 시스템 콜: 유저 모드에서 커널 모드의 시스템 소프트웨어에게 동작 요청하기 위해 syscall 사용.
- syscall 요청: rax, 인자 순서: rdi->rsi->rdx->rcx->r8->r9->stack
Shellcode
- 쉘(Shell): 운영체제에 명령을 내리기 위해 사용되는 사용자의 인터페이스
- 사용자(명령)->쉘(해석)->커널(명령 수행 후 결과 전송)->쉘(해석)->사용자(결과 확인)
- 쉘 코드: 익스플로잇을 위해 제작된 어셈블리 코드 조각. 시스템 해킹의 공격 기법 중 하나
- 만약 해커가 RIP를 자신이 작성한 쉘코드로 옮길 수 있다면 자신이 원하는 어셈블리 코드가 실행되게 할 수 있음.
- orw 쉘코드: open read write. 특정 파일을 열고 읽고 출력하는 코드.

int fd=open("/tmp/flag",O_RDONLY, NULL);
read(fd, buf, 0x30);
write(1, buf, 0x30);
-
컴파일 및 실행: 리눅스에서 실행 가능한 파일의 형식은 ELF. gcc 컴파일을 통해 ELF 형식 으로 변형해야 함. 공격의 대상이 되는 시스템에서 쉘코드를 실행하면, 상대 서버의 자료를 유출해낼 수 있음.
-
gdb 디버깅으로 쉘 코드 동작 분석
-
execve 쉘코드: 임의의 프로그램을 실행하는 쉘코드(일반적인 쉘코드). 최신의 리눅스는 대부분 sh, bash를 기본 셸 프로그램으로 가지고 있음. 리눅스의 기본 실행 프로그램들은 /bin/ 디렉토리에 저장되어 있음. sh 셸도 여기 저장됨
