Skip to content

Commit cbaed1a

Browse files
committed
gui: new menu for choosing scripts
- nicer menu for picking asset scripts - file picker for custom scripts - update readme
1 parent 0608b62 commit cbaed1a

21 files changed

+530
-188
lines changed

README.md

Lines changed: 51 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,64 @@
1-
# Android HID Script
1+
# Android USB Script
22

33
**Use at your own risk. For educational purposes only.**
44

5-
An Android app that provides a simple Lua interface for emulating an HID device, on top of the existing `android-keyboard-gadget` patch by `pelya`. **Root access is required.**
5+
An Android app that provides a simple Lua interface for enumerating and interfacing
6+
with arbitrary composite USB devices.
67

7-
## Requirements
8-
**This app will not work on every Android device.** If your Android OS has Linux Kernel version >= 3.18 and is compiled with configfs and f_hid, then the app can try to create usb gadgets for mouse and keyboard.
8+
**Root access is required.**
99

10-
If your Android OS is compiled with the [android-keyboard-gadget kernel patch](https://github.com/pelya/android-keyboard-gadget), then the app can use the usb gadgets it provides.
10+
The best way to explain what this app does is with a code example. The following script
11+
does the following when interpreted by this app:
1112

12-
## HID Emulation?
13-
```
14-
In computing, the USB human interface device class (USB HID class) is a part of the USB
15-
specification for computer peripherals: it specifies a device class (a type of computer
16-
hardware) for human interface devices such as keyboards, mice, game controllers and
17-
alphanumeric display devices.
18-
- Wikipedia
19-
```
20-
This app provides an easy way to script HID interactions intuitively, with feedback. In addition, it contains wrappers around the HID devices allowing developers to easily integrate HID functionality into their own apps.
13+
1. Configures your phone to become a USB keyboard
14+
2. Sends a series of key presses to the computer your phone is plugged in to, changing
15+
its wallpaper
16+
17+
```lua
18+
-- create a USB composite device composed of a single keyboard
19+
usb = luausb.create({ id = 0, type = "keyboard" })
20+
kb = usb.dev[1]
21+
22+
local file = "https://i.redd.it/ur1mqcbpxou51.png"
2123

22-
On the news recently, use and abuse of the trust given to HID devices was demonstrated with the [BadUSB](https://www.wired.com/2014/07/usb-security/) attack, where USB devices were abused to utilize HID protocol to carry out nefarious actions.
24+
while true do
25+
-- wait for the phone to be plugged into a computer
26+
while not kb.test() do usb.delay(1000) end
2327

24-
## Use Cases of Scripted HID Emulation
25-
- Automation of deployment solutions (ie. configuring computer BIOs settings in an automated fashion)
26-
- Mobile password managers that type in your credentials for you, on computers you do not trust
27-
- Use in computer espionage or social engineering attacks
28+
usb.delay(1000)
2829

29-
## Features
30-
A couple of demo applications are implemented:
31-
- Fuzzing of HID protocol
32-
- PowerShell download and run executable
33-
- PowerShell download and run PowerShell script
34-
- Serial transfer of data through output reports
35-
- Change wallpaper ([video demonstration](https://my.mixtape.moe/zxerjz.mp4))
30+
kb.press_keys(kb.LSUPER, kb.R) -- open the Windows run dialog
31+
usb.delay(2000) -- wait 2 seconds
32+
kb.send_string("powershell\n") -- pop open a powershell window
33+
usb.delay(2000)
3634

37-
New demo applications can be added to `assets/scripts`. The API is pretty much self-documenting, just look at the existing demos to get a feel for how the API works.
35+
-- enter a script that changes your wallpaper
36+
kb.send_string("[Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12;" ..
37+
"(new-object System.Net.WebClient).DownloadFile('" .. file .. "',\"$Env:Temp\\b.jpg\");\n" ..
38+
"Add-Type @\"\n" ..
39+
"using System;using System.Runtime.InteropServices;using Microsoft.Win32;namespa" ..
40+
"ce W{public class S{ [DllImport(\"user32.dll\")]static extern int SystemParamet" ..
41+
"ersInfo(int a,int b,string c,int d);public static void SW(string a){SystemParam" ..
42+
"etersInfo(20,0,a,3);RegistryKey c=Registry.CurrentUser.OpenSubKey(\"Control Pan" ..
43+
"el\\\\Desktop\",true);c.SetValue(@\"WallpaperStyle\", \"2\");c.SetValue(@\"Tile" ..
44+
"Wallpaper\", \"0\");c.Close();}}}\n" ..
45+
"\"@\n" ..
46+
"[W.S]::SW(\"$Env:Temp\\b.jpg\")\n" ..
47+
"exit\n")
48+
49+
-- wait for the phone to be unplugged
50+
while kb.test() do usb.delay(1000) end
51+
end
52+
```
53+
54+
## Requirements
55+
**This app will not work on every Android device.** If your Android OS has Linux Kernel
56+
version >= 3.18 and is compiled with configfs and f_hid, then the app can try to create usb
57+
gadgets.
3858

39-
For people who want to implement HID functionality in their own apps, HID interfacing code available [here (HID.java)](https://github.com/Netdex/android-hid-script/blob/master/app/src/main/java/cf/netdex/hidfuzzer/hid/HID.java),
40-
and a simple ease-of-use wrapper is available [here (HIDR.java)](https://github.com/Netdex/android-hid-script/blob/master/app/src/main/java/cf/netdex/hidfuzzer/hid/HIDR.java). The documentation should be enough to understand how it works.
59+
New demo applications can be added to `assets/scripts`. The API is pretty much self-documenting,
60+
just look at the existing demos to get a feel for how the API works.
4161

4262
## Third-party
43-
- Requires ChainFire's [libsuperuser](https://github.com/Chainfire/libsuperuser) to keep a su shell open.
44-
- Requires LuaJ to provide Lua binding and interpret Lua scripts.
63+
- [libsuperuser](https://github.com/Chainfire/libsuperuser)
64+
- [LuaJ](http://www.luaj.org/luaj/3.0/README.html)

app/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ dependencies {
2929

3030
implementation 'eu.chainfire:libsuperuser:1.1.0.+'
3131
implementation 'org.luaj:luaj-jse:3.0.1'
32+
implementation 'androidx.appcompat:appcompat:1.1.0'
3233
}
3334
repositories {
3435
mavenCentral()

app/src/main/AndroidManifest.xml

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,14 @@
22
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
33
package="org.netdex.hidfuzzer">
44

5-
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
5+
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
66

77
<application
88
android:allowBackup="true"
99
android:icon="@mipmap/ic_fuzzer"
1010
android:label="@string/app_name"
1111
android:supportsRtl="true"
1212
android:theme="@style/AppTheme">
13-
<service
14-
android:name=".service.LuaUsbService"
15-
android:enabled="true"
16-
android:exported="true" />
1713

1814
<activity android:name=".MainActivity">
1915
<intent-filter>
@@ -22,6 +18,17 @@
2218
<category android:name="android.intent.category.LAUNCHER" />
2319
</intent-filter>
2420
</activity>
21+
22+
<activity
23+
android:name=".SelectAssetActivity"
24+
android:label="@string/title_activity_select_asset"
25+
android:parentActivityName=".MainActivity" />
26+
27+
<service
28+
android:name=".service.LuaUsbService"
29+
android:enabled="true"
30+
android:exported="true" />
31+
2532
</application>
2633

2734
</manifest>

app/src/main/assets/scripts/a.lua

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,29 @@
55
--- template.lua: generic template for "run after plug-in" style scripts
66
---
77

8-
usb = luausb.create({ id = 0, type = "keyboard" })
9-
kb = usb.dev[1]
8+
usb = luausb.create({ type = "keyboard", id = 0 }, { type = "keyboard", id = 1 })
9+
kb1 = usb.dev[1]
10+
kb2 = usb.dev[2]
1011

1112
while true do
12-
usb.log("idle")
13-
14-
-- poll until writable
15-
while not kb.test() do
16-
usb.delay(1000)
17-
end
18-
19-
usb.log("running")
13+
--usb.log("idle")
14+
--
15+
---- poll until writable
16+
--while not kb1.test() do
17+
-- usb.delay(1000)
18+
--end
19+
--
20+
--usb.log("running")
21+
--usb.delay(1000)
22+
--
23+
--kb1.send_string("test")
24+
--usb.delay(1000)
25+
--kb2.send_string("test")
26+
--
27+
--usb.log("done")
28+
--while kb1.test() do
29+
-- usb.delay(1000)
30+
--end
31+
--usb.log("disconnected")
2032
usb.delay(1000)
21-
22-
kb.send_string("test")
23-
24-
usb.log("done")
25-
while kb.test() do
26-
usb.delay(1000)
27-
end
28-
usb.log("disconnected")
2933
end

app/src/main/assets/scripts/wallpaper.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ while true do
1616

1717
-- poll until /dev/hidg0 is writable
1818
while not kb.test() do
19-
delay(1000)
19+
usb.delay(1000)
2020
end
2121

2222
usb.log("running")
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package org.netdex.hidfuzzer;
2+
3+
import android.view.LayoutInflater;
4+
import android.view.View;
5+
import android.view.ViewGroup;
6+
import android.widget.TextView;
7+
8+
import androidx.annotation.NonNull;
9+
import androidx.recyclerview.widget.RecyclerView;
10+
11+
import java.util.ArrayList;
12+
13+
public class LuaAssetAdapter extends RecyclerView.Adapter<LuaAssetAdapter.ViewHolder> {
14+
public static class LuaAsset {
15+
private final String name_;
16+
private final String path_;
17+
18+
public LuaAsset(String name, String path) {
19+
this.name_ = name;
20+
this.path_ = path;
21+
}
22+
23+
public String getName() {
24+
return name_;
25+
}
26+
27+
public String getPath() {
28+
return path_;
29+
}
30+
}
31+
32+
public static class ViewHolder extends RecyclerView.ViewHolder {
33+
public TextView textView;
34+
public View layout;
35+
36+
public ViewHolder(View view) {
37+
super(view);
38+
this.layout = view;
39+
textView = view.findViewById(R.id.textView);
40+
}
41+
}
42+
43+
private final ArrayList<LuaAsset> assets_;
44+
45+
public LuaAssetAdapter(ArrayList<LuaAsset> assets) {
46+
this.assets_ = assets;
47+
}
48+
49+
@NonNull
50+
@Override
51+
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
52+
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
53+
View view = inflater.inflate(R.layout.activity_select_asset_row, parent, false);
54+
return new ViewHolder(view);
55+
}
56+
57+
@Override
58+
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
59+
LuaAsset asset = assets_.get(position);
60+
holder.textView.setText(asset.getName());
61+
holder.layout.setOnClickListener(v -> onLuaAssetSelected(asset));
62+
}
63+
64+
@Override
65+
public int getItemCount() {
66+
return assets_.size();
67+
}
68+
69+
public void onLuaAssetSelected(LuaAsset asset) {
70+
}
71+
}

0 commit comments

Comments
 (0)