commit
8cb5a36a68
|
@ -0,0 +1,46 @@
|
|||
import pygatt
|
||||
import base64
|
||||
|
||||
adapter = pygatt.GATTToolBackend()
|
||||
char_uuid = '0000fff2-0000-1000-8000-00805f9b34fb'
|
||||
|
||||
def init():
|
||||
adapter.start()
|
||||
return True
|
||||
|
||||
def connect():
|
||||
device_name = 'BlueBunny'
|
||||
|
||||
devices = adapter.scan(run_as_root=True)
|
||||
device = next((d for d in devices if d['name'] == device_name), None)
|
||||
|
||||
if device:
|
||||
device_address = device['address']
|
||||
bunny = adapter.connect(device_address)
|
||||
|
||||
return bunny
|
||||
else:
|
||||
return False
|
||||
|
||||
def send(bunny, data: str, d_type: str):
|
||||
if d_type == "cmd":
|
||||
flag = "<CMD>"
|
||||
else:
|
||||
flag = "<PAYLOAD>"
|
||||
data = flag + data + flag
|
||||
data = base64.b64encode(data.encode("utf-8")).decode("utf-8")
|
||||
|
||||
if not len(data) <= 15:
|
||||
data_pieces = []
|
||||
|
||||
for i in range(0, len(data), 15):
|
||||
data_pieces.append(data[i:i + 15])
|
||||
|
||||
for i, piece in enumerate(data_pieces):
|
||||
if i == (len(data_pieces) - 1):
|
||||
bunny.char_write(char_uuid, (piece + "\n").encode("utf-8"))
|
||||
else:
|
||||
bunny.char_write(char_uuid, piece.encode("utf-8"))
|
||||
|
||||
else:
|
||||
bunny.char_write(char_uuid, (data + "\n").encode("utf-8"))
|
|
@ -0,0 +1,61 @@
|
|||
from flask import Flask, request, render_template, jsonify
|
||||
import urllib.parse
|
||||
import threading
|
||||
import BunnyLE
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
bb = None
|
||||
connection = 0
|
||||
con_fail_count = 0
|
||||
|
||||
def connect_bunny():
|
||||
global bb
|
||||
global connection
|
||||
global con_fail_count
|
||||
|
||||
BunnyLE.init()
|
||||
current_try = BunnyLE.connect()
|
||||
|
||||
if not current_try == False:
|
||||
bb = current_try
|
||||
connection = 1
|
||||
else:
|
||||
con_fail_count += 1
|
||||
connection = 2
|
||||
|
||||
@app.route("/", methods=['GET', 'POST'])
|
||||
def index():
|
||||
if request.method == 'POST':
|
||||
global bb
|
||||
query = request.form.get('query')
|
||||
mode = request.form.get('mode')
|
||||
|
||||
BunnyLE.send(bb, query, mode)
|
||||
|
||||
return render_template("index.html")
|
||||
|
||||
@app.route("/connect", methods=['GET'])
|
||||
def connect():
|
||||
connect_thread = threading.Thread(target=connect_bunny)
|
||||
connect_thread.start()
|
||||
|
||||
return render_template("connecting.html")
|
||||
|
||||
@app.route("/con-check", methods=['GET'])
|
||||
def connectCheck():
|
||||
global con_fail_count
|
||||
|
||||
if connection == 0:
|
||||
return jsonify(connected=0)
|
||||
elif connection == 1:
|
||||
return jsonify(connected=1)
|
||||
elif connection == 2:
|
||||
if con_fail_count < 5:
|
||||
connect_bunny()
|
||||
return jsonify(connected=0)
|
||||
else:
|
||||
return jsonify(connected=2)
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(host="localhost", port=1472, debug=True)
|
Binary file not shown.
After Width: | Height: | Size: 3.7 KiB |
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
After Width: | Height: | Size: 44 KiB |
|
@ -0,0 +1,163 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="SHORTCUT ICON" type="image/x-icon" href="static/bb_icon.png"/>
|
||||
<link rel="icon" type="image/x-icon" href="static/bb_icon.png" />
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>BlueBunny</title>
|
||||
<meta name="description" content="Remote control your Bash Bunny MKII">
|
||||
<link href="static/bootstrap.min.css" rel="stylesheet">
|
||||
<style type="text/css">
|
||||
.btn-imp {
|
||||
--bs-btn-color: #EC1A24 !important;
|
||||
--bs-btn-border-color: #EC1A24 !important;
|
||||
--bs-btn-hover-border-color: #1a62ec !important;
|
||||
--bs-btn-hover-bg: #1a62ec !important;
|
||||
--bs-btn-hover-color: #ffffff !important;
|
||||
}
|
||||
|
||||
@keyframes spinner {
|
||||
0% {transform: rotate( 0deg ) scale( 1 );}
|
||||
100% {transform: rotate( 360deg ) scale( 1 );}
|
||||
};
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
let fail_counter = 0
|
||||
|
||||
function tryAgain() {
|
||||
document.getElementById("action").innerHTML = '<h3 class="text-center" style="color: #ced4da; margin-bottom: 10px;">Connecting your Bash Bunny...</h3><div class="text-center" style="margin-top: 100px;"><a class="btn btn-imp" title="Connect" href="/connect" id="connectBtn">Too many fails occured... Try again</a><br><br><p class="fw-bold">OR</p></div><ul style="margin-bottom: 100px;"><li>Make sure your bluetooth adapter is running properly</li><li>Restart your Bash Bunny via unplugging and plugging it back in</li><li>Restart the BlueBunny C2 server\'s operating system</li></ul><p>Please be patient - Making BLE connections can be buggy. It\'s likely a temporary problem that will be gone in a minute.</p>'
|
||||
}
|
||||
|
||||
function connectionCheck() {
|
||||
fetch("/con-check").then(function(response) {
|
||||
return response.json();
|
||||
}).then(function(data) {
|
||||
if (data.connected == 1) {
|
||||
window.location.replace("/");
|
||||
} else if (data.connected == 2) {
|
||||
tryAgain();
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
setInterval(connectionCheck, 5000);
|
||||
</script>
|
||||
</head>
|
||||
<body style="background-color: #202124; color: #adb5bd; height: 100%; overflow: hidden">
|
||||
<div style="filter: blur(2.5px); position: absolute; width: 100%; height: 100%;">
|
||||
<nav class="navbar navbar-expand navbar-light fixed-top shadow-sm" style="border-bottom: solid; border-color: #1a62ec; border-width: 2.5px; background: #202124;">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand">
|
||||
<img src="static/logo.png" style="height: 45px; padding-right: 15px; filter: brightness(0) saturate(100%) invert(23%) sepia(75%) saturate(3313%) hue-rotate(217deg) brightness(99%) contrast(86%);" class="d-inline-block">
|
||||
</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarToggler" aria-controls="navbarToggler" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarToggler">
|
||||
<ul class="nav ms-auto">
|
||||
<li class="nav-item">
|
||||
<button class="btn" title="Connect" disabled>Connect to Bash Bunny</button>
|
||||
</li>
|
||||
<li class="nav-item" style="margin: auto; margin-right: 15px; margin-left: 20px;">
|
||||
<a>©</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<nav class="navbar navbar-expand-lg navbar-light" style="visibility: hidden;">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="#">
|
||||
<img src="static/bb_icon.png" style="height: 45px; padding-right: 15px;" class="d-inline-block"><span style="vertical-align: middle;">BlueBunny</span>
|
||||
</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarToggler" aria-controls="navbarToggler" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse">
|
||||
<ul class="nav">
|
||||
<li class="nav-item">
|
||||
<a class="btn">Connect to Bash Bunny</a>
|
||||
</li>
|
||||
<li class="nav-item" style="margin: auto; margin-right: 15px; margin-left: 20px;">
|
||||
<a>©</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="nav ms-auto">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link">©</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<br>
|
||||
<br>
|
||||
<div class="container" style="display: flex; flex-flow: wrap; justify-content: start;">
|
||||
<div style="width: 20rem; margin-right: 50px; margin-bottom: 20px; min-height: 10rem;">
|
||||
<h4 style="color: #ced4da;">Payload One-Liner <p class="text-dark-emphasis" style="font-size: 15px;"><small>Run a single line of code</small></p></h4>
|
||||
<div class="input-group mb-3">
|
||||
<input type="text" class="form-control" placeholder="Q ALT F4" style="background-color: #202124; border-color: #1a62ec; color: #adb5bd;">
|
||||
<button class="btn">Run</button>
|
||||
</div>
|
||||
</div>
|
||||
<div style="width: 20rem; margin-right: 50px; margin-bottom: 20px; min-height: 10rem;">
|
||||
<h4 style="color: #ced4da;">Payload Script <p class="text-dark-emphasis" style="font-size: 15px;"><small>Upload and execute a payload file</small></p></h4>
|
||||
<div class="input-group mb-3">
|
||||
<input type="file" class="form-control" style="background-color: #202124; border-color: #1a62ec; color: #adb5bd;">
|
||||
</div>
|
||||
<button class="btn">Execute Payload</button>
|
||||
</div>
|
||||
<div style="width: 20rem; margin-right: 50px; margin-bottom: 20px; min-height: 10rem;">
|
||||
<h4 style="color: #ced4da;">Attack Mode <p class="text-dark-emphasis" style="font-size: 15px;"><small>Configure Ethernet, Storage, HID and Serial</small></p></h4>
|
||||
<div class="input-group">
|
||||
<select class="form-select" style="background-color: #202124; border-color: #1a62ec; color: #adb5bd;">
|
||||
<option selected>None</option>
|
||||
</select>
|
||||
<button class="btn">Update</button>
|
||||
</div>
|
||||
</div>
|
||||
<div style="width: 20rem; margin-right: 50px; margin-bottom: 20px; min-height: 10rem;">
|
||||
<h4 style="color: #ced4da;">LED <p class="text-dark-emphasis" style="font-size: 15px;"><small>Light up your Bush Bunny</small></p></h4>
|
||||
<div class="input-group">
|
||||
<select class="form-select" style="background-color: #202124; border-color: #1a62ec; color: #adb5bd;" name="query">
|
||||
<option selected>Green</option>
|
||||
</select>
|
||||
<button class="btn">Update</button>
|
||||
</div>
|
||||
</div>
|
||||
<div style="width: 20rem; margin-right: 50px; margin-bottom: 20px; min-height: 10rem;">
|
||||
<h4 style="color: #ced4da;">CPU <p class="text-dark-emphasis" style="font-size: 15px;"><small>Tune the CPU to your needs</small></p></h4>
|
||||
<div class="input-group">
|
||||
<select class="form-select" style="background-color: #202124; border-color: #1a62ec; color: #adb5bd;">
|
||||
<option selected>Quad Core Ondemand (Default)</option>
|
||||
</select>
|
||||
<button class="btn">Update</button>
|
||||
</div>
|
||||
</div>
|
||||
<div style="width: 20rem; margin-right: 50px; margin-bottom: 20px; min-height: 10rem;">
|
||||
<h4 style="color: #ced4da;">Power <p class="text-dark-emphasis" style="font-size: 15px;"><small>Take a break</small></p></h4>
|
||||
<div class="input-group">
|
||||
<select class="form-select" style="background-color: #202124; border-color: #EC1A24; color: #adb5bd;">
|
||||
<option selected>Shutdown</option>
|
||||
</select>
|
||||
<button class="btn btn-imp">Initialize</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="position: absolute; width: 100%; height: 100%;">
|
||||
<div style="display: flex; justify-content: center; align-items: center; margin-top: 25px;">
|
||||
<div class="rounded shadow" style="border: solid; border-color: #1a62ec; border-width: 1px; background: #202124; max-width: 600px; height: fit-content; margin-left: 15px; margin-right: 15px; display: flex; justify-content: center;">
|
||||
<div style="margin: 20px; width: 100%" id="action">
|
||||
<h3 class="text-center" style="color: #ced4da; margin-bottom: 10px;">Connecting your Bash Bunny...</h3>
|
||||
<div class="text-center" style="margin-top: 100px; margin-bottom: 100px;">
|
||||
<img src="static/bb_icon.png" style="height: 5rem; width: 5rem; animation-name: spinner; animation-duration: 1s; animation-delay: 1s; animation-iteration-count: infinite;">
|
||||
</div>
|
||||
<p>This can take some time. Make sure your Bash Bunny is nearby and the BlueBunny payload is running successfully (Green LED).</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,337 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="SHORTCUT ICON" type="image/x-icon" href="static/bb_icon.png"/>
|
||||
<link rel="icon" type="image/x-icon" href="static/bb_icon.png" />
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>BlueBunny</title>
|
||||
<meta name="description" content="Remote control your Bash Bunny MKII">
|
||||
<link href="static/bootstrap.min.css" rel="stylesheet">
|
||||
<style type="text/css">
|
||||
.btn-imp {
|
||||
--bs-btn-color: #EC1A24 !important;
|
||||
--bs-btn-border-color: #EC1A24 !important;
|
||||
--bs-btn-hover-border-color: #1a62ec !important;
|
||||
--bs-btn-hover-bg: #1a62ec !important;
|
||||
--bs-btn-hover-color: #ffffff !important;
|
||||
}
|
||||
|
||||
.btn {
|
||||
--bs-btn-color: #1a62ec;
|
||||
--bs-btn-border-color: #1a62ec;
|
||||
--bs-btn-hover-border-color: #1a62ec;
|
||||
--bs-btn-hover-bg: #1a62ec;
|
||||
--bs-btn-hover-color: #ffffff;
|
||||
}
|
||||
|
||||
code {
|
||||
color: #1a62ec;
|
||||
}
|
||||
|
||||
.form-control::placeholder {
|
||||
color: #adb5bd;
|
||||
opacity: 0.5;
|
||||
}
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
function disableControl() {
|
||||
forms = document.getElementsByClassName('form');
|
||||
|
||||
for (i = 0; i < forms.length; i++) {
|
||||
forms[i].getElementsByTagName('form')[0].hidden = true;
|
||||
forms[i].getElementsByTagName('h6')[0].hidden = false;
|
||||
}
|
||||
}
|
||||
|
||||
function enableControl() {
|
||||
forms = document.getElementsByClassName('form');
|
||||
|
||||
for (i = 0; i < forms.length; i++) {
|
||||
forms[i].getElementsByTagName('h6')[0].hidden = true;
|
||||
forms[i].getElementsByTagName('form')[0].hidden = false;
|
||||
}
|
||||
}
|
||||
|
||||
function connectionCheck() {
|
||||
fetch("/con-check").then(function(response) {
|
||||
return response.json();
|
||||
}).then(function(data) {
|
||||
if (data.connected == 0 || data.connected == 2) {
|
||||
document.getElementById("connectBtn").hidden = false;
|
||||
disableControl();
|
||||
} else if (data.connected == 1) {
|
||||
document.getElementById("connectBtn").hidden = true;
|
||||
enableControl();
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function info(topic) {
|
||||
window.scrollTo(0, 0);
|
||||
|
||||
document.getElementsByTagName("BODY")[0].style["overflow"] = "hidden";
|
||||
|
||||
document.getElementById("page").style["filter"] = "blur(2.5px)";
|
||||
document.getElementById("page").style["position"] = "absolute";
|
||||
document.getElementById("page").style["width"] = "100%";
|
||||
document.getElementById("page").style["height"] = "100%";
|
||||
|
||||
document.getElementById(topic).hidden = false;
|
||||
}
|
||||
|
||||
function infoClose(topic) {
|
||||
document.getElementsByTagName("BODY")[0].style["overflow"] = null;
|
||||
|
||||
document.getElementById("page").style["filter"] = null;
|
||||
document.getElementById("page").style["position"] = null;
|
||||
document.getElementById("page").style["width"] = null;
|
||||
document.getElementById("page").style["height"] = null;
|
||||
|
||||
document.getElementById(topic).hidden = true;
|
||||
}
|
||||
|
||||
function execPayloadFile() {
|
||||
const reader = new FileReader();
|
||||
|
||||
reader.readAsText(document.getElementById("payloadFile").files[0]);
|
||||
|
||||
reader.onloadend = () => {
|
||||
query = reader.result;
|
||||
document.getElementById("payloadContent").value = query;
|
||||
|
||||
document.getElementById("payloadForm").submit();
|
||||
};
|
||||
}
|
||||
|
||||
connectionCheck()
|
||||
setInterval(connectionCheck, 10000);
|
||||
</script>
|
||||
</head>
|
||||
<body style="background-color: #202124; color: #adb5bd; height: 100%">
|
||||
<div id="page">
|
||||
<div>
|
||||
<nav class="navbar navbar-expand navbar-light fixed-top shadow-sm" style="border-bottom: solid; border-color: #1a62ec; border-width: 2px; background: #202124;">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand">
|
||||
<img src="static/logo.png" onclick="info('info_cp')" style="cursor: pointer; height: 45px; padding-right: 15px; padding-bottom: 5px; filter: brightness(0) saturate(100%) invert(23%) sepia(75%) saturate(3313%) hue-rotate(217deg) brightness(99%) contrast(86%);" class="d-inline-block">
|
||||
</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarToggler" aria-controls="navbarToggler" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarToggler">
|
||||
<ul class="nav ms-auto">
|
||||
<li class="nav-item">
|
||||
<a class="btn btn-imp" title="Connect" href="/connect" id="connectBtn" hidden>Connect to Bash Bunny</a>
|
||||
</li>
|
||||
<li class="nav-item" style="margin: auto; margin-right: 15px; margin-left: 20px;">
|
||||
<a style="cursor: pointer; font-size: 1.25rem;" title="Copyright & Attribution" onclick="info('info_cp')">©</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<nav class="navbar navbar-expand-lg navbar-light" style="visibility: hidden;">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="#">
|
||||
<img src="static/bb_icon.png" style="height: 45px; padding-right: 15px;" class="d-inline-block"><span style="vertical-align: middle;">BlueBunny</span>
|
||||
</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarToggler" aria-controls="navbarToggler" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse">
|
||||
<ul class="nav">
|
||||
<li class="nav-item">
|
||||
<a class="btn">Connect to Bash Bunny</a>
|
||||
</li>
|
||||
<li class="nav-item" style="margin: auto; margin-right: 15px; margin-left: 20px;">
|
||||
<a>©</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
<br>
|
||||
<br>
|
||||
<div class="container" style="display: flex; flex-flow: wrap; justify-content: start;">
|
||||
<div style="width: 20rem; margin-right: 50px; margin-bottom: 20px; min-height: 10rem;">
|
||||
<h4 style="color: #ced4da;">Payload One-Liner <p class="text-dark-emphasis" style="font-size: 15px;"><small>Run a single line of code</small></p></h4>
|
||||
<div class="form">
|
||||
<form action="" method="POST" hidden>
|
||||
<div class="input-group mb-3">
|
||||
<input type="text" class="form-control" placeholder="Q ALT F4" autocomplete="off" list="datalistOptions" name="query" style="background-color: #202124; border-color: #1a62ec; color: #adb5bd;">
|
||||
<datalist id="datalistOptions">
|
||||
<option value="Q STRING Hello World!"></option>
|
||||
<option value="Q CAPSLOCK"></option>
|
||||
<option value="Q ALT F4"></option>
|
||||
<option value="Q COMMAND q"></option>
|
||||
<option value="Q WIN r"></option>
|
||||
<option value="Q COMMAND SPACE"></option>
|
||||
</datalist>
|
||||
<input type="hidden" name="mode" value="cmd">
|
||||
<button class="btn" type="submit">Run</button>
|
||||
</div>
|
||||
</form>
|
||||
<h6 hidden>Not available</h6>
|
||||
</div>
|
||||
</div>
|
||||
<div style="width: 20rem; margin-right: 50px; margin-bottom: 20px; min-height: 10rem;">
|
||||
<h4 style="color: #ced4da;">Payload Script<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-info-circle-fill" viewBox="-5 5 19 19" style="overflow: visible; cursor: pointer;" onclick="info('info_payload')"><path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"/><path d="m8.93 6.588-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533L8.93 6.588zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0z"/></svg> <p class="text-dark-emphasis" style="font-size: 15px;"><small>Upload and execute a payload file</small></p></h4>
|
||||
<div class="form">
|
||||
<form hidden>
|
||||
<div class="input-group mb-3">
|
||||
<input type="file" accept=".txt" class="form-control" style="background-color: #202124; border-color: #1a62ec; color: #adb5bd;" id="payloadFile">
|
||||
</div>
|
||||
<button class="btn" title="Execute Payload" onclick="execPayloadFile()">Execute Payload</button>
|
||||
</form>
|
||||
<form action="" method="POST" id="payloadForm">
|
||||
<input type="hidden" name="mode" value="cmd">
|
||||
<input type="hidden" name="query" value="" id="payloadContent">
|
||||
</form>
|
||||
<h6 hidden>Not available</h6>
|
||||
</div>
|
||||
</div>
|
||||
<div style="width: 20rem; margin-right: 50px; margin-bottom: 20px; min-height: 10rem;">
|
||||
<h4 style="color: #ced4da;">Attack Mode<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-info-circle-fill" viewBox="-5 5 19 19" style="overflow: visible; cursor: pointer;" onclick="info('info_attackmode')"><path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"/><path d="m8.93 6.588-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533L8.93 6.588zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0z"/></svg> <p class="text-dark-emphasis" style="font-size: 15px;"><small>Configure Ethernet, Storage, HID and Serial</small></p></h4>
|
||||
<div class="form">
|
||||
<form action="" method="POST" hidden>
|
||||
<div class="input-group">
|
||||
<select class="form-select" style="background-color: #202124; border-color: #1a62ec; color: #adb5bd;" name="query">
|
||||
<option value="ATTACKMODE OFF" selected>None</option>
|
||||
<option value="ATTACKMODE SERIAL">SERIAL</option>
|
||||
<option value="ATTACKMODE ECM_ETHERNET">ECM ETHERNET</option>
|
||||
<option value="ATTACKMODE RNDIS_ETHERNET">RNDIS ETHERNET</option>
|
||||
<option value="ATTACKMODE AUTO_ETHERNET">AUTO ETHERNET</option>
|
||||
<option value="ATTACKMODE STORAGE">STORAGE</option>
|
||||
<option value="ATTACKMODE HID">HID</option>
|
||||
</select>
|
||||
<input type="hidden" name="mode" value="cmd">
|
||||
<button class="btn" type="submit">Update</button>
|
||||
</div>
|
||||
</form>
|
||||
<h6 hidden>Not available</h6>
|
||||
</div>
|
||||
</div>
|
||||
<div style="width: 20rem; margin-right: 50px; margin-bottom: 20px; min-height: 10rem;">
|
||||
<h4 style="color: #ced4da;">LED <p class="text-dark-emphasis" style="font-size: 15px;"><small>Light up your Bush Bunny</small></p></h4>
|
||||
<div class="form">
|
||||
<form action="" method="POST" hidden>
|
||||
<div class="input-group">
|
||||
<select class="form-select" style="background-color: #202124; border-color: #1a62ec; color: #adb5bd;" name="query">
|
||||
<option value="LED G" selected>Green</option>
|
||||
<option value="LED B">Blue</option>
|
||||
<option value="LED R">Red</option>
|
||||
<option value="LED Y">Yellow</option>
|
||||
<option value="LED C">Cyan</option>
|
||||
<option value="LED M">Magenta</option>
|
||||
<option value="LED W">White</option>
|
||||
</select>
|
||||
<input type="hidden" name="mode" value="cmd">
|
||||
<button class="btn" type="submit">Update</button>
|
||||
</div>
|
||||
</form>
|
||||
<h6 hidden>Not available</h6>
|
||||
</div>
|
||||
</div>
|
||||
<div style="width: 20rem; margin-right: 50px; margin-bottom: 20px; min-height: 10rem;">
|
||||
<h4 style="color: #ced4da;">CPU Control <p class="text-dark-emphasis" style="font-size: 15px;"><small>Tune the CPU to your needs</small></p></h4>
|
||||
<div class="form">
|
||||
<form action="" method="POST" hidden>
|
||||
<div class="input-group">
|
||||
<select class="form-select" style="background-color: #202124; border-color: #1a62ec; color: #adb5bd;" name="query">
|
||||
<option value="CUCUMBER ENABLE">Single Core Ondemand (Low Power)</option>
|
||||
<option value="CUCUMBER DISABLE" selected>Quad Core Ondemand (Default)</option>
|
||||
<option value="CUCUMBER PLAID">Quad Core Performance (High Performance)</option>
|
||||
</select>
|
||||
<input type="hidden" name="mode" value="cmd">
|
||||
<button class="btn" type="submit">Update</button>
|
||||
</div>
|
||||
</form>
|
||||
<h6 hidden>Not available</h6>
|
||||
</div>
|
||||
</div>
|
||||
<div style="width: 20rem; margin-right: 50px; margin-bottom: 20px; min-height: 10rem;">
|
||||
<h4 style="color: #ced4da;">Power Management<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-info-circle-fill" viewBox="-5 5 19 19" style="overflow: visible; cursor: pointer;" onclick="info('info_power')"><path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"/><path d="m8.93 6.588-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533L8.93 6.588zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0z"/></svg> <p class="text-dark-emphasis" style="font-size: 15px;"><small>Take a break</small></p></h4>
|
||||
<div class="form">
|
||||
<form action="" method="POST" hidden>
|
||||
<div class="input-group">
|
||||
<select class="form-select" style="background-color: #202124; border-color: #EC1A24; color: #adb5bd;" name="query">
|
||||
<option value="shutdown -h now" selected>Shutdown</option>
|
||||
<option value="reboot">Reboot</option>
|
||||
</select>
|
||||
<input type="hidden" name="mode" value="cmd">
|
||||
<button class="btn btn-imp" type="submit">Initialize</button>
|
||||
</div>
|
||||
</form>
|
||||
<h6 hidden>Not available</h6>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="position: absolute; width: 100%; height: 100%;" id="info_payload" hidden>
|
||||
<div style="display: flex; justify-content: center; align-items: center; margin-top: 25px;">
|
||||
<div class="rounded shadow" style="border: solid; border-color: #1a62ec; border-width: 1px; background: #202124; max-width: 600px; height: fit-content; margin-left: 15px; margin-right: 15px; display: flex; justify-content: center;">
|
||||
<div style="margin: 20px; width: 100%" id="action">
|
||||
<h3 class="text-center" style="color: #ced4da; margin-bottom: 10px;">Payload Script</h3>
|
||||
<p>This section allows you to execute custom payload files.</p>
|
||||
<p>The name of the uploaded file doesn't have to match <code>payload.txt</code>.</p>
|
||||
<p>Uploaded payloads will be sent to your Bash Bunny and will be saved temporary. After finishing your payload, it gets removed automatically.
|
||||
<div class="text-center" style="margin-top: 100px;">
|
||||
<button class="btn" onclick="infoClose('info_payload')">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="position: absolute; width: 100%; height: 100%;" id="info_attackmode" hidden>
|
||||
<div style="display: flex; justify-content: center; align-items: center; margin-top: 25px;">
|
||||
<div class="rounded shadow" style="border: solid; border-color: #1a62ec; border-width: 1px; background: #202124; max-width: 600px; height: fit-content; margin-left: 15px; margin-right: 15px; display: flex; justify-content: center;">
|
||||
<div style="margin: 20px; width: 100%" id="action">
|
||||
<h3 class="text-center" style="color: #ced4da; margin-bottom: 10px;">Attack Mode</h3>
|
||||
<p>This section allows you to change the Bash Bunny's attack mode like the <code>ATTACKMODE</code> payload command does.</p>
|
||||
<p>Further and more complex attack mode combinations can always be set from the "Payload One-Liner" or a payload file.</p>
|
||||
<p class="fw-bold">Important:</p>
|
||||
<p>When setting the attack mode, you likely can't change it without a reboot (besides disabling it again). The target machine may not recognize the change, for example, from STORAGE to HID. It may no longer detect the storage but won't be able to recognize the HID. Keep in mind: This can differ between target devices.</p>
|
||||
<div class="text-center" style="margin-top: 100px;">
|
||||
<button class="btn" onclick="infoClose('info_attackmode')">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="position: absolute; width: 100%; height: 100%;" id="info_power" hidden>
|
||||
<div style="display: flex; justify-content: center; align-items: center; margin-top: 25px;">
|
||||
<div class="rounded shadow" style="border: solid; border-color: #1a62ec; border-width: 1px; background: #202124; max-width: 600px; height: fit-content; margin-left: 15px; margin-right: 15px; display: flex; justify-content: center;">
|
||||
<div style="margin: 20px; width: 100%" id="action">
|
||||
<h3 class="text-center" style="color: #ced4da; margin-bottom: 10px;">Power Management</h3>
|
||||
<p>This section allows you to shutdown or reboot your Bash Bunny.</p>
|
||||
<p>After reboot, your Bash Bunny will run the payload available at the current switch position.</p>
|
||||
<p>Rebooting may help when you encouter execution issues. When the attacked device won't recognize attack mode changes, rebooting and then setting the new attack mode will fix it.</p>
|
||||
<div class="text-center" style="margin-top: 100px;">
|
||||
<button class="btn" onclick="infoClose('info_power')">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="position: absolute; width: 100%; height: 100%;" id="info_cp" hidden>
|
||||
<div style="display: flex; justify-content: center; align-items: center; margin-top: 25px;">
|
||||
<div class="rounded shadow" style="border: solid; border-color: #1a62ec; border-width: 1px; background: #202124; max-width: 600px; height: fit-content; margin-left: 15px; margin-right: 15px; display: flex; justify-content: center;">
|
||||
<div style="margin: 20px; width: 100%" id="action">
|
||||
<h3 class="text-center" style="color: #ced4da; margin-bottom: 10px;">Copyright & Attribution</h3>
|
||||
<br>
|
||||
<img src="static/logo.png" style="height: 45px; padding-right: 15px; padding-bottom: 5px;" class="d-inline-block">
|
||||
<p>BlueBunny is an open source project from <code><a href="https://github.com/90N45-d3v">90N45</a></code>.<br>It is licensed under the MIT license and should be treated as such.</p>
|
||||
<br>
|
||||
<img src="static/bb_icon_original.png" style="height: 45px; padding-right: 15px; padding-bottom: 5px;" class="d-inline-block">
|
||||
<p>Bash Bunny is a trademark of Hak5 LLC.<br>Visit <code><a href="https://hak5.org">hak5.org</a></code> for more.</p>
|
||||
<div class="text-center" style="margin-top: 100px;">
|
||||
<button class="btn" onclick="infoClose('info_cp')">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,92 @@
|
|||
![BlueBunny-Banner](https://github.com/90N45-d3v/BlueBunny/assets/79598596/fae0b5ca-6b38-41b3-a5fc-7aa3cabea369)
|
||||
<p align="center">
|
||||
<img src="https://img.shields.io/badge/Made%20with-Python-blue">
|
||||
<img src="https://img.shields.io/github/license/90N45-d3v/BlueBunny.svg">
|
||||
<img src="https://img.shields.io/badge/Ask%20me-anything-1abc9c.svg">
|
||||
<br>
|
||||
<img src="https://img.shields.io/badge/-Linux-lightblue">
|
||||
</p>
|
||||
<p align="center">
|
||||
C2 solution that communicates directly over Bluetooth-Low-Energy with your Bash Bunny Mark II.<br>Send your Bash Bunny all the instructions it needs just over the air.
|
||||
</p>
|
||||
|
||||
* Author: 90N45
|
||||
* Version: 1.0
|
||||
* Category: Remote
|
||||
* Attackmodes: NONE (Custom)
|
||||
|
||||
## Table of contents
|
||||
- [Overview](https://github.com/90N45-d3v/BlueBunny#overview)
|
||||
- [Installation & Start](https://github.com/90N45-d3v/BlueBunny#installation--start)
|
||||
- [Manual communication with the Bash Bunny through Python](https://github.com/90N45-d3v/BlueBunny#manual-communication-with-the-bash-bunny-through-python)
|
||||
- [Troubleshooting](https://github.com/90N45-d3v/BlueBunny#troubleshooting)
|
||||
- [Working on...](https://github.com/90N45-d3v/BlueBunny#working-on)
|
||||
- [Additional information](https://github.com/90N45-d3v/BlueBunny#additional-information)
|
||||
|
||||
## Overview
|
||||
#### Structure
|
||||
![BlueBunny-Structure](https://github.com/90N45-d3v/BlueBunny/assets/79598596/3004fb10-feef-45c8-8624-1393c2fb7288)
|
||||
|
||||
|
||||
## Installation & Start
|
||||
1. Install required dependencies
|
||||
````
|
||||
pip install pygatt "pygatt[GATTTOOL]"
|
||||
````
|
||||
Make sure [BlueZ](http://www.bluez.org/download/) is installed and `gatttool` is usable
|
||||
````
|
||||
sudo apt install bluez
|
||||
````
|
||||
2. Download the `BlueBunny` folder and switch into the `BlueBunny/C2` folder
|
||||
````
|
||||
cd BlueBunny/C2
|
||||
````
|
||||
3. Start the C2 server
|
||||
````
|
||||
sudo python c2-server.py
|
||||
````
|
||||
4. Plug your Bash Bunny with the BlueBunny payload into the target machine (payload at: `BlueBunny/payload.txt`).
|
||||
5. Visit your C2 server from your browser on `localhost:1472` and connect your Bash Bunny (Your Bash Bunny will light up green when it's ready to pair).
|
||||
|
||||
|
||||
## Manual communication with the Bash Bunny through Python
|
||||
You can use BlueBunny's BLE backend and communicate with your Bash Bunny manually.
|
||||
#### Example Code
|
||||
````python
|
||||
# Import the backend (BlueBunny/C2/BunnyLE.py)
|
||||
import BunnyLE
|
||||
|
||||
# Define the data to send
|
||||
data = "QUACK STRING I love my Bash Bunny"
|
||||
# Define the type of the data to send ("cmd" or "payload") (payload data will be temporary written to a file, to execute multiple commands like in a payload script file)
|
||||
d_type = "cmd"
|
||||
|
||||
# Initialize BunnyLE
|
||||
BunnyLE.init()
|
||||
|
||||
# Connect to your Bash Bunny
|
||||
bb = BunnyLE.connect()
|
||||
|
||||
# Send the data and let it execute
|
||||
BunnyLE.send(bb, data, d_type)
|
||||
````
|
||||
|
||||
## Troubleshooting
|
||||
#### Connecting your Bash Bunny doesn't work? Try the following instructions:
|
||||
- Try connecting a few more times
|
||||
- Check if your bluetooth adapter is available
|
||||
- Restart the system your C2 server is running on
|
||||
- Check if your Bash Bunny is running the BlueBunny payload properly
|
||||
- How far away from your Bash Bunny are you? Is the environment (distance, interferences etc.) still sustainable for typical BLE connections?
|
||||
#### Bugs within BlueZ
|
||||
The Bluetooth stack used is well known, but also very buggy. If starting the connection with your Bash Bunny does not work, it is probably a temporary problem due to BlueZ. Here are some kind of errors that can be caused by temporary bugs. These usually disappear at the latest after rebooting the C2's operating system, so don't be surprised and calm down if they show up.
|
||||
- Timeout after 5.0 seconds
|
||||
- Unknown error while scanning for BLE devices
|
||||
|
||||
## Working on...
|
||||
- Remote shell access
|
||||
- BLE exfiltration channel
|
||||
- Improved connecting process
|
||||
|
||||
## Additional information
|
||||
As I said, BlueZ, the base for the bluetooth part used in BlueBunny, is somewhat bug prone. If you encounter any non-temporary bugs when connecting to Bash Bunny as well as any other bugs/difficulties in the whole BlueBunny project, you are always welcome to contact me. Be it a problem, an idea/solution or just a nice feedback.
|
|
@ -0,0 +1,63 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Title: BlueBunny
|
||||
# Description: BLE based C2 server for the Bash Bunny Mark II
|
||||
# Author: 90N45
|
||||
# Version: 1.0
|
||||
# Category: Remote
|
||||
# Attackmodes: NONE (Custom)
|
||||
|
||||
LED SETUP
|
||||
|
||||
# Enable serial BLE module
|
||||
stty -F /dev/ttyS1 speed 115200 cs8 -cstopb -parenb -echo -ixon -icanon -opost
|
||||
stty -F /dev/ttyS1 speed 115200 cs8 -cstopb -parenb -echo -ixon -icanon -opost
|
||||
sleep 1
|
||||
|
||||
# Configure BLE module as slave
|
||||
echo -n -e "AT+ROLE=0" > /dev/ttyS1
|
||||
echo -n -e "AT+NAME=BlueBunny" > /dev/ttyS1
|
||||
echo -n -e "AT+ADV=1" > /dev/ttyS1
|
||||
echo -n -e "AT+RESET" > /dev/ttyS1
|
||||
|
||||
LED FINISH
|
||||
|
||||
while [[ true ]]; do
|
||||
# Get incomming data from serial port
|
||||
data=$(head -1 /dev/ttyS1)
|
||||
|
||||
# Decode base64 encoded data
|
||||
data=$(echo ${data} | base64 -d)
|
||||
|
||||
# Echo data for debugging
|
||||
echo "Debugger: ${data}"
|
||||
|
||||
# Single command
|
||||
if [[ $data =~ "<CMD>" ]]; then
|
||||
# Extract command
|
||||
command=${data#*<CMD>}
|
||||
command=${command%%<CMD>*}
|
||||
|
||||
# Run recieved command
|
||||
eval "${command}"
|
||||
fi
|
||||
|
||||
# Payload file
|
||||
if [[ $data =~ "<PAYLOAD>" ]]; then
|
||||
# Set payload file name
|
||||
file="BlueBunnyPayload-${RANDOM}.txt"
|
||||
|
||||
# Extract file content
|
||||
content=${data#*<PAYLOAD>}
|
||||
content=${content%%<PAYLOAD>*}
|
||||
|
||||
# Write content to file
|
||||
printf "${content}" > "${file}";
|
||||
|
||||
# Run payload
|
||||
bash $file
|
||||
|
||||
# Remove payload file
|
||||
rm $file
|
||||
fi
|
||||
done
|
Loading…
Reference in New Issue