
P4wnP1 A.L.O.A. by MaMe82는 Raspberry Pi Zero W를 침투 테스트, 레드 팀 운영 및 실제 보안 공격을 위한 유연하고 저렴한 플랫폼으로 변환하거나 "작은 공격 도구"로 변환하는 프레임워크입니다.
P4wnP1 A.L.O.A. by MaMe82는 라즈베리 파이 제로 W를 유연하고 저렴한 침투 테스트, 레드 팀 작업, 물리적 공격 플랫폼으로 변환하거나 "약간 공격적인 기기(A Little Offensive Appliance)"로 만드는 프레임워크입니다.
최신 이미지는 릴리스 탭에서 찾을 수 있습니다.
새로 설치된 P4wnP1 A.L.O.A.에 접근하는 가장 쉬운 방법은 스폰된 WiFi(PSK는 MaMe82-P4wnP1, URL은 http://172.24.0.1:8000) 또는 SSH(기본 비밀번호 toor)를 통해 웹 클라이언트를 사용하는 것입니다.
Math 사용 등) 작성 가능여기서 할 말이 많지 않습니다. P4wnP1 A.L.O.A.는 KALI Linux를 기반으로 하므로 필요한 모든 것을 바로 사용할 수 있습니다 (또는 apt를 사용하여 설치 가능)
따라서 원격 Windows 호스트에서 배치 파일을 사용하여 P4wnP1을 구성하려면 문제 없습니다:
host 매개변수 추가처음에는 계획되지 않았지만 P4wnP1 A.L.O.A.는 웹 클라이언트를 사용하여 구성할 수 있습니다. 클라이언트가 계획되지 않았음에도 불구하고 꽤 훌륭한 소프트웨어로 발전했습니다. 실제로 P4wnP1 A.L.O.A.의 주요 구성 도구가 되었습니다. 웹 클라이언트는 CLI에서 접근할 수 없는 기능(템플릿 저장, "TriggerActions" 생성)을 제공합니다.
핵심 기능:
CTRL+SPACE)이전 P4wnP1 버전의 자동화 접근 방식(정적 bash 스크립트)은 더 이상 사용할 수 없습니다.
P4wnP1 A.L.O.A.의 자동화 접근 방식은 다음 요구 사항을 충족해야 했습니다:
소위 "TriggerActions"를 도입하고 이를 템플릿 시스템(모든 하위 시스템에 대한 영구 설정 저장)과 결합함으로써 모든 요구 사항을 충족할 수 있었습니다. TriggerActions에 대한 자세한 내용은 WorkFlow 섹션에서 확인할 수 있습니다.
P4wnP1 A.L.O.A.는 정적 구성이나 페이로드와 같은 개념을 사용하지 않습니다. 실제로 정적 워크플로우가 전혀 없습니다.
P4wnP1 A.L.O.A.는 가능한 한 유연하게 설계되어 가능한 모든 시나리오(P4wnP1 A.L.O.A.를 만들면서 생각하지 못한 시나리오 포함)에서 사용할 수 있도록 의도되었습니다.
그러나 이 섹션에서 살펴볼 기본 개념이 몇 가지 있습니다. 적절한 (비디오) 문서 없이 모든 것을 설명하기는 어렵기 때문에, 몇 가지 일반적인 사용 사례와 예제를 통해 설명해야 할 내용을 설명하겠습니다.
그럼에도 불구하고 완전한 문서를 제공할 시간은 없을 것 같습니다. 그러므로 모든 분들이 이 README에 링크할 수 있는 튜토리얼과 아이디어를 제공해 주시기를 권장합니다
이제 가장 기본적인 작업 중 하나부터 시작하겠습니다:
이 목표를 달성하기 위한 최소 구성 요구 사항은:
P4wnP1의 기본 구성(수정되지 않은 이미지)은 이미 이러한 요구 사항을 충족합니다:
MaMe82-P4wnP1172.24.0.1172.16.0.1P4wnP11337172.26.0.1root, 기본 비밀번호는 toor참고: HTTPS 연결 배포는 현재 프로젝트 범위에 포함되지 않습니다. 따라서 웹 클라이언트에서 WiFi 자격 증명과 같은 민감한 데이터를 처리하는 경우 이 점을 염두에 두시기 바랍니다. 전체 프로젝트는 보안을 고려하여 구축되지 않았습니다(그리고 이것이 요구 사항이 될 가능성은 낮습니다). 따라서 적절한 조치를 배포하시기 바랍니다(예: 액세스 포인트가 개방 인증으로 구성된 경우 iptables로 웹 클라이언트 접근 제한; PIN 보호 없이 블루투스 검색 가능 및 연결 가능 상태를 유지하지 마십시오 등)
이 시점에서 다음을 가정합니다:
SSH 세션에서 CLI 클라이언트를 실행하려면 다음 명령을 실행하십시오:``` root@kali:~# P4wnP1_cli The CLI client tool could be used to configure P4wnP1 A.L.O.A. from the command line. The tool relies on RPC so it could be used remotely.
Version: v0.1.0-alpha1
Usage: P4wnP1_cli [command]
Available Commands: db Database backup and restore evt Receive P4wnP1 service events help Help about any command hid Use keyboard or mouse functionality led Set or Get LED state of P4wnP1 net Configure Network settings of ethernet interfaces (including USB ethernet if enabled) system system commands template Deploy and list templates trigger Fire a group send action or wait for a group receive trigger usb USB gadget settings wifi Configure WiFi (spawn Access Point or join WiFi networks)
Flags: -h, --help help for P4wnP1_cli --host string The host with the listening P4wnP1 RPC server (default "localhost") --port string The port on which the P4wnP1 RPC server is listening (default "50051")
Use "P4wnP1_cli [command] --help" for more information about a command.
The help screen already shows, that the CLI client uses different commands to interact with the various subsystems of P4wnP1 A.L.O.A. Most of these commands have own sub-commands, again. The help for each command or sub-command could be accessed by appending `-h` to the CLI command:```
root@kali:~# P4wnP1_cli hid run -h
Run script provided from standard input, commandline parameter or by path to script file on P4wnP1
Usage:
P4wnP1_cli hid run [flags]
Flags:
-c, --commands string HIDScript commands to run, given as string
-h, --help help for run
-r, --server-path string Load HIDScript from given path on P4wnP1 server
-t, --timeout uint32 Interrupt HIDScript after this timeout (seconds)
Global Flags:
--host string The host with the listening P4wnP1 RPC server (default "localhost")
--port string The port on which the P4wnP1 RPC server is listening (default "50051")
이제 USB 호스트에 "Hello world"를 입력하려면 다음 CLI 명령어를 사용할 수 있습니다:
P4wnP1_cli hid run -c 'type("Hello world")'
SSH 세션의 결과 출력은 다음과 유사해야 합니다:``` TempFile created: /tmp/HIDscript295065725 Start appending to 'HIDscript295065725' in folder 'TMP' Result: null
USB 호스트에서 "Hello World"가 키보드 포커스가 있는 애플리케이션에 입력되었어야 합니다.
*SSH 클라이언트가 USB 호스트 자체에서 실행 중인 경우, 입력된 "Hello world"는 CLI 명령의 결과 출력 사이 어딘가에 나타납니다 (출력에 속하지는 않지만, 그 사이에 입력된 것입니다).*
**목표 달성. 대상에 키 입력을 주입했습니다.**
키 입력 주입 같은 간단한 작업에 비해 많은 내용을 읽었지만, 다시 말하지만 이 섹션은 기본 개념을 설명하기 위한 것입니다.
### 2.2 HIDScript의 더 정교한 언어 기능으로 넘어가기
"Hello world" 키 입력 주입을 성공적으로 실행했다면, 이제 추가적인 HIDScript 기능을 살펴보기 좋은 시점입니다.
우리는 이미 `type` 명령어를 알고 있지만, 좀 더 정교한 HIDScript 명령어에 대해 논의해 보겠습니다:
#### 특수 키 및 조합 입력
`type` 명령어는 입력 문자열에 "새 줄" 문자를 인코딩하여 리턴 키를 누르는 것을 지원합니다. 예를 들어:```
P4wnP1_cli hid run -c 'type("line 1\nline 2\nline 3 followed by pressing RETURN three times\n\n\n")'
그렇다면 특수 키나 키 조합은 어떨까요?
press 명령이 도움이 됩니다!
press를 사용하여 USB 호스트에 CTRL+ALT+DELETE를 보내 봅시다:```
P4wnP1_cli hid run -c 'press("CTRL ALT DELETE")'
*참고: 두 개의 키는 수정자(CTRL 및 ALT)였고, 하나만 실제 키(DELETE)였습니다*
이제 수정자 키 없이 'A' 키를 눌러보겠습니다:```
P4wnP1_cli hid run -c 'press("A")'
결과 출력은 소문자 'a'여야 합니다. 왜냐하면 press("A")는 'A'를 키(key)로 해석하기 때문입니다. 반면 type("A") 명령은 대문자 'A' 출력 문자를 생성하는 키 조합을 누르려고 시도합니다.
대문자 'A' 출력 문자를 생성하기 위해 (즉, type("A")의 동작을 모방하기 위해) 수정자 키와 비수정자 키를 결합해 보겠습니다:```
P4wnP1_cli hid run -c 'press("SHIFT A")'
이것은 대문자 A 출력을 생성했어야 합니다.
중요한 것은, `press`는 주어진 키 인수를 키(key)로 해석하는 반면, `type`은 의도된 출력 문자를 생성하기 위해 적절한 키 조합을 찾으려고 한다는 점을 이해하는 것입니다.
마지막 예제로, `press`와 `type`을 결합해 보겠습니다.```
P4wnP1_cli hid run -c 'type("before caps\n"); press("CAPS"); type("after caps\n"); press("CAPS");'
마지막 명령은 문자열을 입력하고, CAPSLOCK을 전환하고, 다른 문자열을 입력한 후 CAPS LOCK을 다시 전환했습니다. 결과적으로 CAPSLOCK은 초기 상태(두 번 전환)여야 하지만, 두 문자열 모두 소문자로 입력되었음에도 불구하고 하나는 대문자, 다른 하나는 소문자로 입력됩니다.
press를 사용한 키 누름에 대한 추가 참고 사항:
USB 키보드 리포트의 내부 동작을 깊이 파고들고 싶지는 않지만, press 명령어(원시 키보드 리포트를 기반으로 작동)의 한계와 가능성을 정확히 짚어보기 위해 몇 가지 언급할 가치가 있습니다:
press는 최대 6개의 일반 키 또는 특수 키를 사용합니다
press("Z")는 EN_US 키보드 레이아웃에서 USB_KEY_Z를 생성하지만, 독일어 레이아웃에서는 USB_KEY_Y를 생성합니다. 이는 독일어 키보드에서 하드웨어 키 'Z'를 누르는 것과 같으며, 이 역시 USB_KEY_Y를 생성합니다.)/usr/local/P4wnP1/keymaps/common.json에는 가능한 모든 키가 포함된 형식화된 JSON 키맵이 있습니다(파일을 변경하지 않도록 주의하십시오)press 명령어에 여러 키를 추가해도 키 시퀀스가 생성되지 않습니다. 주어진 모든 키가 동시에 눌리고 동시에 해제됩니다.press는 키를 자동으로 해제하므로, 'ALT를 누른 상태에서 TAB을 누르고, TAB을 다시 누르고, ALT를 해제'와 같은 시퀀스는 현재 불가능합니다키보드 레이아웃을 변경하는 HIDScript 명령어는 layout(<language map name>)입니다.
다음 예제는 키보드 레이아웃을 'US'로 전환하여 무언가를 입력한 후, 계속 입력하기 전에 레이아웃을 'German'으로 전환합니다:``` P4wnP1_cli hid run -c 'layout("us"); type("Typing with EN_US layout\n");layout("de"); type("Typing with German layout supporting special chars üäö\n");'
위 명령의 출력 결과는 USB 호스트가 사용하는 대상 레이아웃에 따라 달라집니다.
독일어 키보드 레이아웃을 사용하는 호스트에서는 결과가 다음과 같습니다:```
Tzping with EN?US lazout
Typing with German layout supporting special chars üäö
US 키보드 레이아웃을 사용하는 호스트에서는 다음과 같이 보입니다:``` Typing with EN_US layout Tzping with German lazout supporting special chars [';
Please note, that the intended output is only achieved, if P4wnP1's keyboard layout aligns with the keyboard layout
actually used by the USB host.
`layout` 명령을 사용하면 P4wnP1의 내부 레이아웃을 대상 USB 호스트의 레이아웃에 맞출 수 있습니다.
실행 중인 HIDScript 중간에 레이아웃을 변경할 수 있으면 유용할 수 있습니다. 누가 알겠습니까? 아마도 여러분은
레이아웃을 변경하면서 명령을 입력하다가, 입력한 명령 중 하나가 원하는 효과를 얻을 때까지 대상 호스트의 키보드 레이아웃을
무차별 대입(bf로 시작하는 단어, 원문은 brute force)하고 싶을 수도 있습니다.
**중요:** 레이아웃은 전역적으로 적용됩니다. 즉, 여러 HIDScript가 동시에 실행 중이고 그중 하나의
스크립트가 새 레이아웃을 설정하면, 다른 모든 스크립트에도 즉시 영향을 미칩니다.
#### 타이핑 속도
기본적으로 P4wnP1은 가능한 한 빠르게 키 입력을 주입합니다. 목표에 따라 이것은 너무 과할 수 있습니다 (예:
타이핑 속도의 행동 분석을 기반으로 키 입력 주입을 방지하는 대책을 생각해 보십시오). HIDScript는 이 동작을 변경하는
명령을 지원합니다.
`typingSpeed(delayMillis, jitterMillis)`
`typingSpeed` 명령의 첫 번째 인수는 두 키 입력 사이에 적용되는 밀리초 단위의 일정한 지연을 나타냅니다.
두 번째 인수는 밀리초 단위의 추가 지터(jitter)입니다. 첫 번째 인수로 제공된 정적 지연에 0부터 주어진 지터(밀리초) 사이의
추가적인 무작위 지연을 더합니다.
`typingSpeed`를 사용하여 타이핑 속도를 늦춰 보겠습니다:```
P4wnP1_cli hid run -c 'typingSpeed(100,0); type("Hello world")'
다음으로, 일정한 지연 대신 랜덤 지터를 시도합니다:``` P4wnP1_cli hid run -c 'typingSpeed(0,500); type("Writing with random jitter up to 500 milliseconds")'
마지막으로, 두 값을 결합하고 조정하여 자연스러운 타이핑 속도를 시뮬레이션할 수 있습니다:```
P4wnP1_cli hid run -c 'typingSpeed(100,150); type("Writing with more natural speed")'
중요: 타이핑 속도는 전역적으로 적용됩니다. 즉, 여러 HIDScript가 동시에 실행 중이고 그중 하나가 새 타이핑 속도를 설정하면 다른 모든 스크립트도 즉시 영향을 받습니다.
LED 보고서, 더 정확히는 LED 상태 변화를 기다리는 것은 HIDScript의 더 정교한 키보드 기능 중 하나입니다. 매우 강력할 수 있지만 약간의 설명이 필요합니다.
USB 호스트 OS에 따라 키보드 상태 수정자(NUM LOCK, SCROLL LOCK, CAPS LOCK)가 여러 연결된 키보드 간에 공유된다는 것을 눈치챘을 수도 있습니다. 예를 들어, Windows 호스트에 두 개의 키보드를 연결하고 그중 하나에서 CAPS LOCK을 토글하면 두 키보드 모두에서 CAPS LOCK LED가 변경됩니다.
바로 이 테스트를 사용하여 특정 OS에서 키보드 상태 수정자가 모든 키보드에서 공유되는지 확인할 수 있습니다.
USB 호스트가 이러한 상태 공유를 지원하는 경우(예: Windows), P4wnP1의 HIDScript 언어가 이를 활용할 수 있습니다.
다음 시나리오를 상상해 보세요:
P4wnP1이 USB 호스트에 연결되어 있고 키 입력 주입을 적용하려고 하지만 HIDScript가 즉시 키 입력을 실행하지 않기를 원합니다. 대신 HIDScript는 호스트의 실제 키보드에서 NUMLOCK, CAPSLOCK 또는 SCROLLLOCK을 누를 때까지 기다려야 합니다. 왜일까요? 아마도 침투 테스트에 참여하고 있는데 누군가가 들어와서 갑자기 팝업된 콘솔 창에 엄청난 양의 문자가 마법처럼 입력되는 모습을 바로 그 "누군가"가 보게 하고 싶지 않기 때문일 것입니다. 그래서 "누군가"가 나갈 때까지 기다렸다가 NUM LOCK을 누르면 결국 콘솔 창이 팝업되고 엄청난 양의 문자가 마법처럼 입력됩니다... 아마 이해하셨을 겁니다.
설명된 동작은 다음과 같이 구현할 수 있습니다:``` P4wnP1_cli hid run -c 'waitLED(NUM); type("A huge amount of characters\n")'
위 명령을 테스트했다면, USB 호스트의 하드웨어 키보드에서 NUM LOCK이 눌려져 있을 때만 타이핑이 시작되어야 하지만, NUM LOCK이 눌리지 않았음에도 키 입력이 즉시 전송되는 경우가 발생할 수 있습니다 (그리고 키보드 LED가 변경되지 않았습니다).
이는 의도된 동작이며, 그 이유는 `waitLED` 명령의 또 다른 사용 사례 때문입니다:
아마도 이전에 다른 키보드 스크립팅 언어나 키 입력을 주입할 수 있는 다른 USB 장치를 사용해 본 적이 있을 것입니다. 이러한 장치들은 대부분 공통적인 문제를 가지고 있습니다: 언제 타이핑을 시작해야 할지 모른다는 것입니다!
USB 장치에 전원이 공급된 직후에 타이핑을 시작하면, USB 호스트가 장치 열거를 완료하지 않아 키보드 드라이버를 올리지 못했을 가능성이 높습니다. 결국 키 입력은 손실됩니다.
이를 극복하기 위해 키 입력 주입이 시작되기 전에 지연 시간을 추가할 수 있습니다. 하지만 이 지연 시간은 얼마나 되어야 할까요? 5초, 10초, 30초?
정답은: 상황에 따라 다릅니다! 호스트가 장치를 열거하고 키보드 드라이버를 올리는 속도에 따라 달라집니다. 실제로 실제 대상에 대해 테스트하지 않고는 이 시간이 얼마나 걸리는지 알 수 없습니다.
하지만 우리가 이미 배웠듯이, Windows와 같은 운영 체제는 여러 키보드 간에 LED 상태를 공유합니다. 즉, 두 번째 키보드를 연결하기 전에 호스트 키보드의 NUMLOCK LED가 켜져 있으면, 연결 후 이 새 키보드의 NUMLOCK LED도 켜져야 합니다. NUM LOCK LED가 꺼져 있었다면, 새로 연결된 키보드는 LED 상태를 수신합니다 (이 경우 모든 LED가 꺼짐). 흥미로운 점은 이 "LED 업데이트"는 키보드 드라이버가 로드를 완료한 경우에만 USB 호스트에서 연결된 키보드로 전송될 수 있다는 것입니다 (그렇지 않으면 LED 상태를 보낼 수 없습니다).
아름답지 않나요? USB 호스트가 우리에게 말해줍니다: "키 입력을 받을 준비가 되었습니다". 초기 지연 시간을 가지고 놀 필요가 없습니다.
하지만 여기에 또 다른 문제가 있습니다: P4wnP1을 USB 호스트에 연결한다고 가정해 봅시다. 수동으로 만든 지연 시간 대신 `waitLED`로 시작하는 HIDScript를 실행합니다. `waitLED` 이후에 타이핑이 시작되지만 아무 일도 일어나지 않습니다 - 키 입력은 어쨌든 손실됩니다! 왜일까요? LED 상태 업데이트가 HIDScript를 시작하기도 전에 도착했기 때문에 이를 놓쳤을 가능성이 높기 때문입니다.
바로 이 "경쟁 조건"이 P4wnP1이 인식된 모든 LED 상태 변경을 보존하는 이유입니다. 단, 적어도 하나의 HIDScript가 `waitLED`(또는 `waitLEDRepeat`)를 호출하여 이를 소비하지 않는 한 말이죠. 이로 인해 앞서 설명된 동작이 발생할 수 있습니다. 즉, LED 변경이 발생하지 않았음에도 `waitLED`가 즉시 반환되는 경우입니다. 이제 우리는 알 수 있습니다: LED 변경은 실제로 발생했지만, 상태 변경이 보존되었기 때문에 훨씬 더 일찍 발생했을 수 있습니다 (HIDScript를 시작하기도 전에). 또한 `waitLED`가 "USB 호스트의 키보드 드라이버 준비 상태"를 테스트하는 데 사용되는 경우, LED 상태 변경을 놓치지 않도록 이 동작이 필요하다는 것도 알고 있습니다.
*참고: 언급할 가치가 있는 것은 `waitLED`는 수신된 LED 상태가 P4wnP1의 내부 상태와 다를 때만 반환된다는 점입니다. 즉, `waitLED(ANY)`로 특정 LED의 변경을 기다리더라도, USB 호스트로부터 P4wnP1의 내부 상태와 다른 점이 없는 초기 LED 상태를 수신할 수 있습니다. 이 경우 `waitLED(ANY)`는 영원히 차단됩니다 (또는 실제 LED 변경이 일어날 때까지). 이 특수한 경우는 `waitLED(ANY_OR_NONE)`을 호출하여 처리할 수 있습니다. 이는 새로운 LED 상태가 도착하는 즉시 반환되며, 변경이 발생하지 않더라도 마찬가지입니다.*
**설명은 충분합니다. 이제 실제로 해봅시다... 그 전에 하드웨어 설정을 약간 변경해야 합니다:**
라즈베리 파이 제로의 두 번째 USB 포트(바깥쪽 포트)에 외부 전원 공급 장치를 연결합니다. 이렇게 하면 P4wnP1이 더 이상 버스 전원에 의존하지 않기 때문에 USB 호스트에서 분리될 때 전원이 꺼지지 않습니다. P4wnP1을 대상 USB 호스트에 연결하는 데 사용해야 하는 USB 포트는 두 포트 중 안쪽 포트입니다.
이제 다음 HIDScript를 시작합니다```
P4wnP1_cli hid run -c 'while (true) {waitLED(ANY);type("Attached\n");}'
P4wnP1을 USB 호스트에서 분리하세요 (전원이 켜져 있는지 확인하세요)! 다시 USB 호스트에 연결하세요... P4wnP1을 호스트에 다시 연결할 때마다 호스트에 "Attached"가 입력되어야 합니다.
이를 통해 3가지 사실을 알 수 있었습니다:
waitLED는 키보드 드라이버가 준비되는 즉시 입력을 시작하도록 스크립트의 초기 명령으로 사용될 수 있습니다.waitLED는 USB 호스트에서 LED를 변경하는 키를 누를 때까지 HID 스크립트를 일시 중지하는 완벽한 선택은 아닙니다. 왜냐하면 보존된 상태 변경이 의도하지 않은 방식으로 명령을 해제할 수 있기 때문입니다.아직 waitLED 명령어를 마무리하지 않았지만, 이제 세 번째 사실을 처리합니다. CLI를 종료합시다.
http://172.24.0.1:8000).ms_snake.js는 LED 기반 트리거의 강력함을 보여주는 아주 좋은 예입니다).편집기 창의 스크립트를 다음 스크립트로 교체하세요:``` return waitLED(ANY);
실행 버튼을 누른 후, 창 오른쪽에 새로운 실행 중인 HID 작업이 표시되어야 합니다. HIDScript 작업 오른쪽에 있는 작은 "info" 버튼을 누르면 세부 사항(예: 상태(실행 중이어야 함), 작업 ID, VM ID(이 작업을 실행하는 JavaScript VM 번호. 이러한 VM은 8개가 있으므로 8개의 HIDScript를 병렬로 실행할 수 있음))을 볼 수 있습니다.
이제 USB 호스트에서 LED 변경이 발생하면(NUM, CAPS 또는 SCROLL 전환을 통해) HIDScript 작업이 종료되어야 합니다. 이 작업은 "Succeeded" 작업에서도 찾을 수 있습니다.
작은 "info" 버튼을 다시 누르면 결과 값(JSON으로 인코딩됨)에 대한 정보가 표시되며, 이는 다음과 같습니다:```
{"ERROR":false,"ERRORTEXT":"","TIMEOUT":false,"NUM":true,"CAPS":false,"SCROLL":false,"COMPOSE":false,"KANA":false}
그러므로 waitLED 명령은 다음과 같은 JavaScript 객체를 반환합니다:```
{
ERROR: false, // gets true if an error occurred (f.e. HIDScript was aborted, before waitLED could return)
ERRORTEXT: "", // corresponding error string
TIMEOUT: false, // gets true if waitLED timed out (more on this in a minute)
NUM: true, // gets true if NUM LED had changed before waitLED returned
CAPS: false, // gets true if CAPS LED had changed before waitLED returned
SCROLL: false, // gets true if SCROLL LED had changed before waitLED returned
COMPOSE: false, // gets true if COMPOSE LED had changed before waitLED returned (uncommon)
KANA: false // gets true if KANA LED had changed before waitLED returned (uncommon)
}
제 경우에는 `NUM`이 참이 되었습니다. 여러분의 경우에는 아마 `CAPS`였을 수도 있습니다. 어떤 LED였는지는 중요하지 않습니다. 중요한 점은 반환 값이 명령을 반환하게 만드는 LED 변경을 검사할 기회를 제공하며, 따라서 이를 통해 (USB 호스트의 실제 키보드에서 발행된 LED 상태 변경에 기반하여) HIDScript에서 분기 결정을 내리는 데 사용할 수 있다는 사실입니다.
예제를 시도해 보겠습니다:```
while (true) {
result = waitLED(ANY);
if (result.NUM) {
type("NUM has been toggled\n");
}
if (result.SCROLL) {
type("SCROLL has been toggled\n");
}
if (result.CAPS) {
break; //exit loop
}
}
Assuming the given script is already running, pressing NUM on the USB host should result in typing out "NUM has been toggled", while pressing SCROLL LOCK results in the typed text "SCROLL has been toggled". This behavior repeats, until CAPS LOCK is pressed and the resulting LED change aborts the loop and ends the HIDScript.
주어진 스크립트가 이미 실행 중이라고 가정할 때, USB 호스트에서 NUM을 누르면 "NUM has been toggled"가 타이핑되고, SCROLL LOCK을 누르면 "SCROLL has been toggled"가 타이핑됩니다. 이 동작은 CAPS LOCK이 눌려 결과 LED 변경이 루프를 중단하고 HIDScript를 종료할 때까지 반복됩니다.
Puhhh ... a bunch of text on this command for a single HIDScript command, but there still some things left.
휴... 단일 HIDScript 명령어에 대한 설명이 길었지만, 아직 남은 내용이 있습니다.
We provided arguments like NUM, ANY or ANY_OR_NONE to the waitLED command, without further explanation.
waitLED 명령어에 NUM, ANY, ANY_OR_NONE 같은 인수를 추가 설명 없이 사용했습니다.
The waitLED accepts up to two arguments:
waitLED는 최대 두 개의 인수를 받습니다:
The first argument, as you might have guessed, is a whitelist filter for the LEDs to watch. Valid arguments are:
ANY (react on a change to any of the LEDs)ANY_OR_NONE (react on every new LED state, even if there's no change)NUM (ignore all LED changes, except on the NUM LED)CAPS (ignore all LED changes, except on the NUM CAPS)SCROLL (ignore all LED changes, except on the NUM SCROLL)CAPS | NUM, NUM | SCROLL첫 번째 인수는 짐작하셨겠지만, 감시할 LED에 대한 화이트리스트 필터입니다. 유효한 인수는 다음과 같습니다:
ANY (모든 LED 변경에 반응)ANY_OR_NONE (변경이 없더라도 모든 새 LED 상태에 반응)NUM (NUM LED를 제외한 모든 LED 변경 무시)CAPS (CAPS LED를 제외한 모든 LED 변경 무시)SCROLL (SCROLL LED를 제외한 모든 LED 변경 무시)CAPS | NUM, NUM | SCROLL처럼 조합할 수 있습니다.The second argument, we haven't used so far, is a timeout duration in milliseconds. If no LED change occurred during
this timeout duration, waitLED returns and has TIMEOUT: true set in the resulting object (additionally ERROR is
set to true and ERRORTEXT indicates a timeout).
두 번째 인수는 지금까지 사용하지 않았으며, 밀리초 단위의 타임아웃 시간입니다. 이 타임아웃 시간 동안 LED 변경이 없으면 waitLED는 반환되며 결과 객체에 TIMEOUT: true가 설정됩니다 (추가로 ERROR는 true로 설정되고 ERRORTEXT는 타임아웃을 나타냅니다).
The following command would wait for a change on the NUM LED, but aborts waiting after 5 seconds:
다음 명령어는 NUM LED의 변경을 기다리지만, 5초 후에 대기를 중단합니다:``` waitLED(NUM,5000)
`waitLED`는 올바르게 사용하면 매우 강력한 명령이지만, 대상 USB 호스트에서 상태 수정자 키가 눌릴 때까지 HIDScript를 강건하게 일시 중지하는 간단한 작업을 처리하는 데는 도움이 되지 않았습니다. (기억하세요: 타자가 시작되기 전에 원치 않는 "누군가"가 나갈 때까지 실행을 일시 중지하려 했지만, `waitLED`는 보존된 LED 상태 변경 때문에 가끔 조기에 반환되었습니다.)
이것이 바로 `waitLEDRepeat`가 등장하여 구원하는 부분입니다.
다음 스크립트를 편집기에 붙여넣고 명령이 반환되도록 해보세요. 이후 HIDScript 결과를 검사하세요.```
return waitLEDRepeat(ANY)
동일한 LED가 자주 여러 번 변경되어야
waitLEDRepeat 명령이 반환된다는 것을 금방 알 수 있을 것입니다. 서로 다른 LED의 상태가 변경되거나
단일 LED의 변경이 너무 느리게 발생하면 waitLEDRepeat 명령이 반환되지 않습니다.
waitLEDRepeat에 제공된 인수(예제에서는 ANY)는 waitLED와 동일한 목적을 수행합니다.
이는 화이트리스트 필터입니다. 예를 들어 waitLEDRepeat(NUM)은 NUM LOCK LED의 변경에 대해서만 반환됩니다 - 아무리
빠르고 자주 CAPS LOCK 키를 눌러도 NUM LOCK이 자주 눌리지 않으면 반환되지 않습니다.
기본적으로, waitLEDRepeat가 반환되려면 화이트리스트에 포함된 LED 중 하나가 3번 변경되어야 하고, 두 번의 연속된 변경 사이의 지연 시간이 800밀리초를 초과하지 않아야 합니다. 이 동작은 조정될 수 있습니다, 제공함으로써
다음 예제와 같은 추가 인수를:```
filter = ANY; // same filters as for waitLED
num_changes = 5; // how often the SAME LED has to change, in order to return from waitLEDRepeat
max_delay = 800; // the maximum duration between two LED changes, which should be taken into acccount (milliseconds)
timeout = 10000; // timeout in milliseconds
waitLEDRepeat(filter, num_changes, max_delay); //wait till a LED frequently changed 5 times, no timeout waitLEDRepeat(filter, num_changes, max_delay, timeout); //wait till a LED frequently changed 5 times, abort after 10 seconds
그게 바로 HIDScript에서 USB 호스트의 LED 보고서와 상호작용하는 방법입니다.
*참고: `waitLEDRepeat`는 보존된 LED 상태 변경의 소비에 관해서는 `waitLED`와 다르지 않습니다.
어쨌든, 의도치 않게 트리거하기는 훨씬 어렵습니다.*
따라서 `waitLEDRepeat`는 사람의 상호작용이 있을 때까지 HIDScript를 일시 중지하는 작업에 적합한 선택입니다. 물론 `waitLED`와 동일한 반환 객체를 제공하므로 분기(branching)에도 사용할 수 있습니다.
지금까지 우리는 HIDScript에 대해 꽤 많은 지식을 얻었습니다(물론 모든 것에 대해서는 아니며, 이 스크립팅 언어의 마우스 제어 기능조차 아직 살펴보지 않았습니다). 어쨌든, 이 튜토리얼은 P4wnP1 A.L.O.A. 워크플로우와 기본 개념에 관한 것입니다. 따라서 지금은 다른 HIDScript 기능을 살펴보지 않고 넘어가겠습니다.
지금까지 P4wnP1의 워크플로우와 개념에 대해 배운 내용을 요약해 보겠습니다.
- CLI 클라이언트에서 주문형(on-demand)으로 키스트로크 인젝션과 같은 작업을 시작할 수 있었습니다.
- 웹 클라이언트를 사용하여 동일한 작업을 수행할 수 있었으며, HIDScript 작업에 대한 추가 제어도 가능했습니다.
- 외부 전원 공급 장치를 P4wnP1 A.L.O.A.에 연결하면 다른 USB 호스트에 연결/분리할 때 이미 시작된 HIDScript가 중단 없이 계속 작동했습니다.
- USB 스택을 필요에 맞게 정확히 구성할 수 있었습니다(재부팅 없이 런타임에 구성을 변경할 수 있습니다).
- 함수, 루프, 분기 등을 지원하는 JavaScript 기반의 다목적 HIDScript를 복잡한 로직으로 작성할 수 있었습니다.
### 3. 워크플로우 2부 - 템플릿과 TriggerActions
P4wnP1 A.L.O.A.의 다른 주요 개념으로 넘어가기 전에, 첫 번째 목표였던 "USB 호스트에 대한 키스트로크 인젝션 실행"을 구체화해 보겠습니다.
- 새로운 목표는 Windows USB 호스트(notepad.exe)의 편집기에 "Hello world"를 입력하는 것입니다.
- 편집기는 P4wnP1이 열어야 합니다(사용자가 수동으로 열지 않음).
- USB 호스트의 키보드 LED 중 하나가 토글되면 편집기가 자동으로 닫혀야 합니다.
- P4wnP1이 USB 호스트에 연결될 때마다 이 동작이 반복되어야 합니다(외부 전원 사용, P4wnP1 재부팅 없음).
- HIDScript가 시작된 후 키보드 LED 변경이 연속으로 발생하더라도, 이 프로세스는 P4wnP1이 USB 호스트에 다시 연결되지 않는 한 *한 번만 실행되어야 합니다*.
- P4wnP1이 재부팅되더라도, 설정 세부 사항을 처음부터 다시 만들지 않고 동일한 동작을 복구할 수 있어야 합니다.
메모장을 시작하고 "Hello world"를 입력한 후 LED 변경 후 메모장을 닫는 것은 지금까지 배운 내용으로 가능합니다. 이에 해당하는 HIDScript는 다음과 같을 수 있습니다:```
// Starting notepad
press("WIN R"); // Windows key + R, to open run dialog
delay(500); // wait 500ms for the dialog to open
type("notepad.exe\n"); // type 'notepad.exe' to the run dialog, append a RETURN press
delay(2000); // wait 2 seconds for notepad to come up
// Type the message
type("Hello world") // Type "Hello world" to notepad
// close notepad after LED change
waitLED(ANY); // wait for a single LED change
press("ALT F4"); // ALT+F4 shortcut to close notepad
//as we changed content, there will be a confirmation dialog before notepad exits
delay(500); // wait for the confirmation dialog
press("RIGHT"); // move focus to next button (don't save) with RIGHT ARROW
press("SPACEBAR"); // confirm dialog with space
이 스크립트에서 새로운 것은 delay 명령뿐인데, 이는 별다른 설명이 필요하지 않습니다. 주어진 밀리초만큼 실행을 지연시킵니다.
스크립트를 웹클라이언트 HIDScript 편집기에 붙여넣고 "run"으로 시작하여 테스트할 수 있습니다.
의도한 대로 작동할 것이므로 거의 완료되었습니다. 재부팅 후에도 스크립트를 재사용할 수 있도록 지속적으로 저장합니다. 이는 웹클라이언트의 HIDScript 탭에서 "store" 버튼을 누르면 됩니다. 이름(여기서는 tutorial1을 사용)을 입력하고 대화상자를 확인하면 HIDScript가 저장됩니다. 웹클라이언트의 "Load & Replace" 버튼을 눌러 확인할 수 있습니다. 저장된 스크립트는 tutorial1.js라는 이름으로 저장된 스크립트 목록에 나타납니다(.js 확장자는 "store" 대화상자에 아직 제공되지 않은 경우 자동으로 추가됩니다).
경고: "store" 대화상자에 이미 존재하는 파일 이름을 사용하면 추가 확인 없이 해당 파일이 덮어쓰기됩니다.
저장된 스크립트를 SSH 세션의 CLI 클라이언트에서 다음과 같이 시작해 봅시다:``` P4wnP1_cli hid run tutorial1.js
이것은 작동했어야 합니다. 즉, P4wnP1 A.L.O.A. CLI 클라이언트를 사용하여 셸 명령어를 지원하는 모든 애플리케이션이나 간단한 bash 스크립트에서 저장된 HIDScript를 시작할 수 있습니다.
Windows용으로 컴파일된 CLI 클라이언트에서 원격으로 스크립트를 시작하는 것도 가능합니다. Windows 호스트가 WiFi를 통해 P4wnP1 A.L.O.A.에 연결할 수 있고 P4wnP1의 IP가 `172.24.0.1`로 설정되어 있다고 가정하면 적절한 명령어는 다음과 같습니다:```
P4wnP1_cli.exe --host 172.24.0.1 hid run tutorial1.js
참고: 이 글을 쓰는 시점에서, P4wnP1 A.L.O.A.가 모든 가능한 플랫폼과 아키텍처에 대해 CLI 바이너리를 제공할지 아직 결정하지 않았습니다. 하지만 주요 플랫폼용으로 미리 컴파일된 버전이 제공될 가능성이 높습니다. 그렇지 않더라도 - CLI 클라이언트의 Go 코드 크로스 컴파일은 1분 미만이 소요되므로 큰 문제가 되지 않습니다.
다음 단계는 P4wnP1이 USB 호스트에 다시 연결될 때마다 스크립트가 다시 실행되도록 하는 것입니다. 이러한 동작을 달성하기 위해 이미 사용한 방법은 모든 것을 루프로 감싸고 waitLED(ANY_OR_NONE)을 앞에 추가하는 것이었습니다. waitLED(ANY_OR_NONE)은 대상 USB 호스트가 전역 키보드 LED 상태 업데이트를 보내 키보드 드라이버가 입력을 받을 준비가 되었음을 알릴 때만 루프가 계속되도록 보장했습니다. 이에 따라 수정된 스크립트는 다음과 같습니다:```
while (true) {
waitLED(ANY_OR_NONE); // wait till keyboard driver sends the initial LED state
// Starting notepad press("WIN R"); // Windows key + R, to open run dialog delay(500); // wait 500ms for the dialog to open type("notepad.exe\n"); // type 'notepad.exe' to the run dialog, append a RETURN press delay(2000); // wait 2 seconds for notepad to come up
// Type the message type("Hello world") // Type "Hello world" to notepad
// close notepad after LED change waitLED(ANY); // wait for a single LED change press("ALT F4"); // ALT+F4 shortcut to close notepad
//as we changed content, there will be a confirmation dialog before notepad exits delay(500); // wait for the confirmation dialog press("RIGHT"); // move focus to next button (don't save) with RIGHT ARROW press("SPACEBAR"); // confirm dialog with space }
위의 스크립트는 실제로 P4wnP1이 USB 호스트에 연결될 때마다 실행됩니다. 하지만 이 스크립트는 그다지 강력하지 않은데, 두 번째 `waitLED`가 포함되어 있어서 notepad.exe가 다시 닫힐 때까지 기다리기 때문입니다.
이렇게 하면 여러 문제가 발생합니다. 예를 들어, "Hello world"가 입력되기 전에 P4wnP1이 분리되면, 지금 차단된 `waitLED`가 `press("ALT F4")` 이전의 것이 되어, P4wnP1이 (다른) USB 호스트에 다시 연결될 때 HIDScript의 정확히 그 지점부터 실행이 계속됩니다.
선택한 접근 방식에 대한 결정적인 종료 기준은 다음과 같은 문제입니다. 스크립트가 USB 호스트에 P4wnP1이 연결된 후 한 번만 실행되어야 한다는 요구 사항을 충족할 수 없는데, NUM LOCK을 여러 번 누르면 스크립트가 계속해서 다시 시작되기 때문입니다.
그렇다면 어떻게 해결할까요?
#### TriggerActions 소개
이 문제에 대한 해결책은 소위 "TriggerActions"입니다. 이름에서 알 수 있듯이, 이 P4wnP1 A.L.O.A. 워크플로우 개념은 미리 정의된 트리거를 기반으로 작업을 실행합니다.
제가 말하는 것이 무엇인지 감을 잡으려면 웹클라이언트의 "TRIGGER ACTIONS" 탭으로 이동하세요. 현재 설정에 따라 이미 TriggerActions가 존재할 수 있습니다. 지금은 기존 TriggerActions에 신경 쓰지 않습니다.
"ADD ONE" 버튼을 누르면 새로운 TriggerActions가 추가되고 즉시 편집 모드로 열립니다. 새 TriggerAction은 기본적으로 비활성화되어 있으며, 편집 가능하게 하려면 활성화해야 합니다. 따라서 활성화 스위치를 토글합니다.
이제 "Trigger"라는 풀다운 메뉴에서 "USB gadget connected to host" 옵션을 선택해야 합니다. 작업에는 미리 "write log entry"가 선택되어 있어야 합니다. 이 상태로 두고 "Update" 버튼을 누릅니다.
새로 추가된 TriggerAction이 이제 TriggerActions 개요(가장 높은 ID를 가진 것)에 표시되며, 선택한 트리거와 선택한 작업에 대한 요약을 읽을 수 있는 형식으로 보여줍니다.
새로 정의된 TriggerAction이 작동하는지 테스트하려면 웹클라이언트의 "Event Log" 탭으로 이동하세요. WiFi를 통해 웹클라이언트를 열어야 합니다(USB 이더넷이 아님). P4wnP1에 외부 전원을 연결하고, USB 호스트에서 분리한 후 다시 연결합니다. P4wnP1이 USB 호스트에 연결될 때마다 즉시 로그 메시지가 클라이언트로 푸시됩니다.
이것을 몇 번 반복했다면 "USB gadget connected to host" 트리거가 매우 빠르게(또는 USB 열거 단계의 초기 단계에서) 발생한다는 것을 알 수 있습니다. 더 정확히 말하면, 이 트리거가 발생할 때 P4wnP1이 USB 호스트에 연결되었다는 것은 알 수 있지만, USB 호스트가 필요한 모든 USB 장치 드라이버를 로드했는지는 보장할 수 없습니다. **실제로 트리거가 발생할 때 USB 키보드 드라이버가 로드되었을 가능성은 매우 낮습니다. 이 점을 명심해야 합니다.**
작업을 계속 진행하기 전에 추가 테스트를 하나 해보겠습니다. "TriggerAction" 탭으로 돌아가서 새로 만든 TriggerAction에 대해 펜 모양의 작은 파란색 버튼을 누릅니다. 다시 편집 모드로 들어갑니다.
이번에는 `One shot` 옵션을 활성화합니다. 그 후 "Event Log"로 돌아가서 P4wnP1을 USB 호스트에서 분리했다가 다시 연결합니다. 이번에는 TriggerAction이 한 번만 실행되어야 합니다. 이후 P4wnP1이 USB 호스트에 다시 연결되어도 USB 연결을 나타내는 새 로그 메시지가 생성되지 않습니다.
"One shot" TriggerAction은 트리거가 실행된 후 삭제되지 않는다는 점을 언급할 가치가 있습니다. 대신 TriggerAction이 다시 비활성화됩니다. 다시 활성화하면 TriggerAction을 다시 정의하지 않고 재사용할 수 있습니다. 빨간색 "trash" 버튼을 누르면 해당 TriggerAction이 삭제될 때까지 아무것도 손실되지 않습니다.
**경고: TriggerAction의 삭제 버튼을 클릭하면 추가 확인 없이 TriggerAction이 영구적으로 삭제됩니다.**
이 시점에서 당연한 작업을 해보겠습니다. 생성된 TriggerAction을 편집하고 실행할 작업으로 "write log entry" 대신 "start a HIDScript"를 선택합니다. 또한 "one-shot"을 다시 비활성화합니다. "script name"이라는 새 입력 필드가 나타납니다. 이 입력 필드를 클릭하면 이전에 만든 `tutorial1.js` HIDScript를 포함하여 저장된 모든 HIDScript의 선택 대화상자가 나타납니다.
*이것이 작동하는지 테스트하기 전에 "write log entry" 작업에 대해 간략히 설명하겠습니다. P4wnP1 A.L.O.A.는 이미 실행된 트리거를 추적하지 않습니다. 즉, "write log entry" 작업으로 생성된 로그 항목은 모든 수신 클라이언트에 전달되지만 P4wnP1 서비스에 저장되지는 않습니다(여러 이유로). 반면 웹클라이언트는 로그 항목을 웹클라이언트 자체가 다시 로드될 때까지 저장합니다. 이는 HIDScript 작업과 관련된 이벤트에도 동일하게 적용됩니다. HIDScript가 종료되면(성공 또는 오류), 현재 열려 있는 모든 웹클라이언트에 이벤트가 푸시됩니다. 요약하면, 각 웹클라이언트에는 코어 서비스 자체보다 더 많은 정보를 보유하는 런타임 상태가 있습니다. 웹클라이언트의 런타임 상태가 너무 커지면(메모리 사용량이 너무 많음), 클라이언트를 다시 로드하여 "기록" 상태 정보를 지우기만 하면 됩니다. 코어 서비스가 동일하게 작동하여 모든 기록 정보를 저장한다면 곧 리소스가 부족해질 것입니다. 따라서 이 개념은 P4wnP1 A.L.O.A.의 대부분의 하위 시스템에 적용됩니다.*
이제 작업으로 돌아갑니다. P4wnP1이 USB 호스트에 연결될 때마다 HIDScript를 실행해야 하는 TriggerAction이 준비되었습니다.
대상 USB 호스트에 따라 이것은 어느 정도 안정적으로 작동합니다. 제 테스트 설정에서는 전혀 작동하지 않았고 그 이유가 있습니다.
HIDScript의 처음 몇 줄을 검토해 보겠습니다.```
// Starting notepad
press("WIN R"); // Windows key + R, to open run dialog
delay(500); // wait 500ms for the dialog to open
type("notepad.exe\n"); // type 'notepad.exe' to the run dialog, append a RETURN press
... snip ...
"USB gadget connected" 트리거가 USB 열거 초기 단계에서 발생하며, USB 호스트의 키보드 드라이버가 반드시 로드되어 있지 않다는 사실을 상기하면 문제가 명확해집니다. 키보드 드라이버가 활성화되었는지 확인하기 위해 스크립트에 일종의 지연을 앞에 추가해야 합니다(그렇지 않으면 키 입력이 아무데도 전달되지 않습니다). 최적의 지연 시간을 예측할 수 없다는 것을 이미 알고 있으므로, 앞서 설명한 waitLED(ANY_OR_NONE) 방식을 사용합니다. 새로운 스크립트는 다음과 같습니다:```
waitLED(ANY_OR_NONE); //assure keyboard driver is ready
// Starting notepad press("WIN R"); // Windows key + R, to open run dialog delay(500); // wait 500ms for the dialog to open type("notepad.exe\n"); // type 'notepad.exe' to the run dialog, append a RETURN press delay(2000); // wait 2 seconds for notepad to come up
// Type the message type("Hello world") // Type "Hello world" to notepad
// close notepad after LED change waitLEDRepeat(ANY); // wait for a single LED change press("ALT F4"); // ALT+F4 shortcut to close notepad
//as we changed content, there will be a confirmation dialog before notepad exits delay(500); // wait for the confirmation dialog press("RIGHT"); // move focus to next button (don't save) with RIGHT ARROW press("SPACEBAR"); // confirm dialog with space
수정된 스크립트를 정확히 같은 이름(`tutorial1`)으로 저장하면, 앞서 지적한 대로 이전 HIDScript를 추가 확인 없이 덮어씁니다. 따라서 TriggerAction을 조정할 필요가 없습니다. TriggerAction이 참조하는 HIDScript 이름이 변경되지 않았기 때문입니다.
이 작은 변경으로 모든 것이 의도한 대로 작동하며, USB 호스트에 연결할 때마다 스크립트가 트리거되지만 한 번만 실행됩니다.
이제 P4wnP1이 재부팅되거나 전원이 꺼져도 HIDScript는 영구적으로 저장되었으므로 유지되지만, TriggerAction은 사라집니다. 물론 TriggerAction도 영구적으로 저장할 수 있습니다.
"TriggerAction" 탭의 "store" 버튼은 HIDScript 편집기의 버튼과 정확히 동일하게 작동합니다. "store" 대화상자가 확인되면 *현재 활성화된 모든 TriggerAction*이 저장된다는 점에 유의하십시오(비활성화된 것도 포함).
가장 좋은 방법은 저장하기 전에 현재 범위의 작업에 속하지 않는 TriggerAction을 모두 삭제하고(필요했다면 이전에 저장했어야 함), 현재 작업과 관련된 작은 TriggerAction 집합만 적절한 이름으로 저장하는 것입니다. 저장된 TriggerAction을 활성화된 항목으로 다시 로드하는 두 가지 옵션이 있습니다.
- "load & replace"는 모든 활성 TriggerAction을 지우고 저장된 항목만 로드합니다.
- "load & add"는 이미 활성화된 TriggerAction을 유지하고 저장된 항목을 추가합니다. 따라서 "load & add"를 사용하여 더 작은 집합으로 복잡한 TriggerAction 집합을 구성할 수 있습니다. 결과 집합은 다시 저장할 수 있습니다.
지금은 HIDScript를 시작하는 단일 TriggerAction만 저장해야 합니다. 저장에 사용하는 이름은 다시 `tutorial1`이며, `tutorial1`이라는 HIDScript와 충돌하지 않습니다.
"TriggerAction" 탭에서 "load&replace" 버튼을 클릭하여 저장이 성공했는지 확인합니다. 저장된 TriggerAction 집합이 목록에 나타나야 하며 이름이 `tutorial1`이어야 합니다.
**경고: TriggerAction "load" 대화상자에서는 각 작업 옆의 빨간색 "trash" 버튼을 클릭하여 저장된 TriggerAction을 삭제할 수 있습니다. 버튼을 클릭하면 추가 확인 없이 해당 TriggerAction 집합이 영구적으로 삭제됩니다.**
이 시점에서 "TriggerActions" 탭에서 TriggerAction을 안전하게 삭제할 수 있습니다(!!로드 대화상자의 휴지통 버튼이 아닙니다!!).
활성화된 항목에서 TriggerAction을 삭제하면 USB 호스트에서 P4wnP1을 분리했다가 다시 연결해도 아무 일도 일어나지 않습니다.
어쨌든 저장된 TriggerAction 집합 `tutorial1`은 재부팅 후에도 유지되며 언제든지 다시 로드할 수 있습니다.
웹 클라이언트에서 TriggerAction 집합을 다시 로드하는 대신 CLI 클라이언트를 사용하여 이를 수행해 보겠습니다.
`template deploy` 하위 명령의 도움말 화면을 간단히 살펴보겠습니다.```
root@kali:~# P4wnP1_cli template deploy -h
Deploy given gadget settings
Usage:
P4wnP1_cli template deploy [flags]
Flags:
-b, --bluetooth string Deploy Bluetooth template
-f, --full string Deploy full settings template
-h, --help help for deploy
-n, --network string Deploy network settings template
-t, --trigger-actions string Deploy trigger action template
-u, --usb string Deploy USB settings template
-w, --wifi string Deploy WiFi settings templates
Global Flags:
--host string The host with the listening P4wnP1 RPC server (default "localhost")
--port string The port on which the P4wnP1 RPC server is listening (default "50051")
사용 화면은 TriggerAction Templates가 -t 플래그로 배포될 수 있음을 보여줍니다. 다음 명령을 실행합니다,
저장된 TriggerAction 집합을 복원하기 위해:```
P4wnP1_cli template deploy -t tutorial1
USB 호스트 연결 시 HIDScript를 실행하는 TriggerAction이 다시 로드되어 웹클라이언트의 TriggerActions 탭에 표시되어야 합니다. P4wnP1 A.L.O.A.가 USB 호스트에 연결되면 스크립트가 다시 실행됩니다.
템플릿의 저장, 로드 및 배포는 P4wnP1의 자동화 워크플로우를 구성하는 두 가지 주요 개념 중 하나이며, 다른 하나는 이미 알려진 TriggerActions입니다. TriggerAction 세트 자체를 템플릿으로 저장하고 로드할 수 있을 뿐만 아니라, 적절한 경우 TriggerActions를 사용하여 이미 저장된 템플릿을 배포할 수도 있다는 점을 언급할 가치가 있습니다.
작업을 다시 살펴보면, 정의된 모든 요구 사항이 이제 충족된 것으로 보입니다.
- Windows USB 호스트의 편집기에 "Hello world"를 입력했습니다.
- 편집기는 사용자가 수동으로 열지 않고 P4wnP1이 엽니다.
- 키보드 LED가 한 번 토글되면 편집기가 자동으로 닫힙니다.
- P4wnP1이 USB 호스트에 연결될 때마다 이 동작이 반복됩니다.
- HIDScript는 P4wnP1이 USB 호스트에 다시 연결되지 않는 한 한 번만 실행되며, 연속적인 키보드 LED 변경이 발생해도 마찬가지입니다.
- P4wnP1이 재부팅되면 저장된 TriggerAction 세트(저장된 HIDScript를 다시 참조함)를 로드하여 동일한 동작을 복구할 수 있습니다. 이는 단일 CLI 명령어 또는 웹클라이언트의 트리거 액션 탭에서 간단한 "load&add"나 "load&replace"로 수행할 수 있습니다.
이제 추가 목표를 더해 보겠습니다.
- USB 구성에 키보드 기능이 활성화되어 있는지 확인해야 합니다. (현재 설정은 이 작업을 수행하지 않으며, USB 키보드가 비활성화된 경우 TriggerAction이 HIDScript를 시작할 수 없습니다.)
- 생성된 설정은 P4wnP1 A.L.O.A.의 부팅 시 자동으로 적용되어야 하며, TriggerAction 세트를 수동으로 로드할 필요가 없습니다. 설정은 P4wnP1의 재부팅 후에도 유지되어야 합니다.
두 가지 추가 목표를 달성하려면 새로운 주제로 들어가야 합니다...
#### 마스터 템플릿 및 시작 마스터 템플릿 소개
마스터 템플릿을 살펴보기 전에, 지금까지 모든 것이 의도한 대로 작동했기 때문에 아직 하지 않은 작업을 수행합니다. 작업에 맞는 유효한 USB 구성을 정의합니다!
- 장치 일련 번호: 123456789
- 장치 제품 이름: Auto Writer
- 장치 제조업체: The Creator
- 제품 ID: 0x9876
- 공급업체 ID: 0x1D6B
- 활성화된 USB 기능
- HID 키보드
- HID 마우스
먼저 이러한 설정을 배포하는 데 사용할 수 있는 CLI 명령어의 사용 화면을 살펴보겠습니다.```
root@kali:~# P4wnP1_cli usb set -h
set USB Gadget settings
Usage:
P4wnP1_cli usb set [flags]
Flags:
-e, --cdc-ecm Use the CDC ECM gadget function
-n, --disable If this flag is set, the gadget stays inactive after deployment (not bound to UDC)
-h, --help help for set
-k, --hid-keyboard Use the HID KEYBOARD gadget function
-m, --hid-mouse Use the HID MOUSE gadget function
-g, --hid-raw Use the HID RAW gadget function
-f, --manufacturer string Manufacturer string (default "MaMe82")
-p, --pid string Product ID (format '0x1347') (default "0x1347")
-o, --product string Product name string (default "P4wnP1 by MaMe82")
-r, --rndis Use the RNDIS gadget function
-s, --serial Use the SERIAL gadget function
-x, --sn string Serial number (alpha numeric) (default "deadbeef1337")
-u, --ums Use the USB Mass Storage gadget function
--ums-cdrom If this flag is set, UMS emulates a CD-Rom instead of a flashdrive (ignored, if UMS disabled)
--ums-file string Path to the image or block device backing UMS (ignored, if UMS disabled)
-v, --vid string Vendor ID (format '0x1d6b') (default "0x1d6b")
Global Flags:
--host string The host with the listening P4wnP1 RPC server (default "localhost")
--json Output results as JSON if applicable
--port string The port on which the P4wnP1 RPC server is listening (default "50051")
명령에는 많은 플래그가 있지만 변경 가능한 USB 설정도 많이 있습니다. 정의된 USB 설정을 배포하는 것은 CLI를 사용하여 다음과 같이 수행할 수 있습니다:``` root@kali:~# P4wnP1_cli usb set \
--sn 123456789
--product "Auto Writer"
--manufacturer "The Creator"
--pid "0x9876"
--vid "0x1d6b"
--hid-keyboard
--hid-mouse Successfully deployed USB gadget settings Enabled: true Product: Auto Writer Manufacturer: The Creator Serialnumber: 123456789 PID: 0x9876 VID: 0x1d6b
Functions: RNDIS: false CDC ECM: false Serial: false HID Mouse: true HID Keyboard: true HID Generic: false Mass Storage: false
(길어 보이는) 명령의 결과 출력은 최종 USB 설정을 보여줍니다. 웹클라이언트의 "USB 설정" 탭을 확인하여 설정이 적용되었는지 확인해 봅시다. 아무 문제가 없다면 모든 변경 사항이 반영되어야 합니다.
CLI를 사용하여 USB 설정을 배포하는 것이 완전히 가능하지만, CLI보다 웹클라이언트를 사용하는 데에는 몇 가지 이점이 있습니다. 이 경우:
- 웹클라이언트에서 설정을 변경하는 것이 더 쉽고 편리합니다.
- 웹클라이언트는 내부 설정 상태를 유지하므로, 실제로 배포하지 않고도 USB 설정을 정의할 수 있습니다 (반면 CLI는 설정을 배포해야만 조작할 수 있습니다. 이는 다시 P4wnP1의 전체 USB 스택과 모든 종속 기능을 재설정합니다. 예를 들어 이미 실행 중인 HIDScript가 중단되거나 USB 네트워크 인터페이스가 재배포됩니다).
- 웹클라이언트의 현재 설정을 미리 배포하지 않고 영구 템플릿에 저장할 수 있습니다.
- CLI 클라이언트는 (현재) USB 설정을 저장할 수 없습니다.
현재 우리의 경우, USB 설정에 필요한 변경을 위해 웹클라이언트를 사용하는 것이 분명히 더 나은 선택입니다. CLI 접근 방식(여기서 이미 사용한)의 좋은 점은 다음과 같습니다: CLI가 USB 설정을 배포하도록 강제했기 때문에, 영구 템플릿에 저장하기 전에 설정이 작동하는지 확인할 수 있었습니다.
이제 USB 설정 저장을 계속해 보겠습니다:
다시 "저장" 버튼을 누르고, 이번에는 "USB 설정" 탭에서 누릅니다. 템플릿 이름을 다시 `tutorial1`이라고 지정합니다 (같은 이름으로 저장된 TriggerAction 템플릿과 충돌하지 않습니다. USB 설정에는 다른 네임스페이스가 사용되기 때문입니다).
이제 두 개의 새로운 영구 저장 템플릿이 생겼습니다::
1) `tutorial1`이라는 이름의 TriggerAction 세트 템플릿
2) `tutorial1`이라는 이름의 USB 설정 템플릿
(현재 USB 설정, TriggerActions 또는 둘 다의) 상태가 어떤 식으로든 변경되었다고 가정하면, 다음 CLI 명령을 실행하여 저장된 두 설정을 한 번에 다시 로드할 수 있습니다:```
P4wnP1_cli template deploy --usb tutorial1 --trigger-actions tutorial1
P4wnP1 template deploy 명령은 P4wnP1 A.L.O.A.의 각 하위 시스템에 대한 템플릿을 한 번에 로드할 수 있습니다 (네트워크 하위 시스템의 경우 여러 템플릿(각 어댑터당 하나)을 로드할 수 있습니다). 여러 하위 시스템에 대한 템플릿을 배포하는 것은 P4wnP1 A.L.O.A. 작업 시 일반적인 작업으로 간주됩니다. 대부분의 경우 단일 목표를 달성하기 위해 여러 하위 시스템을 재구성해야 하기 때문입니다. 이를 위해 소위 마스터 템플릿이 도입되었습니다.
마스터 템플릿은 다음으로 구성될 수 있습니다:
마스터 템플릿은 웹클라이언트의 "일반 설정" 탭에 있는 "마스터 템플릿 편집기"를 사용하여 정의, 저장 또는 로드할 수 있습니다. 웹클라이언트를 사용하는 것은 마스터 템플릿을 정의하는 편리한 방법입니다. 각 하위 시스템에 대해 이미 저장된 템플릿만 선택할 수 있도록 지원하기 때문입니다(그리고 현재 웹클라이언트가 마스터 템플릿을 정의하는 유일한 방법입니다).
그럼 현재 작업을 위한 마스터 템플릿을 정의해 보겠습니다:
tutorial1 템플릿을 선택하고 "확인" 버튼으로 확인합니다.tutorial1을 선택합니다(USB 하위 시스템의 다른 템플릿이지만 TriggerActions용 템플릿과 이름은 동일합니다).tutorial1을 입력하여 새 마스터 템플릿을 저장합니다.템플릿이 저장되었는지 확인하려면 "저장된 항목 로드" 버튼을 사용할 수 있습니다. 템플릿이 선택 항목에 표시되어야 합니다. "저장된 항목 로드" 대화상자를 다시 취소합니다.
이제 "저장된 항목 배포" 버튼을 누르고 startup이라는 템플릿을 선택한 다음 "확인"으로 확인합니다.
"저장된 항목 로드" 기능(저장된 템플릿을 마스터 템플릿 편집기에 로드)과 달리 "저장된 항목 배포" 기능은 마스터 템플릿의 모든 설정을 P4wnP1의 해당 하위 시스템에 즉시 적용합니다(마스터 템플릿 편집기에 로드하지 않음).
startup 마스터 템플릿이 현재 WiFi 설정을 덮어쓰기 때문에 웹클라이언트 연결이 끊어져 P4wnP1 WiFi 네트워크에 다시 연결해야 할 수 있습니다.
다시 연결에 성공하고 현재 USB 설정과 현재 TriggerActions를 검사하면 이전에 저장한 설정이 startup 마스터 템플릿의 하위 설정에 의해 덮어쓰여진 것을 확인할 수 있습니다.
tutorial1 마스터 템플릿을 다시 배포하는 방법은 두 가지입니다:
startup 마스터 템플릿으로 수행한 것처럼)P4wnP1_cli template deploy --full tutorial1 명령을 사용하여 배포(--full 플래그는 마스터 템플릿의 별칭임)마스터 템플릿 tutorial1을 배포할 수 있게 됨으로써 우리는 새로운 목표 중 하나를 이미 달성했습니다:
키 입력 주입 설정을 로드할 때 USB 구성에 키보드 기능이 활성화되어 있음이 보장됩니다.
작동 방식에 대한 빠른 요약:
tutorial1은 tutorial1이라는 USB 설정을 로드하며, 여기에는
tutorial1은 단일 TriggerAction이 포함된 TriggerAction 집합을 로드합니다
tutorial1.js를 시작합니다
waitLED 트리거가 발생하면(키보드 드라이버 준비) 입력을 시작하고, 연속적인 LED 변경 후 종료됩니다남은 유일한 목표는 다음과 같습니다: 생성된 설정이 P4wnP1 A.L.O.A. 부팅 시 자동으로 적용되어야 하며, TriggerAction 집합을 수동으로 로드할 필요가 없어야 합니다. 설정은 P4wnP1 재부팅 후에도 유지되어야 합니다.
이 목표는 이제 매우 쉽게 달성할 수 있습니다. 웹클라이언트의 "일반 설정" 탭에는 시작 마스터 템플릿이라는 카드가 있습니다. 이 시점에서 시작 마스터 템플릿을 tutorial1로 변경하면 즉시 효과가 있으며, P4wnP1 A.L.O.A.의 작동 중인 부트 구성을 파괴할 가능성이 높습니다.
중요: 마스터 템플릿에 하위 템플릿이 비어 있는 경우(예: Bluetooth 템플릿이 선택되지 않은 경우), 마스터 템플릿이 로드될 때 해당 하위 시스템은 재구성되지 않습니다. 이는 런타임 재구성 시 필요하지 않은 USB 스택 또는 WiFi 스택과 같은 이미 실행 중인 하위 시스템을 재설정하지 않아도 되므로 편리하지만, 시작 마스터 템플릿으로 사용되는 마스터 템플릿은 정의되지 않은 템플릿이 있는 하위 시스템을 정의되지 않은 상태로 둡니다. 예를 들어 유효한 WiFi 템플릿이 제공되지 않으면 재부팅 후 P4wnP1 A.L.O.A.가 WiFi를 통해 연결 가능할 가능성이 낮습니다.
따라서 새 tutorial1 마스터 템플릿을 시작 마스터 템플릿으로 배포하기 전에 다른 하위 시스템에 대해 적절한 설정이 로드되었는지 확인합니다. 다음과 같이 수행합니다:
tutorial1 템플릿을 편집기에 다시 로드합니다.tutorial1이 설정되어 있어야 합니다.startup이라는 템플릿을 선택합니다.startup이라는 템플릿을 선택합니다.bteth_startupusbeth_startupwlan0_startup_dhcp_servertutorial1 마스터 템플릿을 덮어씁니다("저장" 버튼을 누르고 tutorial1을 입력한 후 "확인"으로 확인).tutorial1을 선택합니다. 로드된 마스터 템플릿의 모든 하위 섹션이 여기에 설명된 대로 표시되어야 합니다.이제 새 마스터 템플릿을 시작 마스터 템플릿으로 배포할 준비가 되었습니다. 그런 다음 "재부팅" 버튼을 누릅니다.
재부팅되면 P4wnP1 A.L.O.A.가 HIDScript를 자동으로 트리거해야 하며(재구성을 위해 WiFi를 통해 여전히 연결 가능해야 함).
축하합니다, 모든 목표를 달성했습니다.
P4wnP1 A.L.O.A.의 기본 워크플로 개념을 배웠습니다.
현재로서는 전체 문서를 제공할 수 없습니다. 따라서 아직 다루지 않았지만 살펴볼 가치가 있는 주제에 대한 몇 가지 설명이 있습니다.
P4wnP1은 TriggerActions에서 BashScript를 실행할 수 있습니다. TriggerActions에서 사용할 수 있는 스크립트는 /usr/local/P4wnP1/scripts에 있습니다. 스크립트가 TriggerAction에서 호출되면 bash 변수를 통해 여러 인수(예: 실제 트리거)가 전달됩니다. /usr/local/P4wnP1/scripts/trigger-aware.sh 파일은 호출 트리거에 따라 다르게 동작하는 bash 스크립트의 좋은 예입니다. 현재 사용 가능한 모든 "TriggerAction 변수"를 사용하므로 이 스크립트를 살펴볼 가치가 있습니다.
이전 P4wnP1 버전의 커뮤니티에서는 때때로 Raspberry Pi의 하드웨어 모드나 확장을 제안하고, 이를 통합하는 방법에 대해 질문했습니다. 이 문제에 대해 일반적인 솔루션을 제공하는 것은 불가능합니다. 또한 소수만 사용하는 매우 특정한 하드웨어 확장에 대한 지원을 제공하는 것도 좋은 생각이 아닙니다. TriggerAction의 도입으로 GPIO 입력을 통한 트리거와 GPIO 출력을 발행하는 동작 모두를 지원하는 아이디어가 나왔습니다. 첫 번째 릴리스에서는 계획되지 않았지만 이 기능은 이미 구현되었습니다. 아직 문서화할 시간이 없었으며 일부 사항이 변경될 수 있습니다. 이 기능은 "periph.io" 라이브러리를 약간 확장하여 사용합니다(맞춤형 디바운스가 있는 맞춤형 에지 감지를 위한 GPIO, 이에 대한 @marcaruel의 교환에 감사드립니다).
P4wnP1 A.L.O.A.에 포함된 WiFi 펌웨어는 KARMA를 지원하도록 수정되었습니다(nexmon 프레임워크 활용). 이 기능은 아직 코어에 포함되지 않았으며(펌웨어 측면에서 일부 재작업 필요) 따라서 웹클라이언트나 CLI에서 사용할 수 없습니다. KARMA 기능을 사용해보고 싶다면 레거시 Python CLI가 있으며, 이를 통해 즉시 KARMA 옵션을 설정할 수 있습니다. Python 스크립트는 다음에서 찾을 수 있습니다:
/usr/local/P4wnP1/legacy/karmatool.py
팁: KARMA 기능을 최대한 활용하려면 P4wnP1 A.L.O.A.를 인증 없이 WiFi 액세스 포인트를 제공하도록 설정해야 합니다. 그렇지 않으면 큰 의미가 없습니다. 열악한 비콘 플러딩의 경우 필요하지 않지만, 비콘 전송을 위한 (정적) 사용자 지정 SSID는 개수가 제한됩니다(WiFi 칩의 리소스 절약).
RePo: https://github.com/mame82/P4wnP1_nexmon_additions Creds to: seemoo-lab for "NEXMON" project
A hostapd based Access Point should be up and running, when using this tool (see the README for details).
Usage: python karmatool.py [Arguments]
Arguments: -h Print this help screen -i Interactive mode -d Load default configuration (KARMA on, KARMA beaconing off, beaconing for 13 common SSIDs on, custom SSIDs never expire) -c Print current KARMA firmware configuration -p 0/1 Disable/Enable KARMA probe responses -a 0/1 Disable/Enable KARMA association responses -k 0/1 Disable/Enable KARMA association responses and probe responses (overrides -p and -a) -b 0/1 Disable/Enable KARMA beaconing (broadcasts up to 20 SSIDs spotted in probe requests as beacon) -s 0/1 Disable/Enable custom SSID beaconing (broadcasts up to 20 SSIDs which have been added by the user with '--addssid=' when enabled) --addssid="test" Add SSID "test" to custom SSID list (max 20 SSIDs) --remssid="test" Remove SSID "test" from custom SSID list --clearssids Clear list of custom SSIDs --clearkarma Clear list of karma SSIDs (only influences beaconing, not probes) --autoremkarma=600 Auto remove KARMA SSIDs from beaconing list after sending 600 beacons without receiving an association (about 60 seconds, 0 = beacon forever) --autoremcustom=3000 Auto remove custom SSIDs from beaconing list after sending 3000 beacons without receiving an association (about 5 minutes, 0 = beacon forever)
Example: python karmatool.py -k 1 -b 0 Enables KARMA (probe and association responses) But sends no beacons for SSIDs from received probes python karmatool.py -k 1 -b 0 Enables KARMA (probe and association responses) and sends beacons for SSIDs from received probes (max 20 SSIDs, if autoremove isn't enabled)
python karmatool.py --addssid="test 1" --addssid="test 2" -s 1 Add SSID "test 1" and "test 2" and enable beaconing for custom SSIDs
### WiFi 은밀 채널
WiFi 은밀 채널은 아직 Go로 포팅되지 않았으며 P4wnP1 코어에 포함되지 않았습니다. 어쨌든, 레거시 기능은 제공됩니다. 은밀 채널을 실행하려면 여러 조건이 충족되어야 합니다:
- 타겟 클라이언트에 키스트로크 인젝션을 적용하여 stage1을 주입해야 함
- stage1은 HID 은밀 채널의 (단순화된 버전)을 통해 stage2를 로드하므로, P4wnP1에 특수 USB HID 장치를 제공하고 stage2를 제공하기 위해 특수 HID 은밀 채널 서버를 시작해야 함
- 수정된 WiFi 펌웨어와 인터페이스하는 두 번째 서버를 시작하여 WiFi 은밀 채널을 통해 연결하는 클라이언트를 관리하고 해당 클라이언트에 대화형 셸 액세스를 제공해야 함 (서버는 `screen`과 같은 터미널 멀티플렉서에서 실행되도록 설계된 콘솔 애플리케이션)
앞서 언급된 모든 조건은 필요한 구성 요소(HID 스테이저, WiFi 은밀 채널 서버, 전달할 클라이언트 에이전트)가 제공된다면 P4wnP1 A.L.O.A.의 기능 세트를 사용하여 충족될 수 있습니다.
P4wnP1 A.L.O.A.로 그러한 작업을 수행하는 것은 그 기능을 보여주는 훌륭한 예입니다. 또한 P4wnP1 A.L.O.A.가 무엇으로 의도되었고 무엇으로 의도되지 않았는지를 구분하는 데 도움이 됩니다.
P4wnP1 A.L.O.A.는 다음과 같은 용도가 아닙니다:
- "무기화된" 도구
- 무슨 일이 일어나고 있는지 또는 어떤 위험이 관련되어 있는지 이해하지 않고 누구나 수행할 수 있는 RTR 페이로드 제공
P4wnP1 A.L.O.A.는 다음과 같은 용도입니다:
- 유연하고 저렴한 주머니 크기 플랫폼
- 여기에 설명된 것과 같은 작업을 위한 인에이블러 역할
- 최종 정적 솔루션을 제공하지 않고 펜테스트 또는 레드팀 작업 중 일반적으로 사용되는 모든 종류의 USB 관련 작업의 프로토타이핑, 테스트 및 수행 지원
어떤 의미에서, `/usr/local/P4wnP1/legacy` 폴더에는 WiFi 은밀 채널을 실행하는 데 필요한 외부 도구(즉, WiFi 서버, HID 은밀 채널 스테이저 서버 및 WiFi 은밀 채널 클라이언트 에이전트)가 있습니다. 이러한 구성 요소는 외부 부품(P4wnP1 A.L.O.A. 코어에 속하지 않음)으로 간주될 수 있습니다.
또한 P4wnP1 A.L.O.A.는 주어진 구성 요소를 활용하여 다음 작업을 수행하는 구성을 제공합니다:
- Windows 호스트에 대한 드라이브바이 공격을 통해 HID 은밀 채널을 통해 stage2를 다운로드하기 위한 메모리 내 클라이언트 코드 전달(키스트로크 인젝션(HIDScript) 기반)
- P4wnP1이 USB 호스트에 연결되는 즉시 키스트로크 인젝션 시작(TriggerAction이 HIDScript 실행)
- 키스트로크 인젝션이 시작되는 즉시 HID 은밀 채널을 통해 WiFi 은밀 채널 클라이언트 에이전트를 전달하는 스테이저 시작(TriggerAction이 bash 스크립트를 실행하고, 다시 외부 서버 시작)
- 필요할 때 WiFi 은밀 채널 서버 시작(동일한 TriggerAction 및 BashScript)
- USB 키보드(키스트로크 인젝션 허용)와 추가 원시 HID 장치(stage2 전달을 위한 은밀 채널 역할)를 제공하는 USB 설정 배포 - USB 설정은 설정 템플릿에 저장됨
- WiFi 은밀 채널 서버의 CLI 프론트엔드와 상호작용할 수 있도록 P4wnP1에 원격 액세스를 허용하는 WiFi 설정 배포 - WiFi 설정은 설정 템플릿에 저장됨
- 필요한 모든 구성을 한 번에 배포할 수 있는 단일 진입점 제공(적절한 WiFi 설정, 적절한 USB 설정 및 HIDScript를 시작하는 데 필요한 TriggerActions로 구성된 마스터 템플릿에 의해 수행됨)
마스터 템플릿은 "wifi covert channel"이라고 합니다. 웹클라이언트의 "generic settings" 탭에서 배포하면("마스터 템플릿 편집기"에서 "DEPLOY STORED") P4wnP1 A.L.O.A.는 설명된 모든 단계를 실행할 준비가 됩니다.
USB 호스트에 다시 연결되는 즉시 stage1을 입력하기 시작하고 해당 서버가 내부적으로 시작됩니다.
SSH 세션(예: WiFi를 통해)에서 `screen -d -r wifi_c2`를 사용하여 WiFi 은밀 채널 서버에 액세스하여 WiFi 은밀 채널을 통해 다시 연결된 클라이언트와 상호작용할 수 있습니다.
키스트로크 인젝션은 USB 호스트의 언어 레이아웃에 따라 달라지므로, 해당 HIDScript `wifi_covert_channel.js`에는 사용 중인 키보드 레이아웃을 조정하는 데 사용할 수 있는 `language` 변수가 있습니다. 또한 `hide`(기본값 false)라는 변수가 있습니다. `hide`가 true로 설정되면 stage1이 입력되는 동안 클라이언트의 콘솔 창이 숨겨집니다. 이는 다시 HIDScript와 백엔드 JavaScript 엔진 덕분에 복잡한 작업을 단순한 부울 변수로 축소할 수 있는 방법을 보여줍니다.
P4wnP1의 마스터 템플릿과 함께 제공되는 "wifi covert channel" 데모는 시작 마스터 템플릿으로도 사용할 수 있습니다. WiFi 액세스가 여전히 가능하므로 언제든지 원격으로 구성을 다시 변경할 수 있기 때문입니다.
TriggerAction에서 호출되는 관련 BashScript는 CLI 클라이언트가 얼마나 유연해질 수 있는지 보여주는 좋은 예입니다. HID 스테이저는 수신할 장치 파일(일반 HID 장치를 나타내는 파일)을 알아야 하지만 이 정보는 런타임에만 사용 가능하므로(활성화된 USB 가젯 기능에 따라 다름), 스크립트는 `hidraw=$(P4wnP1_cli usb get device raw)`를 실행하여 CLI가 올바른 HID 장치를 보고하도록 요청합니다.
전체 BashScript는 `/usr/local/P4wnP1/scripts` 폴더에 있으며, 이 폴더는 TriggerActions에서 액세스할 수 있는 모든 bash 스크립트의 위치입니다.
### 블루투스 NAP
P4wnP1은 블루투스 네트워크 캡슐화 프로토콜(BNEP)을 통해 블루투스 기반 네트워크 기능을 제공합니다. 현재 가장 흥미로운 기능은 블루투스 네트워크 액세스 포인트(NAP)로, 예를 들어 모바일에서 P4wnP1에 대한 IP 기반 블루투스 원격 액세스를 허용합니다.
이 기능을 사용하려면 몇 가지 사항을 알아야 합니다:
- `bteth`라는 블루투스 네트워크 인터페이스는 다른 네트워크 인터페이스(웹클라이언트 또는 CLI)처럼 구성하고 템플릿화할 수 있습니다.
- Android 모바일(iPhone은 테스트되지 않음)에서 NAP 액세스를 허용하려면 모바일이 연결될 뿐만 아니라 P4wnP1이 DHCP를 통해 `bteth` 인터페이스의 기본 게이트웨이에 적절한 IP를 제공해야 합니다. 이는 모바일이 NAP를 인터넷 게이트웨이로 사용하려고 하기 때문입니다(의도된 사용). NAP 자체가 게이트웨이를 제공하지 않으면 Android 모바일은 DHCP D.O.R.A. 이후 추가 요청을 수행하지 않습니다. 이를 해결하는 가장 쉬운 방법은 DHCP 서버가 `bteth` 인터페이스 자체의 IP를 기본 게이트웨이(DHCP 옵션 3)로 제공하도록 지시하는 것입니다. 실제 업스트림 연결이 없더라도 내 테스트에서는 작동했습니다. 모바일이 "전화 집"을 위해 게이트웨이와 계층 3 통신을 해야 하기 때문입니다. 연속적인 연결 테스트가 실패하더라도 작동하는 계층 3 연결은 유지됩니다. 예를 들어 블루투스를 통한 SSH 액세스가 가능합니다. "High Speed"가 활성화되면 웹클라이언트도 꽤 잘 작동합니다.
- PIN 기반 페어링을 허용하려면 단순 보안 페어링(SSP)을 비활성화해야 합니다. SSP가 활성화되면 실행 중인 페어링 에이전트가 모든 패스키를 확인합니다(즉, 레거시 PIN 페어링보다 보안이 약화되어 모든 장치가 연결할 수 있음). 향후 CLI/웹클라이언트에 SSP 기반 패스키 페어링을 위한 확인 대화 상자가 구현될 수 있지만 현재는 범위를 벗어납니다. SSP를 사용하는 경우, 의도한 장치가 페어링된 후에는 "discoverable" 및 "bondable"을 비활성화하는 것이 좋습니다.
- SSP를 비활성화한 경우 또 다른 단점은 블루투스 연결에 "High Speed"를 사용할 수 없다는 것입니다(또는 High Speed를 활성화하려면 SSP로 페어링해야 함). "High Speed"가 활성화되지 않으면(통신에 802.11 프레임 사용) 웹클라이언트를 요청하는 데 약 10분이 걸리며, High Speed가 활성화되면 몇 초가 걸립니다. 그러나 SSH 및 CLI 클라이언트를 "High Speed" 없이 NAP를 통해 사용하는 것은 괜찮습니다.
- 기본 블루투스 네트워크 인터페이스 설정(`bteth_startup`)과 기본 블루투스 설정(`startup`)은 레거시 PIN 페어링을 통한 SSH "Low Speed" 액세스를 허용해야 합니다. PIN은 `1337`이며 웹클라이언트에서 변경할 수 있습니다.
### TriggerAction 그룹
TriggerActions에는 "Groups"라는 멋진 라우팅 기능이 있습니다. 시간 내에 기능 데모를 준비하지 못했지만, LED 기반 4비트 이진 카운터(GPIO, 토글 스위치 및 4개의 LED 사용) 예제를 포함할 계획입니다.
그룹의 개념은 다음과 같습니다:
정확히 동일한 트리거(예: "USB 호스트에 연결됨")에서 실행되는 4개의 TriggerAction(TA)을 원한다고 가정해 보겠습니다. 각각 "USB 호스트에 연결됨" 트리거를 사용하여 4개의 TA를 생성하면 됩니다.
또는 "USB 호스트에 연결됨"이 발생할 때 `"connected"`라는 그룹에 값 `1`을 보내는 TriggerAction을 만들 수 있습니다. 이제 다른 4개의 TriggerAction을 `"connected"`라는 그룹에서 값 `1`을 수신할 때 실행되도록 정의합니다. 결과는 동일하며 지금은 별 의미가 없습니다(사실 하나의 TriggerAction이 더 필요합니다). 지금의 유일한 긍정적인 효과는 그룹 이름 덕분에 TriggerActions가 약간 더 읽기 쉬워진다는 것입니다. 그룹 이름은 자유롭게 선택할 수 있습니다.
이제 첫 번째 고급 작업으로 다음 CLI 명령을 실행할 수 있습니다:```
P4wnP1_cli trigger send --group-name=connected --group-value=1
이 명령은 "USB 호스트에 연결됨" 호스트 TriggerAction과 다른 4개의 TA에 정확히 동일한 효과를 주며, 이들은 connected 그룹에 값 1이 도착하기를 기다리고 있다가 실행됩니다. 기억하실지 모르겠지만, CLI 클라이언트는 원격으로 (다양한 플랫폼에서) 실행될 수 있으므로, 원격으로 Trigger 명령을 내리는 데 사용될 수 있습니다.
"그룹 채널"에 반응하는 Trigger는 "그룹 채널의 값"이라고 합니다. 더 흥미로운 트리거는 "그룹 채널의 여러 값"이라고 합니다. 이 "여러 값" 트리거는 실행되기 전에 값의 순서가 있는 시퀀스, 또는 여러 값 중 하나, 또는 순서 없는 시퀀스의 모든 값을 수신 대기할 수 있습니다.
다음 조건이 충족될 때 BashScript를 실행하려고 한다고 가정해 보겠습니다:
다음과 같이 두 이벤트에 대한 TA를 만들 수 있습니다:
이제 다음과 같이 세 번째 TriggerAction을 배포할 수 있습니다:
이 구성에서는 두 "condition" Trigger가 모두 실행된 경우에만 bash 스크립트가 시작됩니다.
유형으로 "All (logical AND)" 대신 "정확한 순서 시퀀스"를 사용했다면, bash 스크립트는 WiFi AP가 USB 연결 Trigger보다 먼저 켜진 경우에만 시작됩니다 (반대의 경우는 아님). GPIO 트리거와 결합하면, 예를 들어 간단한 PIN 패드의 입력을 기반으로 작업을 트리거하는 데 사용할 수 있습니다.
"그룹" 채널에 대한 멋진 사용 아이디어가 있으실 거라 확신합니다.
언급할 가치가 있는 사항:
CLI 클라이언트는 다음과 같은 명령을 사용하여 "그룹 채널"에 특정 값이 도착할 때까지 차단 대기(blocking wait)를 수행할 수 있습니다:``` P4wnP1_cli trigger wait --group-name=waitgroup --group-value=1
이 기능은 CLI를 활용하여 (GPIO와 같은 모든 기능을 사용하여) TriggerActions에서 스크립트를 구동하는 데 사용할 수 있습니다.
진행 중인 작업, 누락된 섹션:
- HIDScript 트리거 변수 (TriggerActions에서 실행된 HIDScript에 전달되는 변수)
- HIDScript 헬퍼 (PowerShell 함수)
- HIDScript 데모 snake (마우스)
- USB 대용량 저장소 (genimg 헬퍼)
## 4. 복구: 구성을 망가뜨려 P4wnP1 A.L.O.A.에 접근할 수 없는 경우
P4wnP1 A.L.O.A.는 잘못된 구성으로 인해 사용할 수 없게 되는 것을 막아주지 않습니다 (루트 콘솔이 `rm -rf /`를 실행하는 것을 막지 않는 것과 같습니다).
모든 것을 망가뜨린 경우, 문제를 해결하는 몇 가지 방법은 다음과 같습니다:
### 데이터베이스 백업
아직 작동 중인 P4wnP1 구성에 중요한 변경을 가하기 전에 데이터베이스 백업을 생성하세요. 이는 웹클라이언트의 "일반 설정" 탭 또는 CLI에서 `P4wnP1_cli db backup` 명령으로 수행할 수 있습니다.
백업은 선택한 이름으로 `/usr/local/P4wnP1/db` 폴더에 저장됩니다.
"복원" 기능 또는 `P4wnP1_cli db restore` 명령을 사용하여 지정된 백업을 복원할 수 있습니다.
백업에는 모든 저장된 템플릿 (USB, WiFi, 네트워크, 블루투스, TriggerActions, 마스터 템플릿)과 설정된 시작 마스터 템플릿이 포함됩니다. 백업에는 HIDScript 또는 BashScript가 포함되지 않는데, 둘 다 파일로 저장되어 편집이 용이하기 때문입니다.
### 백업이 없고 모든 것을 망가뜨린 경우
P4wnP1 A.L.O.A.가 시작되면 데이터베이스가 존재하는지 확인합니다. 데이터베이스가 없으면 P4wnP1 A.L.O.A.와 함께 제공되는 초기 백업을 기반으로 새 데이터베이스를 채웁니다.
초기 백업은 `/usr/local/P4wnP1/db/init.db`에 저장되어 있으며 **삭제되거나 덮어써서는 안 됩니다**.
P4wnP1이 강제로 데이터베이스를 다시 생성하도록 하려면 실제 데이터베이스를 삭제해야 합니다. 이는 P4wnP1 A.L.O.A. SD 카드를 EXT 파티션을 쓸 수 있는 시스템에 마운트하여 수행할 수 있습니다.
완료되면 SD 카드의 루트 파티션에서 `/usr/local/P4wnP1/store` 폴더를 삭제하십시오. 이렇게 하면 데이터베이스가 삭제되어 P4wnP1이 다시 부팅될 때 강제로 재생성됩니다.
### 백업이 있지만 복원하기 위해 P4wnP1에 접근할 수 없는 경우
접근 권한이 없어 기존 데이터베이스를 복원할 수 없는 경우, "백업이 없고 모든 것을 망가뜨린 경우"의 단계를 따를 수 있습니다. `/usr/local/P4wnP1/store` 삭제에 더하여 `/usr/local/P4wnP1/db/init.db` 파일을 백업의 파일로 교체하십시오 (init.db의 백업 복사본이 있는지 확인하십시오).
그러면 P4wnP1이 재부팅될 때 사용자 정의 DB가 다시 생성됩니다.
### 백업의 시작 마스터 템플릿을 망가뜨린 경우
시작 마스터 템플릿이 작동하지 않는 백업이 있는 경우 추가 단계를 수행해야 합니다. 백업에서 시작 템플릿을 직접 변경할 수 없기 때문입니다.
먼저 "백업이 없고 모든 것을 망가뜨린 경우"의 단계를 따라 초기 P4wnP1 데이터베이스를 다시 생성하십시오.
P4wnP1이 재부팅된 후 다시 P4wnP1의 웹클라이언트에 원격으로 접근할 수 있어야 합니다.
"일반 설정"으로 이동하여 자신의 백업 (시작 마스터 템플릿이 잘못된 백업)을 복원하십시오.
"시작 마스터 템플릿"에 선택된 마스터 템플릿이 "깨진" 것으로 표시되어야 합니다. 그렇지 않은 경우 웹클라이언트 애플리케이션을 호스팅하는 브라우저 탭을 다시 로드하십시오.
다시 "일반 설정" 탭으로 이동하여 작동이 확인된 시작 마스터 템플릿을 선택하십시오.
이 시점에서 재부팅할 준비가 되어 있어야 합니다.
### 위의 어떤 방법도 도움이 되지 않은 경우
죄송합니다. 깨끗한 이미지에서 P4wnP1 A.L.O.A. SD 카드를 다시 생성해야 할 것 같습니다.
## 5. 크레딧
공사 중, 무작위 순서
- @JohanBrandhorst (gopherjs를 통한 gRPC-web에 대한 긴밀한 논의, "서버 스트리밍을 위한 웹소켓"의 매우 빠른 구현, 기능 요청)
- @steevdave, @_binkybear (Kali 빌드 스크립트, 논의 및 지속적인 교류)
- @Re4sonKernel (P4wnP1 커널 변경 사항을 잘 관리되고 인기 있는 리포지토리로 이전하는 지원, Bluez 수정에 대한 협업)
- @SymbianSyMoh (재부팅 없이 HID 공격 재트리거에 대한 영감)
- @quasarframework (서드파티 라이브러리 목록에 포함될 수 있지만, 여기서 이루어진 작업은 엄청납니다; P4wnP1 웹클라이언트의 외관과 느낌은 이 아름다운 라이브러리의 기본 구성 요소를 기반으로 합니다)
- @CyberArms (가장 초기의 P4wnP1 지지자 중 한 명, 이 주제에 대한 최고의 튜토리얼과 심지어 책을 저술한 사람)
- @LucaBongiorni (가장 초기의 지지자일 뿐만 아니라, 그가 하드웨어에서 하는 일은 내가 소프트웨어에서만 할 수 있는 일입니다; 그는 USB 주제에 대해 강연하고 오픈 소스 솔루션을 존중하며, 전반적으로 훌륭한 사람이자 영감을 주는 사람입니다)
- @evilsocket (그의 블록이 저를 Go로 이끌었습니다, 훌륭한 OSS 개발자, 그의 코드를 읽어보면 제가 무슨 뜻인지 아실 겁니다)
- @RoganDawes and @Singe from @SensePost (영감을 주는 사람들)
- @Swiftb0y (초기 지지자, "구" P4wnP1 위키 작성자, P4wnP1 A.L.O.A.에 대한 아이디어의 초기 테스터)
- @marcaruel (periph.io를 사용한 GPIO 에지 감지에 대한 논의)
## 6. 할 일 및 지원
이것은 완전한 할 일 목록은 아니지만, 몇 가지 이정표가 남아 있으며 커뮤니티 지원을 받을 수 있다면 기쁠 것입니다.
- 전체 HID 은닉 채널 기능을 Go 코어로 포팅 (이것은 제가 직접 해야 합니다)
- **CLI용 블루투스 구성 명령 추가**
- 추가 키보드 레이아웃 생성 (현재 br, de, es, fr, gb, it, ru 및 us 지원)
- 블루투스 기능 확장하여 다른 검색 가능한 장치에 연결 허용 (인증 및 신뢰)
- WiFi KARMA 기능을 전용 Python 도구에서 P4wnP1 코어로 이동 (웹클라이언트 지원 포함)
- HIDScript에 대한 전체 문서 생성 (기본적으로 마우스 부분만 누락됨)
- P4wnP1에 대한 전체 문서 생성 (커뮤니티에 기대)
- Docker netlink에 대한 남은 종속성 제거 (netlink 폴더의 README 참조)
블루투스 참고 사항:
P4wnP1은 Bluez API에 대한 사용자 정의 바인딩과 함께 작동합니다. Bluez API가 저전력 블루투스 (GATT, 주변 장치 에뮬레이션 등)를 지원하지만, 이 기능을 P4wnP1 A.L.O.A.에 통합할 계획은 없습니다.
Nexmon 참고 사항:
P4wnP1은 nexmon을 활용합니다. 대부분의 사람들은 nexmon을 브로드컴 WiFi 칩 (Raspberry Pi Zero W에서 사용되는 BCM43430a1 포함)에 대해 모니터 모드와 패킷 주입을 가능하게 하는 펌웨어 수정으로 알고 있습니다. 그러나 nexmon은 그 이상입니다. 이것은 약간의 리버싱 후 ARM 펌웨어 블롭을 수정할 수 있는 프레임워크로, 고수준 C 코드로 작성된 패치를 적용할 수 있습니다. P4wnP1은 이 프레임워크를 사용하여 WiFi 펌웨어에 사용자 정의 패치를 적용하여 하드웨어 기반 KARMA 지원과 WiFi 은닉 채널을 위한 펌웨어 (및 드라이버) 지원을 활성화합니다. 이 수정의 목적은 내장 WiFi 인터페이스에 대한 적절한 모니터 모드나 주입 지원을 제공하는 것이 아닙니다. 현재 WiFi 펌웨어에 레거시 nexmon 모니터 모드 기능이 포함되어 있지만, 이는 P4wnP1에서 사용하는 표준 WiFi 기능을 방해하므로 "오류"로 간주됩니다 (인터페이스가 스테이션 모드로 사용될 때 충돌 등).
## 7. 저작권
P4wnP1 A.L.O.A.
Copyright (C) 2018 Marcus Mengs
이 프로그램은 자유 소프트웨어입니다: 귀하는 자유 소프트웨어 재단이 공표한 GNU 일반 공중 사용 허가서의 조건에 따라 이 프로그램을 재배포 및/또는 수정할 수 있습니다. 버전 3 또는 (귀하의 선택에 따라) 이후 버전을 선택할 수 있습니다.
이 프로그램은 유용하게 사용되기를 바라며 배포되지만, 어떤 종류의 보증도 제공하지 않습니다. 상품성 또는 특정 목적에의 적합성에 대한 묵시적 보증조차도 제공하지 않습니다. 자세한 내용은 GNU 일반 공중 사용 허가서를 참조하십시오.
귀하는 이 프로그램과 함께 GNU 일반 공중 사용 허가서 사본을 받았을 것입니다. 그렇지 않은 경우, <http://www.gnu.org/licenses/>에서 확인하십시오.