From c5570bdca514398d53bea14fda56ec640102862c Mon Sep 17 00:00:00 2001 From: Harvey Phillips Date: Sun, 12 Nov 2017 20:03:48 +0000 Subject: [PATCH] Add post-setup script support to `options.txt` and documentation --- ADDED.md | 21 +++++++++++++++++++++ README.md | 6 +++--- TODO.md | 4 +++- doc/FAQ.md | 4 ++++ doc/OPTIONS.md | 3 +++ src/main.go | 6 +++++- src/parser.go | 28 +++++++++++++++++++++++++--- 7 files changed, 64 insertions(+), 8 deletions(-) diff --git a/ADDED.md b/ADDED.md index bf5381b..0ebb71b 100644 --- a/ADDED.md +++ b/ADDED.md @@ -2,3 +2,24 @@ ## Newly Added Features As things get crossed off the [TODO](TODO.md) list, they will be written about here. + +### Post-Setup Scripts + +You can now specify a script or executable than will be ran after the gadgets are setup and running. +This done by adding a new line to `options.txt`. + +``` +. +. +. +post: /path/to/file +``` + +You can either pass it an absolute path as above, or a relative path from within `/boot/usbninja/`. + +Note that you need to have the executable bit set on whatever you point to, else it will fail! +You can do this with a simple `chmod` as below: + +``` +$ sudo chmod +x /boot/usbninja/exec.sh +``` diff --git a/README.md b/README.md index 5c44651..b35ae94 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ -# USB Ninja - Testing Repository - Post Gadget Setup Script Execution +# USB Ninja The USB Ninja is an advanced USB attack development platform designed to be as simple as possible whilst leaving as many options open for development. Written in Golang, it was developed on a Raspberry Pi Zero W, but should work on any device that supports USB OTG - see the list of [Supported Devices](doc/SUPPORTED.md). It makes heavy use of [configfs](https://www.kernel.org/doc/Documentation/filesystems/configfs/configfs.txt) to configure and present the drivers to the host system. See the [FAQ](doc/FAQ.md) for more information. -**WARNING: THIS IS THE TESTING BRANCH. THINGS IN THIS BRANCH ARE UNLIKELY TO WORK!** +**Post-Setup Scripts can now be set! See [ADDED.md](ADDED.md) or [OPTIONS.md](src/OPTIONS.md) for more information!** Currently supported gadgets are: * [USB-To-Serial](doc/SERIAL.md) @@ -41,6 +41,6 @@ By default, the USB Ninja will start up in `serial` mode with a baud rate of `11 The other option is to just download and setup [Arch Linux ARM](https://archlinuxarm.org/platforms/armv6/raspberry-pi) by yourself and follow the instructions in [INSTALL.md](INSTALL.md) to compile the binaries from source and setup all the other services. The process is exactly the same as what was done to prepare the image. ## Using other gadgets -If you want to use gadgets other than plain old `serial` (and if you're hear - you probably do), then all you need to do is edit `usbninja/options.txt` on the first partition of the MicroSD card. This corresponds to the `/boot` directory when the OS boots up. +If you want to use gadgets other than plain old `serial` (and if you're here - you probably do), then all you need to do is edit `usbninja/options.txt` on the first partition of the MicroSD card. This corresponds to the `/boot` directory when the OS boots up. See [OPTIONS.md](doc/OPTIONS.md) and [GADGETS.md](doc/GADGETS.md) for more information. diff --git a/TODO.md b/TODO.md index d3a9b94..c77b374 100644 --- a/TODO.md +++ b/TODO.md @@ -5,9 +5,11 @@ * hid_remote gadget * Add "one-stop-shop" mode that deletes options.txt after execution * Multiple keyboard layouts -* Post gadget-setup script execution +* ~~Post gadget-setup script execution~~ +* Add some API functions for post-setup scripts to use ## Code Changes +* **Find a better way to distribute releases other than an 8GB image!** * Replace C style if IsTrue() == 0 statements with bools * Replace config array with map for clarity - removes need for GetOption() * Speed up boot time of Raspberry Pi diff --git a/doc/FAQ.md b/doc/FAQ.md index c68a6d4..b11f235 100644 --- a/doc/FAQ.md +++ b/doc/FAQ.md @@ -24,3 +24,7 @@ As detailed on the [ethernet](ETHERNET.md) page, the `ethernet` gadget is just a **6. I'm trying to use multiple gadgets at once, but it isn't working!** Multiple gadget support is currently still in testing. As far as I have seen - it seems to work just fine, but if you've found a combination that doesn't work as expected (and you have reason to think it should), then please raise an issue on this repo. + +**7. My `post` script isn't running even though the path is right in `options.txt`!** + +If you're sure the path is right (note that you can specify either an absolute path or a path relative to `/boot/usbninja/`), then you might need to set the executable bit on the file. If your script is `/boot/usbninja/exec.sh`, then you can set the executable bit with the following command: `sudo chmod +x /boot/usbninja/exec.sh` diff --git a/doc/OPTIONS.md b/doc/OPTIONS.md index f7a5364..7970e53 100644 --- a/doc/OPTIONS.md +++ b/doc/OPTIONS.md @@ -18,12 +18,15 @@ productname: Composite USB Device |Option|Description|Format|Default Value| |-|-|-|-| |`gadget`|The USB gadget(s) to be used|`gadget1, gadget2, etc`|`serial`| +|`post`|An executable or script to be run after all the gadgets are setup|`file` or `/path/to/file`|none| |`vendorid`|The VID presented to the Host OS|`0x????` (two hex bytes)|`0x1d6b`| |`productid`|The PID prestented to the Host OS|`0x????` (two hex bytes)|`0x0104`| |`serialnumber`|The Serial Number of the emulated device|`????????????????` (16 hex characters)|`fedcba9876543210`| |`manufacturer`|The Manufacturer string reported to the Host OS|Up to 32 characters long|`Generic Corp`| |`productname`|The Product Name string reported to the Host OS|Up to 32 characters long|`USB Device`| +**Note: The `post` script can be either an absolute path or a path relative to `/boot/usbninja/`.** + ### Settings available to certain gadgets |Option|Gadget|Description|Format|Default Value| |-|-|-|-|-| diff --git a/src/main.go b/src/main.go index c8e1259..bbf83e4 100644 --- a/src/main.go +++ b/src/main.go @@ -15,7 +15,7 @@ func main() { // Check which gagdet is set and branch accordingly gadgets := GetGadgets() - fmt.Printf("LOG: Options set as:\n=> delay: %s\n=> vendorid: %s\n=> productid: %s\n=> serialnumber: %s\n=>manufacturer: %s\n=>productname: %s\n\n", GetOption(config, "delay"), GetOption(config, "vendorid"), GetOption(config, "productid"), GetOption(config, "serialnumber"), GetOption(config, "manufacturer"), GetOption(config, "productname")) + fmt.Printf("LOG: Options set as:\n=>delay: %s\n=> vendorid: %s\n=> productid: %s\n=> serialnumber: %s\n=>manufacturer: %s\n=>productname: %s\n=>post: %s\n\n", GetOption(config, "delay"), GetOption(config, "vendorid"), GetOption(config, "productid"), GetOption(config, "serialnumber"), GetOption(config, "manufacturer"), GetOption(config, "productname"), GetOption(config, "post")) fmt.Printf("LOG: Gadgets set as: %v\n", gadgets) // SetupGenericGadget @@ -62,4 +62,8 @@ func main() { HIDPostSetup(config) } } + + // We now run the post-setup script. + // If none was set, then this is just "echo" + ShellOut(GetOption(config, "post")) } diff --git a/src/parser.go b/src/parser.go index 709c550..1a99c13 100644 --- a/src/parser.go +++ b/src/parser.go @@ -45,7 +45,7 @@ func GetGadgets() []string { func GetConfig() []string { // Parse out options from options.txt and return as an array - var delay, vendorid, productid, serialnumber, manufacturer, productname, eth_hostaddr, eth_devaddr string + var delay, vendorid, productid, serialnumber, manufacturer, productname, eth_hostaddr, eth_devaddr, post string // Check for options.txt locations file_location := GetOptionLocation() @@ -166,8 +166,22 @@ func GetConfig() []string { slice := key_val[1:] eth_devaddr = strings.TrimSpace(strings.Join(slice, ":")) } + + } else if key_val[0] == "post" { + // Check if the file exists, and set post to empty otherwise + + val := strings.TrimSpace(key_val[1]) + val2 := fmt.Sprintf("/boot/usbninja/%s", val) + + if FileExist(val) { + post = val + } else if FileExist(val2) { + post = val2 + } else { + post = "" + } + } } - } if delay == "" { delay = SetDefaults("delay") @@ -193,8 +207,11 @@ func GetConfig() []string { if eth_devaddr == "" { eth_devaddr = SetDefaults("eth_devaddr") } + if post == "" { + post = SetDefaults("post") + } - return []string{delay, vendorid, productid, serialnumber, manufacturer, productname, eth_hostaddr, eth_devaddr} + return []string{delay, vendorid, productid, serialnumber, manufacturer, productname, eth_hostaddr, eth_devaddr, post} } func SetDefaults(options string) string { @@ -222,6 +239,9 @@ func SetDefaults(options string) string { if options == "eth_devaddr" || options == "all" { return "42:61:64:55:53:42" } + if options == "post" || options == "all" { + return "echo" + } return "error" } @@ -380,6 +400,8 @@ func GetOption(config []string, option string) string { return string(config[6]) case "eth_devaddr": return string(config[7]) + case "post": + return string(config[8]) } return "error" }