This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
howto:dji_ftpd_aes_unscramble [2017/07/28 12:42] czokie [3. Now What?] |
howto:dji_ftpd_aes_unscramble [2019/01/15 23:00] (current) czokie |
||
---|---|---|---|
Line 3: | Line 3: | ||
When you get FTP access to your DJI, you can push files to the aircraft using normal FTP commands (to a limited subset of directories due to /system being read only). | When you get FTP access to your DJI, you can push files to the aircraft using normal FTP commands (to a limited subset of directories due to /system being read only). | ||
- | But, downloading is another matter. DJI modified the FTPD that is built into their firmware, to stop people getting access to the files, in an attempt to hide the fact that their aircraft is using GPL software contrary to the software | + | But, downloading is another matter. DJI modified the FTPD that is built into their firmware, to stop people getting access to files, in an attempt to hide the fact that their aircraft is using GPL software contrary to the licenses of those GPL components. |
- | A number of people have already solved how to upload/ | + | A number of people have already solved how to upload/ |
+ | |||
+ | Through earlier work, we have the decryption key. Before encrypting, DJI also do some XOR operations on the first 16 bytes of the input document, | ||
+ | |||
+ | This method is published [[https:// | ||
===== 1. Toolchain ===== | ===== 1. Toolchain ===== | ||
Line 11: | Line 15: | ||
===== 2. Get the DJI_ftpd_aes_unscramble magic ===== | ===== 2. Get the DJI_ftpd_aes_unscramble magic ===== | ||
- | If this is your first time using duml, you will need to checkout the code from git. | + | If this is your first time using DJI_ftpd_aes_unscramble, you will need to checkout the code from git. |
cd ~/ | cd ~/ | ||
Line 24: | Line 28: | ||
===== 3. Now What? ====== | ===== 3. Now What? ====== | ||
+ | Below are a set of instructions that come from the GIT repository where this code is located. The details are included here for ease of use. | ||
+ | |||
- | Through earlier work, we have the decryption key. Before encrypting, DJI also do some XOR operations | + | # DJI_ftpd_aes_unscramble |
+ | DJI has modified | ||
+ | |||
+ | Windows executable release created via: | ||
+ | < | ||
+ | c: | ||
+ | </ | ||
+ | If not using packaged release for Windows, make sure you have pip, and that pycrypto is installed | ||
+ | |||
+ | Usage: | ||
+ | Make sure you have a DJI Mavic, Inspire 2, or Phantom 4, or Spark connected. | ||
+ | |||
+ | Mirror the FTPD via the script, OR manually pull down a target file. | ||
+ | < | ||
+ | $ python dji_ftpd_descrambler.py 192.168.42.2 | ||
+ | --2017-05-25 23: | ||
+ | => ‘DJI_aes_ftp_dump/ | ||
+ | Connecting to 192.168.42.2: | ||
+ | Check the contents of the folder DJI_aes_ftp_dump | ||
+ | ... | ||
+ | |||
+ | Verify the file is AES encrytped aka " | ||
+ | $ xxd DJI_aes_ftp_dump/ | ||
+ | 00000000: dee9 a171 7fad 24e2 a2ad fe52 f2a9 43e4 ...q..$....R..C. | ||
+ | 00000010: cdf3 ab35 4ec3 82a8 f491 f3e5 40a8 c92c ...5N.......@.., | ||
+ | 00000020: b80a 8c8e 0bef 6bf5 5505 b71c d819 9bde ......k.U....... | ||
+ | 00000030: cf23 f181 68b1 ae23 6305 1c8b 4d1a 986c .# | ||
+ | 00000040: 4d3e 569a 97e1 33b0 7a05 4ff1 92c2 d88d M> | ||
+ | 00000050: 20b7 d872 5ef4 a288 f25d dc06 a8e7 6b0d | ||
+ | 00000060: dc14 85c1 45eb bc59 36d8 1c63 b17f d35b ....E..Y6..c...[ | ||
+ | 00000070: 07c0 1499 ff5b 4c0f 7cc7 df67 d09b a2ea .....[L.|..g.... | ||
+ | 00000080: 0dfc fcb3 8aab 5f06 aace 0f41 a6c6 fb89 ......_....A.... | ||
+ | 00000090: 5d13 a609 c74a 7318 4734 2d95 d5bc b975 ]....Js.G4-....u | ||
+ | </ | ||
+ | |||
+ | Descramble the file... profit! | ||
+ | < | ||
+ | $ python dji_ftpd_descrambler.py DJI_aes_ftp_dump/ | ||
+ | PBS^U\5] [0x0] state=0, reset phy | ||
+ | [1980/00/01 0:0:5] [0x0]========= machine=1, state=0, runtime=72 ========= | ||
+ | [1980/00/01 0:0:5] [0x0] state=0, [0] reset mac to idle | ||
+ | [1980/00/01 0:0:7] [0x1866] state=0, recv shakehand req | ||
+ | [1980/00/01 0:0:7] [0x187c] state from 0 to connect | ||
+ | [2017/04/14 14:42:30] [0x3d27d0] state=3, connect to out_of_sync | ||
+ | [2017/04/14 14:42:30] [0x3d27d0] state=3, [1] reset mac to idle | ||
+ | [2017/04/14 14:44:8] [0x47d] state=3, recv shakehand req | ||
+ | [2017/04/14 14:44:8] [0x4c3] state=3, recv shakehand req | ||
+ | [2017/04/14 14:44:8] [0x530] state from 3 to connect | ||
+ | </ | ||
+ | On Windows the process works the same, with alternate synatx | ||
+ | |||
+ | You can use the new bash interface: | ||
+ | < | ||
+ | MavproxyUser@DESKTOP-QPUF664 MINGW64 ~/ | ||
+ | $ python dji_ftpd_descrambler.py kernel00.log | ||
+ | oOZTPTP7] c0 1 (init) init: untracked pid 621 exited | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | </ | ||
+ | Or make use of the standard cmd.exe interface: | ||
+ | < | ||
+ | C: | ||
+ | !!!New kernel log start!!! | ||
+ | |||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | -- More -- | ||
+ | </ | ||
+ | Alternatively on windows you can use the precompied .exe (see the Releases tab) | ||
+ | < | ||
+ | C: | ||
+ | h | ||
+ | VTVSPW] c1 11916 (kworker/ | ||
+ | <7>[ 1380.255734] c1 11916 (kworker/ | ||
+ | <7>[ 1382.825736] c0 26031 (kworker/ | ||
+ | </ | ||
+ | |||
+ | Description: | ||
+ | |||
+ | |||
+ | I miss the good ole days of public tar & feathering over GPL violations! | ||
+ | |||
+ | < | ||
+ | "The following products | ||
+ | </ | ||
+ | |||
+ | < | ||
+ | This page is no longer updated, these days, BusyBox handles enforcement | ||
+ | |||
+ | Previously, this page listed products that included BusyBox but included neither source code nor offer for one. The BusyBox project has decided to not publicly shame companies until Conservancy has an opportunity to talk privately with companies who violate the GPL to convince them to comply with BusyBox' | ||
+ | </code> | ||
+ | |||
+ | https:// | ||
+ | |||
+ | In an attempt to obfuscate the files downloaded from several DJI products, an AES function | ||
+ | |||
+ | It is extremely trivial to extract the binary using binwalk from one of the available firmware downloads. From here it can be Reverse Engineered. | ||
+ | |||
+ | |||
+ | On OSX you can navigate to: / | ||
+ | On Windows to: C:\Program Files (x86)\DJI Product\DJI Assistant 2\ Assistant\Data\firm_cache | ||
+ | |||
+ | Run binwalk with the extraction flag against any appropriate firmware file. | ||
+ | < | ||
+ | $ grep busybox wm* -r | ||
+ | Binary file wm220_0100_v02.05.04.34_20170209_ca02.pro.fw.sig matches | ||
+ | Binary file wm220_0100_v02.06.04.84_20170324_ca02.pro.fw.sig matches | ||
+ | Binary file wm220_0801_v01.04.17.03_20170120.pro.fw.sig matches | ||
+ | Binary file wm220_0801_v01.05.00.20_20170331.pro.fw.sig matches | ||
+ | Binary file wm220_0805_v01.01.00.71_20161227.pro.fw.sig matches | ||
+ | Binary file wm220_0805_v01.01.00.87_20170427.pro.fw.sig matches | ||
+ | Binary file wm220_1301_v01.04.17.03_20170120.pro.fw.sig matches | ||
+ | Binary file wm220_1301_v01.05.00.23_20170418.pro.fw.sig matches | ||
+ | Binary file wm220_2801_v01.02.21.01_20170421.pro.fw.sig matches | ||
+ | </ | ||
+ | |||
+ | Pick one... just make sure it doesn' | ||
+ | < | ||
+ | $ binwalk -e wm220_0801_v01.04.17.03_20170120.pro.fw.sig | ||
+ | </ | ||
+ | Launch the binary in a chroot via qemu-user-static. | ||
+ | https:// | ||
+ | |||
+ | < | ||
+ | # ./busybox tcpsvd -vE 0.0.0.0 21 ./busybox ftpd -wv /tmp/ | ||
+ | tcpsvd: listening on 0.0.0.0:21, starting | ||
+ | tcpsvd: status 1/30 | ||
+ | tcpsvd: start 9062 127.0.0.1: | ||
+ | </ | ||
+ | |||
+ | Download, compile, and run aes-finder against the ftp binary. Extract the AES key by running against the PID. | ||
+ | https:// | ||
+ | |||
+ | < | ||
+ | $ sudo ./a.out -9062 | ||
+ | Searching PID 9062 ... | ||
+ | [0x7f4e6c17b93c] Found AES-128 encryption key: 746869732d6165732d6b657900000000 | ||
+ | [0x7f4e6c17ba30] Found AES-128 decryption key: 746869732d6165732d6b657900000000 | ||
+ | |||
+ | $ echo -e " | ||
+ | this-aes-key | ||
+ | </ | ||
+ | |||
+ | This oddly enough was the string that made me look for the routine in the first place. It shows up in clear text in the binary. | ||
+ | Busybox does not normally have an AES function, so this was immediately a red flag. | ||
+ | |||
+ | I had a hunch that DJI reused their encryption choices... and they did, the same routines used on the NAZA firmware work on the downloads. | ||
+ | |||
+ | https:// | ||
+ | https:// | ||
+ | |||
+ | Simply replace the AES key with the one above in the tool provided by seasonalvegetables3. | ||
+ | |||
+ | < | ||
+ | #Key = " | ||
+ | Key = " | ||
+ | IV = " | ||
+ | </ | ||
+ | |||
+ | This project will recurvively download the contents of the ftp server, and decrypt them for you in a local plaintext mirror. | ||
+ | |||
+ | In essence using code in this repo would be the same as running: | ||
+ | < | ||
+ | $ wget -m ftp:// | ||
+ | </ | ||
+ | |||
+ | Followed by: | ||
+ | < | ||
+ | python djicrypt.py -d -i downloadedfile -o outputfile | ||
+ | </ | ||
+ | |||
+ | Alternately you can just use openssl: | ||
+ | < | ||
+ | openssl enc -d -nosalt -in downloadedfile -aes-128-cbc -K 746869732d6165732d6b657900000000 -iv 00000000000000000000000000000000 | ||
+ | </ | ||
+ | |||
+ | And of course *our* script | ||
+ | |||
+ | In this example | ||
- | This method is published [[https://github.com/MAVProxyUser/DJI_ftpd_aes_unscramble|here]]. | + | $ python dji_ftpd_descrambler.py |
+ | < | ||
+ | < | ||
+ | initrd=0x07400000, | ||
+ | recovery: | ||
+ | chip_sn=31337000 board_sn=01EAT2D111XXXX daak=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA daek=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA drak=6f707f2962351d75bc089ac34da119fa | ||
+ | saak=6f402fb8625205ce9bdd580217d218d8 waek=WIFIPASS production quiet board_id=0xe2200026 | ||
+ | </ | ||
+ | ===== Credit ===== | ||
+ | * This python module was created by Hostile (aka MavProxyUser). | ||
+ | * Subsequent bug fixes created by Czokie. | ||
+ | * Earlier work was based on https:// |