
장치의 선호 네트워크 목록에서 SSID를 캡처 및 표시하는 정찰 도구.

선호 네트워크 목록 스니퍼(PNLS)는 간단한 웹 인터페이스를 갖춘 레드팀 Wi-Fi 감사 도구로, 장치의 선호 네트워크 목록(PNL)1에서 SSID2를 가로챌 수 있습니다. 이는 주변의 프로브 요청을 스니핑하여 SSID 및 기타 정보를 파싱한 후 최종적으로 웹 UI에 전파함으로써 이루어집니다. 이 프로젝트의 주요 동기는 802.11 프로브 요청과 이들이 전송하는 데이터와 관련된 개인정보 위험을 조사하는 것이었습니다.
그림 1: PNLS 시스템 개요
[!WARNING] 이 프로젝트의 모든 내용은 보안 연구 목적으로만 제공됩니다.
[!NOTE]
이 프로젝트를 복제하고 배포하는 데 필요한 하드웨어 및 소프트웨어 구성 요소는 다음과 같습니다. 작업 환경이 준비되면 설정 섹션으로 이동하세요.
sudo airmon-ng start wlan0 [2].[!NOTE]
Kali 이미지는 Re4son의 커널을 사용하며, 여기에는 외부 Wi-Fi 카드용 드라이버와 RPi 3 및 4의 내장 무선 카드용 Nexmon 펌웨어가 포함되어 있습니다 [3].
그림 2: 외부 안테나와 보조 배터리를 사용하는 RPi 4에서 실행 중인 PNLS
그림 3: AWUS036ACS 안테나가 있는 케이스를 사용하는 RPi 4에서 실행 중인 PNLS
그림 4: AWUS036ACM 안테나를 사용하는 RPi 4에서 실행 중인 PNLS
Docker를 사용하지 않으려면 Docker 없이 설정하기로 이동하세요.
개발 인스턴스를 빠르게 설정하세요:
# First clone this repo.
git clone https://github.com/AleksaMCode/Preferred-Network-List-Sniffer.git
# Move to the project root folder.
cd Preferred-Network-List-Sniffer
# Build backend and frontend image.
docker compose build
# Bring up both the backend and the frontend server.
docker compose up
# Move into the sniffer folder.
cd sniffer
# Run the Sniffer service.
sudo python3 sniffer.py
현재 다중 플랫폼 이미지는 제공되지 않으며, 프로젝트는 ARM64v8 아키텍처만 지원합니다. GitHub Container Registry에서 최신 사전 빌드 이미지를 다운로드하여 로컬에서 실행하세요.
# First clone this repo.
git clone https://github.com/AleksaMCode/Preferred-Network-List-Sniffer.git
# Move to the project root folder.
cd Preferred-Network-List-Sniffer
# Download the prebuild images.
docker pull ghcr.io/aleksamcode/pnls-backend-ghcr:latest
docker pull ghcr.io/aleksamcode/pnls-frontend-ghcr:latest
# Bring up both the backend and the frontend server.
docker compose up
# Move into the sniffer folder.
cd sniffer
# Run the Sniffer service.
sudo python3 sniffer.py
다음은 모든 것을 '수동으로' 실행했을 때의 스크린샷입니다:
그림 5: PNLS 스크린샷
프로브 요청은 장치를 이전에 연결했던 무선 액세스 포인트(AP)에 연결하는 데 사용되는 관리 802.11 프레임입니다. 장치에서 Wi-Fi가 활성화되어 있지만 네트워크에 연결되어 있지 않을 때마다 PNL의 SSID가 포함된 프로브 요청 버스트를 주기적으로 전송합니다. 이러한 프레임은 암호화되지 않은 상태로 전송되며, 무선 주파수(RF)를 모니터링하는 사람이라면 누구나 캡처하여 읽을 수 있습니다. 프로브는 브로드캐스트 DA 주소(ff:ff:ff:ff:ff:ff)로 전송됩니다. 전송 후 장치는 프로브 타이머를 시작합니다. 타이머가 끝나면 장치는 수신된 응답을 처리합니다. 응답을 받지 못하면 다음 채널로 이동하여 과정을 반복합니다. 프로브 요청에는 두 가지 유형이 있습니다:
지정 프로브 요청: 장치 PNL의 특정 SSID 사용
널 프로브 요청: 와일드카드 SSID (빈 SSID) 사용
빈 요청은 범위 내에 있는 모든 사용 가능한 AP로부터 응답을 받기 위해 전송됩니다.
캡처된 모든 패킷에서 802.11 프로브 요청 프레임을 필터링하는 것 외에도 Sniffer는 와일드카드 SSID도 필터링합니다.
많은 Wi-Fi 클라이언트가 있는 대규모 로컬 네트워크가 있는 장소에서 프로브 요청을 캡처할 때 PNLS는 필연적으로 해당 네트워크의 SSID를 포함하는 많은 프로브 요청을 캡처하게 됩니다. 이러한 SSID는 우리에게 가치가 없으며 소켓 부하를 증가시킬 수 있으므로 필터링하는 것이 유리할 수 있습니다. 이러한 SSID를 필터링하면 소켓 연결 부하를 줄일 뿐만 아니라 웹 UI에서 해당 SSID가 스팸되는 것을 방지할 수 있습니다.
이 기능을 사용할 때는 소스 코드를 약간 수정해야 합니다. 정확히는 settings.py 파일의 SSID_FILTER 목록을 Sniffer가 무시하려는 값으로 업데이트해야 합니다. 업데이트 후 프로젝트를 다시 빌드하고 PNLS를 시작하세요.
이 프로젝트는 메시지 중심 아키텍처 위에 설계된 이벤트 중심 아키텍처(EDA)를 사용합니다. 이 프로젝트는 중앙 집중식 솔루션(모든 것이 RPi에서 실행됨)을 사용하지만, EDA 사용으로 인해 구성 요소가 느슨하게 결합되어 있기 때문에 필요에 따라 분산 솔루션을 만들 수 있습니다. PNLS는 이벤트 발행자(sniffer), 이벤트 소비자(웹 애플리케이션), 이벤트 채널로 구성됩니다. 여기서 이벤트 채널은 메시지 지향 미들웨어(MOM)로 구현됩니다.
그림 6: PNLS 시스템 배포 다이어그램
비동기 서버 게이트웨이 인터페이스(ASGI)는 비동기 기능을 갖춘 Python 웹 서버와 서비스 간의 표준화된 인터페이스를 제공합니다 [4]. ASGI는 여러 클라이언트 간의 비동기 통신을 용이하게 하기 위해 장기간 유지되는 WebSocket 연결이 필요한 프로젝트의 요구 사항으로 인해 선택되었습니다. 또한 API 호출 중에 백그라운드 코루틴을 활용할 수 있습니다. PNLS는 ASGI 웹 서버를 사용하기 위해 Python용 uvicorn 구현을 사용합니다.
WebSocket 통신 프로토콜을 활용하면 전이중 양방향 통신이 가능합니다. 이 프로젝트에는 양방향 통신이 필요하지 않지만, 시스템 구성 요소 간의 실시간 상호 작용이 필요합니다. 이렇게 하면 스니핑된 데이터가 캡처되는 즉시 최종 사용자에게 제공됩니다.
프로젝트의 MOM은 Redis를 사용하는 메시지 브로커를 통해 실현됩니다. 발행-구독(pub-sub) 모델에서 Sniffer는 메시지를 생성하는 역할을 하며, 웹 애플리케이션(구독자)은 특정 주제(Redis 채널)에 등록합니다. Sniffer가 주제에 메시지를 보내면 등록된 모든 소비자에게 배포되어 비동기식 확장 가능한 통신이 가능합니다. PNLS는 메시지 브로드캐스팅을 위해 경량 메시징 프로토콜인 Redis Pub/Sub를 사용하여 지연 시간이 짧고 처리량이 많은 단기 메시지를 전파합니다 [5][6]. 이렇게 하면 데이터 구조를 디스크에 쓸 수 있는 형태로 인코딩하는 오버헤드가 방지됩니다. 이를 통해 이 솔루션은 잠재적으로 더 나은 성능을 제공할 수 있습니다 [7]. 아래 그림은 이벤트 중심 워크플로를 통한 단순화된 시스템 활동을 보여줍니다.
그림 7: PNLS 발행-구독 모델 시퀀스 다이어그램
[!NOTE] 구현된 MOM은 데이터 축적을 위한 영구 저장소나 메시지 큐를 제공하지 않습니다. 즉, 구독자가 없는 주제에 메시지가 발행되면 메시지가 손실됩니다.
다음은 게시된 테스트 SSID를 표시하는 웹 UI의 예입니다.
그림 8: PNLS 웹 - 테스트 SSID 예시
선호 네트워크 목록(PNL)은 장치를 해당 네트워크에 처음 연결할 때 생성한 저장된 SSID와 추가 설정의 모음입니다. ↩
서비스 세트 식별자(SSID)는 Wi-Fi 네트워크의 이름을 지정하는 데 사용되는 802.11 ID로, 최대 32자의 대소문자 구분 문자, 숫자 및 특수 문자로 구성되며 32자를 초과할 수 없습니다. ↩
모니터 모드, 프레임 인젝션 등을 가능하게 하는 Broadcom/Cypress Wi-Fi 칩용 C 기반 펌웨어 패치 프레임워크입니다. ↩
Broadcom은 공식적으로 모니터 모드를 지원하지 않아 라즈베리 파이 장치의 무선 카드 유용성이 제한되었습니다 [8]. Nexmon 프로젝트는 RPi 장치에서 사용되는 Broadcom 칩용 펌웨어 패치입니다 [1]. 이 패치를 사용하면 RPi 장치에서 모니터링 모드를 사용할 수 있습니다. ↩
| PNL | 선호 네트워크 목록 |
| PNLS | 선호 네트워크 목록 스니퍼 |
| SSID | 서비스 세트 식별자 |
| UI | 사용자 인터페이스 |
| RPi | 라즈베리 파이 |
| OS | 운영 체제 |
| AP | 액세스 포인트 |
| RF | 무선 주파수 |
| EDA | 이벤트 중심 아키텍처 |
| MOM | 메시지 지향 미들웨어 |
| ASGI | 비동기 서버 게이트웨이 인터페이스 |
| pub-sub | 발행-구독 |