
अपने Pi Zero 2W को BadUSB बनाने के लिए कॉन्फ़िगर करें।
Raspberry Pi Zero 2 W पर निर्मित एक प्रोग्रामेबल BadUSB / HID आक्रमण प्लेटफ़ॉर्म। यह Pi एक USB कम्पोज़िट डिवाइस (कीबोर्ड प्लस एक वैकल्पिक रीड-ओनली मास-स्टोरेज वॉल्यूम) के रूप में एन्यूमरेट होता है और Ducky-Script-शैली के पेलोड उस होस्ट पर निष्पादित करता है जिससे यह जुड़ा होता है। यह अधिकृत रेड-टीम अभियानों, पेनेट्रेशन परीक्षणों और CTF के लिए डिज़ाइन किया गया है।
⚠️ कानूनी सूचना। केवल उन्हीं सिस्टम पर उपयोग करें जिनके आप स्वामी हैं या जिनके परीक्षण की स्पष्ट लिखित अनुमति आपके पास है। अधिकांश क्षेत्राधिकारों में अनधिकृत पहुँच अवैध है, और यह दिखावा करना कि आपको पता नहीं था, काम नहीं आएगा।
configured अवस्था के माध्यम से — बूट पर कोई फ़र्ज़ी पेलोड फायर नहीं होता।LAYOUT के साथ प्रति-पेलोड चयन योग्य।IF / ELSE, WHILE, HOLD / RELEASE, INJECT_MOD, RANDOM_* जनरेटर, STRING_BLOCK / STRINGLN_BLOCK, DEFINE।ExecStop के साथ जो गैजेट को सफाई से टियर-डाउन करता है। कोई बचा हुआ configfs स्टेट नहीं, रीस्टार्ट बिना रीबूट के काम करता है।/dev/hidg0 के लिए — कोई वर्ल्ड-राइटेबल डिवाइस नोड नहीं।+----------------+ USB cable +-------------+
| Raspberry Pi | ===================>>> | Host PC |
| Zero 2 W | (Pi emulates HID + | (target) |
| (this device) | optional drive) | |
+----------------+ +-------------+
|
| /home/pi/pi-badusb/
|
+-- badusb.service ----> monitor_and_run.py
|
| on `state == configured`:
v
run_payload.py
|
v
/dev/hidg0 (USB HID gadget)
badusb.service systemd यूनिट gadget_setup.sh चलाता है, जो configfs/libcomposite का उपयोग करके एक HID कीबोर्ड फ़ंक्शन और (वैकल्पिक रूप से) /var/badusb/storage.img पर एक फ्लैट इमेज फ़ाइल द्वारा समर्थित मास-स्टोरेज LUN के साथ एक USB गैजेट कम्पोज़ करता है।monitor_and_run.py चलाती है। यह /sys/class/udc/<udc>/state को पोल करती है और configured की प्रतीक्षा करती है — USB-विनिर्देश अवस्था जिसका अर्थ है कि एक होस्ट ने गैजेट को सफलतापूर्वक एन्यूमरेट कर लिया है। (हम /dev/hidg0 के अस्तित्व को संकेत के रूप में नहीं उपयोग करते: वह उसी क्षण सत्य होता है जब गैजेट बूट पर UDC से बाइंड होता है, चाहे कुछ भी प्लग्ड हो।)run_payload.py निष्पादित करता है, जो payload.txt को पार्स करता है और HID रिपोर्टें /dev/hidg0 पर लिखता है।| घटक | टिप्पणी |
|---|---|
| Raspberry Pi Zero 2 W | 2026-05 हार्डवेयर रिवीज़न पर परीक्षण किया गया। BCM2835 dwc_otg ड्राइवर वाला पुराना Pi Zero W भी सैद्धांतिक रूप से काम करता है, लेकिन यह README dwc2 वाले 2 W को मानता है। |
| micro-USB से USB-A केबल | या एक "USB स्टिक" फॉर्म-फैक्टर एडेप्टर जो Pi को सीधे होस्ट पोर्ट में प्लग करने देता है। |
| वैकल्पिक: अलग चार्जर | यदि आप Pi को गैर-होस्ट स्रोत से पावर देना चाहते हैं ताकि लिसनर किसी टारगेट में प्लग होने से पहले बूट हो सके (अन्यथा होस्ट पोर्ट पावर की आपूर्ति करता है)। |
Pi Zero 2 W में दो micro-USB पोर्ट हैं:
PWR IN — केवल पावर, dwc2 OTG ब्लॉक को USB डेटा लाइनें एक्सपोज़ नहीं करता।USB — OTG डेटा पोर्ट; यही वह जगह है जहाँ आप टारगेट में प्लग करते हैं।रिपो को Pi में क्लोन या कॉपी करें, फिर इंस्टॉलर चलाएँ:
git clone http://your-gitea/admin/Pi-Zero-2W-Bad-USB.git /home/pi/pi-badusb
cd /home/pi/pi-badusb
sudo ./install.sh
sudo reboot
रीबूट के बाद, सेवा को सक्षम और प्रारंभ करें:
sudo systemctl enable --now badusb.service
journalctl -u badusb -f
install.sh इडेम्पोटेंट है — जब भी आप प्रोजेक्ट फ़ाइलें बदलें, इसे दोबारा चलाएँ। यह:
/boot/firmware (Bookworm+) बनाम /boot (पुराना) का पता लगाता है।config.txt में [all] ब्लॉक के अंतर्गत dtoverlay=dwc2,dr_mode=otg सक्रिय है। Raspberry Pi Imager डिफ़ॉल्ट इस पंक्ति को [cm5] फ़िल्टर के अंदर रखते हैं जो Pi Zero 2 W पर लागू नहीं होता; इंस्टॉलर एक सेंटिनल-चिह्नित ओवरराइड जोड़ता है ताकि दोबारा चलाने पर यह डुप्लिकेट न हो।modules-load=dwc2 cmdline.txt में है।g_ether अभी भी cmdline.txt में मौजूद है (यह libcomposite से UDC चुरा लेता है और गैजेट मोड को तोड़ देता है)।/etc/systemd/system/badusb.service पर इंस्टॉल करता है।/etc/udev/rules.d/99-badusb-hidg.rules पर इंस्टॉल करता है ताकि द्वारा ग्रुप-राइटेबल हो।# Start / stop / restart
sudo systemctl start badusb
sudo systemctl stop badusb
sudo systemctl restart badusb # safe to do while plugged in
# Watch live
journalctl -u badusb -f
# Disable autostart on boot
sudo systemctl disable badusb
# Tune timings (creates an override drop-in)
sudo systemctl edit badusb
# (paste an [Service] block with Environment="BADUSB_REARM_COOLDOWN_S=8" etc)
sudo systemctl restart badusb
सेवा sys-kernel-config.mount और एक UDC की उपस्थिति पर निर्भर करती है, इसलिए गैजेट वास्तव में तैयार होने से पहले यह पेलोड फायर नहीं कर सकती।
पेलोड संपादित करने के लिए रीस्टार्ट की आवश्यकता नहीं होती — payload.txt हर प्लग-इन पर ताज़ा पढ़ा जाता है।
payload.txt इंस्टॉल निर्देशिका में रहता है। पूर्ण कमांड संदर्भ payload_commands.md में है।
REM Open Run dialog and type a greeting via Notepad
LAYOUT US
GUI r
DELAY 1500
STRING notepad
ENTER
DELAY 2500
STRINGLN Hello from the Pi Zero 2 W
VAR $USER="alice"
VAR $COUNT=0
WHILE $COUNT < 3
STRINGLN Hello $USER (iteration $COUNT)
VAR $COUNT = $COUNT + 1
END_WHILE
IF $USER == "alice"
STRINGLN matched
ELSE
STRINGLN missed
END_IF
VAR में गणितीय व्यंजक एक ast-वॉकर सुरक्षित मूल्यांकनकर्ता से गुजरते हैं — कोई नाम नहीं, कोई कॉल नहीं, कोई एट्रिब्यूट एक्सेस नहीं, केवल संख्यात्मक लिटरल और + - * / // % **।
HOLD SHIFT
STRINGLN this line is in capitals
RELEASE SHIFT
REM Hold Ctrl+Shift (0x01 + 0x02) and tap A
INJECT_MOD 0x03
STRING a
REM Release all modifiers
INJECT_MOD 0x00
RANDOM_LETTER 12 # 12 random mixed-case letters
RANDOM_NUMBER 6 # 6 random digits
RANDOM_SPECIAL 4 # 4 random ASCII symbols
LAYOUT UK # switch to UK ISO mappings for subsequent STRING/STRINGLN
STRING @ " # ~ £ \ | # types correctly on a UK-locale host
keymaps/ में एक और फ़ाइल डालें (us.py और uk.py के साथ) और LAYOUT <name> निर्देश इसे importlib के माध्यम से उठा लेगा।
gadget_setup.sh का शीर्ष)इन्हें प्रति-इनवोकेशन ओवरराइड किया जा सकता है, gadget_setup.sh को मैन्युअल रूप से चलाते समय पर्यावरण में सेट करके, या वैश्विक रूप से यूनिट के Environment= निर्देशों के माध्यम से।
monitor_and_run.py)इस प्रकार ओवरराइड करें:
sudo systemctl edit badusb
# In the editor:
# [Service]
# Environment="BADUSB_REARM_COOLDOWN_S=8"
# Environment="BADUSB_MIN_INTER_FIRE_S=20"
sudo systemctl restart badusb
state का उपयोग क्यों करता है, /dev/hidg0 का नहींपिछला कार्यान्वयन /dev/hidg0 के अस्तित्व + लिखने-योग्यता को "host attached" संकेत के रूप में परीक्षण करता था। वह डिवाइस नोड उसी क्षण बन जाता है जब गैजेट बूट पर UDC से बाइंड होता है — किसी होस्ट द्वारा वास्तव में एन्यूमरेट किए जाने से बहुत पहले। इसलिए पेलोड पावर-अप पर तुरंत फायर हो जाते थे, चाहे Pi कहीं भी प्लग्ड हो।
विश्वसनीय संकेत /sys/class/udc/<udc>/state है, जो USB-विनिर्देश डिवाइस अवस्था रिपोर्ट करता है। केवल configured का अर्थ है कि होस्ट ने SetConfiguration(1) जारी किया है — डिवाइस अब HID रिपोर्ट भेजने के योग्य है।
Pi Zero 2 W पर भौतिक डिस्कनेक्ट का पता लगाना सॉफ़्टवेयर से असंभव है: बोर्ड VBUS सेंस को SoC के dwc2 OTG ब्लॉक से नहीं जोड़ता। भौतिक अनप्लग के बाद:
/sys/class/udc/<udc>/state configured पर बना रहता है।current_speed high-speed पर बना रहता है।GOTGCTL रजिस्टर 0x000d0000 पर बना रहता है (BSesVld बिट सेट)।इसलिए ऐसे संकेत की प्रतीक्षा करने के बजाय जो कभी नहीं आएगा, लिसनर सक्रिय रूप से डिस्कनेक्ट का कारण बनता है: प्रत्येक पेलोड के बाद, यह गैजेट की UDC configfs फ़ाइल में "" लिखता है (जिसे कर्नेल अनबाइंड के रूप में व्याख्या करता है), BADUSB_REARM_COOLDOWN_S के लिए सोता है, फिर रीबाइंड करने के लिए UDC नाम वापस लिखता है। अगला होस्ट प्लग-इन एक स्वच्छ configured संक्रमण उत्पन्न करता है जिसे लिसनर पहचान सकता है।
यदि ऑपरेटर पेलोड के बाद Pi को प्लग्ड छोड़ देता है, तो रीबाइंड होस्ट को गैजेट को फिर से एन्यूमरेट करने का कारण बनता है। रनअवे फायर लूप को रोकने के लिए, दो सुरक्षा उपाय सक्रिय होते हैं:
BADUSB_MIN_INTER_FIRE_S — यदि पिछले फायर के इस विंडो के भीतर कोई configured संक्रमण होता है, तो उसे दबाएँ और फिर से अनबाइंड करें। गैजेट पृष्ठभूमि में चुपचाप चक्र करता रहता है।BADUSB_MAX_FIRES_PER_MINUTE — स्लाइडिंग-विंडो कठोर सीमा। सीमा से अधिक पर, लिसनर BADUSB_RATELIMIT_PAUSE_S के लिए रुकता है और एक चेतावनी लॉग करता है।rm -rf कभी उपयोग क्यों नहीं करतेconfigfs की कर्नेल-प्रबंधित एट्रिब्यूट फ़ाइलें (bcdUSB, idVendor, webusb/*, os_desc/*, …) को rm(2) द्वारा हटाया नहीं जा सकता — कर्नेल EPERM लौटाता है। वे केवल तब जारी होती हैं जब उनकी पैरेंट निर्देशिका rmdir की जाती है। gadget_setup.sh और teardown_gadget.sh दोनों configfs ट्री को विहित libcomposite क्रम में चलते हैं — केवल rmdir, एट्रिब्यूट फ़ाइलों पर कभी rm नहीं — और कर्नेल बाकी को स्वचालित रूप से साफ कर देता है।
os.write का उपयोग क्यों करते हैं, file.write का नहींopen(path, "w").write("") के माध्यम से एक खाली स्ट्रिंग लिखना शून्य बाइट्स के साथ write(2) को नहीं बुलाता — CPython का TextIOWrapper इसे हटा देता है। configfs अनबाइंड के लिए (जिसे कर्नेल न्यूलाइन-स्ट्रिप के बाद शून्य-लंबाई वाली राइट से व्याख्या करता है), हम सीधे os.write(fd, b"\n") का उपयोग करते हैं ताकि syscall हमेशा कम से कम एक बाइट के साथ जारी हो।
Ducky पार्सर के पास एक 34-परीक्षण pytest सुइट है जो MockHIDEngine (वास्तविक HID राइटर के लिए इन-मेमोरी ड्रॉप-इन) के विरुद्ध चलता है, इसलिए इसे किसी Pi और किसी USB हार्डवेयर की आवश्यकता नहीं होती।
cd /home/pi/pi-badusb
python3 -m pytest tests/
कवरेज में शामिल हैं:
safe_eval_math अंकगणित स्वीकार करता है, नाम / कॉल / एट्रिब्यूट एक्सेस / स्ट्रिंग कॉन्स्टेंट अस्वीकार करता है।evaluate_condition संख्यात्मक और केस-संवेदी स्ट्रिंग तुलनाओं के लिए।VAR =, +=, -=, *=, /= के साथ।IF / ELSE / END_IF सही शाखा लेता है।WHILE / END_WHILE पुनरावृत्ति गणनाएँ < और <= के लिए।cat /sys/class/udc/*/state — होस्ट एन्यूमरेट करने पर configured तक पहुँचना चाहिए। यदि यह not attached पर बना रहता है, होस्ट संवाद नहीं कर रहा: एक अलग केबल आज़माएँ (कुछ केवल-चार्ज होती हैं) या एक अलग होस्ट पोर्ट।lsmod | grep dwc2 — लोड होना चाहिए। यदि केवल dwc_otg है, तो dtoverlay=dwc2,dr_mode=otg लागू नहीं हो रहा; install.sh दोबारा चलाएँ और रीबूट करें।journalctl -u badusb -f — होस्ट एन्यूमरेशन के ~2s के भीतर Host attached. Running payload. दिखाना चाहिए।यह एक वास्तविक बग था जो अब ठीक कर दिया गया है। यदि ऐसा होता है, तो आप pre-os.write बिल्ड पर लौट गए हैं। सुनिश्चित करें कि monitor_and_run.py वर्तमान main ब्रांच से मेल खाता है (os.write(fd, payload) खोजें)।
Operation not permitted"फिक्स से पहले gadget_setup.sh configfs पर rm -rf का उपयोग करता था। वर्तमान संस्करण teardown_gadget() का उपयोग करता है — यदि आप वे त्रुटियाँ देखते हैं, तो आपके पास एक पुरानी कॉपी है। Main से पुनः डिप्लॉय करें।
/dev/hidg0 पर अनुमति अस्वीकृत"udev नियम को लागू होने के लिए हॉट-प्लग की आवश्यकता होती है, या sudo udevadm trigger और एक पुनः-लॉगिन ताकि pi उपयोगकर्ता plugdev समूह उठा सके।
g_ether चेतावनी"cmdline.txt से g_ether हटाएँ; यह libcomposite के बाइंड होने से पहले UDC पर दावा कर लेता है।
मास-स्टोरेज आकार BACKING_SIZE_MB द्वारा सेट होता है और केवल पहले रन पर प्रभावी होता है जब बैकिंग इमेज बनाई जाती है। आकार बदलने के लिए:
sudo systemctl stop badusb
sudo rm /var/badusb/storage.img
sudo BACKING_SIZE_MB=256 /home/pi/pi-badusb/gadget_setup.sh
sudo systemctl start badusb
इसी के लिए BADUSB_MIN_INTER_FIRE_S और BADUSB_MAX_FIRES_PER_MINUTE हैं। उन्हें systemctl edit badusb के माध्यम से अधिक सेट करें। डिफ़ॉल्ट के साथ, प्लग्ड छोड़ा गया Pi पहले मिनट के लिए हर ~15s में फिर से फायर करता है, फिर 60s के लिए रुकता है, फिर जारी रखता है।
.
├── README.md This file
├── LICENSE MIT
├── install.sh Idempotent installer (firmware config, systemd, udev, plugdev)
├── gadget_setup.sh Composes the USB gadget via configfs/libcomposite
├── teardown_gadget.sh Canonical configfs teardown (wired as ExecStop)
├── reload_gadget.sh Manual UDC unbind/rebind helper
├── autorun.sh Legacy manual-launch wrapper (systemd is preferred)
├── monitor_and_run.py Listener: waits for host attach, runs payload, forces re-arm
├── run_payload.py Ducky-Script-style interpreter
├── payload.txt Your payload — edit freely; re-read on each plug-in
├── payload_commands.md Full command reference
├── etc/
│ ├── badusb.service systemd unit
│ └── 99-badusb-hidg.rules udev rule for /dev/hidg0 ownership
├── keymaps/
│ ├── __init__.py Dynamic layout loader
│ ├── us.py US ANSI (default)
│ └── uk.py UK ISO
└── tests/
├── __init__.py
├── conftest.py pytest path setup
└── test_parser.py 34 parser tests against a MockHIDEngine
libcomposite दस्तावेज़ीकरण, dwc2 कर्नेल ड्राइवर।MIT — देखें LICENSE।
configured| आवश्यकता | क्यों |
|---|
| Raspberry Pi OS (Debian Bookworm या Trixie, 64-bit Lite अनुशंसित) | इंस्टॉल स्क्रिप्ट Bookworm+ पर /boot/firmware/... में लिखती है और पुरानी इमेजों पर /boot/... पर फॉल बैक करती है। |
| Python 3 | Pi OS के साथ आता है। |
mkfs.vfat | पहले रन पर मास-स्टोरेज बैकिंग इमेज को फ़ॉर्मेट करने के लिए। यदि आप मास स्टोरेज अक्षम करते हैं तो छोड़ दें। |
| सेटअप के लिए रूट एक्सेस | systemd, udev, और /boot/firmware/config.txt को छूता है। |
/dev/hidg0plugdevpi उपयोगकर्ता को plugdev में जोड़ता है।/var/badusb/ बनाता है।| चर | डिफ़ॉल्ट | अर्थ |
|---|
ENABLE_MASS_STORAGE | 1 | केवल-HID गैजेट के लिए 0। |
BACKING_FILE | /var/badusb/storage.img | होस्ट को एक्सपोज़ की गई फ्लैट इमेज। |
BACKING_SIZE_MB | 64 | यदि अनुपस्थित हो तो पहले रन पर बनाई जाती है। |
BACKING_LABEL | BADUSB | FAT वॉल्यूम लेबल। |
MASS_STORAGE_RO | 1 | डिफ़ॉल्ट रूप से रीड-ओनली। |
| एनवी वेरिएबल | डिफ़ॉल्ट | अर्थ |
|---|
BADUSB_POST_PAYLOAD_FLUSH_S | 0.5 | अनबाइंडिंग से पहले पेलोड के बाद सोएं ताकि HID राइट्स ड्रेन हो जाएँ। |
BADUSB_REARM_COOLDOWN_S | 5 | अनबाइंड और रीबाइंड के बीच गैजेट होस्ट के लिए कितनी देर अदृश्य रहता है। |
BADUSB_MIN_INTER_FIRE_S | 10 | दो पेलोड फायर के बीच न्यूनतम सेकंड; इससे कम पर, फायर दबा दिया जाता है और गैजेट फिर से अनबाइंड हो जाता है। |
BADUSB_MAX_FIRES_PER_MINUTE | 6 | कठोर सीमा; इससे अधिक पर, BADUSB_RATELIMIT_PAUSE_S के लिए रुकें। |
BADUSB_RATELIMIT_PAUSE_S | 60 | रेट-लिमिट ट्रिगर के बाद रुकने की अवधि। |
RANDOM_* लंबाई शुद्धता; RANDOM_<unknown> नो-ऑप + चेतावनी।INJECT_MOD मॉडिफ़ायर बाइट की बाद के कीस्ट्रोक्स में स्थिरता।HOLD SHIFT STRINGLN abc में प्रत्येक वर्ण को कैपिटल करता है।LAYOUT US बनाम LAYOUT UK @ और " के लिए अलग-अलग रिपोर्ट उत्पन्न करते हैं; अज्ञात लेआउट पिछले वाले पर फॉल बैक हो जाता है।STRING_BLOCK पंक्तियों को जोड़ता है; STRINGLN_BLOCK न्यूनतम-इंडेंट का सम्मान करता है।