robertdavidgraham/whats-dec là dự án mã nguồn mở trên GitHub, viết chủ yếu bằng C, với 94 sao. WhatsApp end-to-end media decryptor
Tóm tắt dựng từ metadata GitHub của chính dự án — chưa có bài review TopGit. Trang sẽ tự động cập nhật khi bài review đầy đủ được xuất bản.
VÌ SAO CHƯA CÓ REVIEW
TopGit viết bài đầy đủ cho repo có nhiều sao nhất và được yêu cầu nhiều nhất. Trang này là snapshot trong thời gian chờ — xem README gốc ở tab READ ME.
This is a program for decrypting and decoding WhatsApp end-to-end encrypted
media files (videos, photos, audio).
This is written in responsibe to the January 2020 story claiming Saudi Crown
Prince MBS hacked the iPhone of Amazon CEO Jeff Bezos. The report said it
could not decrypt the video sent by MBS to Bezos, and the phone acted
strangely after receiving the video. The implication is that the video
probably contained some sort of hack or virus.
However, such things can be easily decrypted. The term "end-to-end" means
nobody in the middle can decrypt it, including the service provider like
WhatsApp. However, those in posession of the "ends" can still decrypt it.
The necessary decrypt key is, in fact, located right next to the encrypted
filename within the WhatsApp database, so there's no reason why the
investigators couldn't decrypt the file. All they would need is a tool --
a tool like this one.
This program doesn't simply decrypt the file, but also spits out a lot of
diagnostic information about what it decoded in the file. One of the reasons
the investigators were suspicious of the encrypted file was because it was
slightly longer. In fact, WhatsApp encryption always adds between 11 and 26
bytes to the end of everything it encrypts, so this is not strange. This
program decodes exactly what those extra bytes are, so that this fact can
be verified.
This means that of suspecting MBS, we can either covict him beyond a shadow
of a doubt, or completely exonerate him. If the encrypted file contains
an exploit or malware, we can know for certain. Likewise, if it doesn't,
we'll know that for certain as well.
The investigator Bezos hired used expensive tools marketed only to law
enforcement. However, everything the did can be done by you at home with
free tools. A section below describes how to do everything with your own
iPhone using free tools to decrypt Whatsapp videos from your own iPhone.
Building
This program is written entirely in the C programing language with no dependencies.
It'll compile on Windows, Linux, macOS, and many other places.
It relies on no other dependency than the standard C library
(all the crypto routines are included).
Simply compile the files together, as in:
$ cc *.c -o whats-enc
There is also a Makefile in the directory:
$ make
$ make test
You need a C compiler, such as Microsoft Visual C, gcc, or clang. On Debian
versions of Linux, this can be obtained by:
$ sudo apt install build-essential
Extracting end-to-end keys
End-to-end encryption means that nobody in the middle can decrypt messages or
content. The WhatsApp messaging app uses end-to-end encryption, meaning that
not even WhatsApp can decrypt either text messages or multi-media messages
containing video.
However, the devices on either end need to be able to decrypt these things.
That means the decryption keys are located somewhere on the device.
A forensics analysis of the device, or a backup of the device, should be
able to retrieve the decryption keys, and thus, decrypt any content.
For WhatsApp, these keys are stored in a file called ChatStorage.sqlite.
When you backup an iPhone, this file gets renamed to
7c7fba66680ef796b916b067077cc246adacf01d.
This file contains an SQL database. Inside that debase is a table called
ZWAMEDIAITEM. In that table are two columns of interest, ZMEDIAULR that
is the download URL for the encrypted media file, and ZMEDIAKEY needed to
decrypt it.
The ZMEDIAKEY contains more than just the key we need. It is a "blob"
containing binary data, which you can format in hex, as in the block
below:
0a 20 31 67 ca 52 06 c6 e9 c3 5c 18 ea a0 5c 7e
d3 d3 72 4f 46 65 3d d6 85 8e d5 62 d3 f7 6b 25
58 90 12 20 70 21 23 08 1a 9f 8a c1 e2 80 29 b5
f7 82 87 99 83 8d 66 32 d8 2b ad 58 78 9c c1 4f
bb 80 90 bc 18 9f c4 e7 f1 05 20 01
This blob is structured with protobufs and has four
fields. The first field contains the encryption key
that we'll use for the next step. The first byte
0a is the field tag, and the second byte 20 is the length
of the key, in this case 0x20 or 32 bytes. The next
32 bytes are the key, as in:
31 67 ca 52 06 c6 e9 c3 5c 18 ea a0 5c 7e
d3 d3 72 4f 46 65 3d d6 85 8e d5 62 d3 f7 6b 25
58 90
We use this key in the step below.
Example usage
A friend used WhatsApp to send a video to my iPhone. I backed up the phone
to my computer, and using the steps above, extracted both the URL of the
encrypted video and the key.
The URL was https://mmg-fna.whatsapp.net/d/f/Aj_7Mge6zUvrFKT-B600W-hk36LiHU3zhh2W-UI0q4Ld.enc.
The key was 3167ca5206c6e9c35c18eaa05c7ed3d3724f46653dd6858ed562d3f76b255890.
I used the program curl to download the encrypted video. I then used
this program to decrypt the file.
$ curl https://mmg-fna.whatsapp.net/d/f/Aj_7Mge6zUvrFKT-B600W-hk36LiHU3zhh2W-UI0q4Ld.enc -o mbsvid.enc
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 4331k 100 4331k 0 0 2506k 0 0:00:01 0:00:01 --:--:-- 2505k
$ ./whats-dec --in mbsvid.enc --out mbsvid.mp4 --key 3167ca5206c6e9c35c18eaa05c7ed3d3724f46653dd6858ed562d3f76b255890
[+] ciphertext = mbsvid.enc
[+] plaintext = mbsvid.mp4
[+] mediatype = video
[+] mediakey = 3167ca5206c6e9c35c18eaa05c7ed3d3 724f46653dd6858ed562d3f76b255890
[a] info string = WhatsApp Video Keys
[b] mediakey.iv = 8df703e1097a254e0c156eaa5715d3ab
[c] mediakey.aeskey = 2e294ad0892b1a985383c5d9c9e662fe a23ada93e19e973f02e4e2bd32930abf
[d] mediakey.mackey = 7f69685c88160ca3313a940c871afef6 bbab93278d9adba44e122bd695fbe0ee
[e] block[0] = 0000001c667479706d70343200000000
[f] block[n] = 5a5a5a5a5a5a5a5a5a5a5a5e
[g]-padding = 04040404
[h]-mac = fed41680725fba0dd4f1
[i] MAC = fed41680725fba0dd4f1e8b3409bedef a35c13dadb5ecff72b79764df79af8d9
[j] matched! (verified unmodified)
[k] SHA256(file).hex = 7ea5a6036f2e3a4a33ca18f1ac33c669 0cce86df371109af09a00574dda6509d
[l] SHA256(file).b64 = fqWmA28uOkozyhjxrDPGaQzOht83EQmvCaAFdN2mUJ0=
[m] SHA256(enc).hex = 702123081a9f8ac1e28029b5f7828799 838d6632d82bad58789cc14fbb8090bc
[n] SHA256(enc).b64 = cCEjCBqfisHigCm194KHmYONZjLYK61YeJzBT7uAkLw=
The output marked with [+] just repeats the configuration given on the
command-line. The input encrypted file is that downloaded from curl stored in
mbsvid.enc. The decrypted file we are going to ouput will be written to
mbsvid.mp4.
Here is an explanation of the additional fields:
[a] info string
This is a string needed for something called 'key expansion', derived
from the output file type. If you think the file is one format, such as
a JPEG, but it's in fact another format, like an MP4, then it won't decrypt
correctly (will appear corrupt). The correct format is stored in the database
alongside the URL and mediakey, but it's likely you'll just already know
the proper format before using this program.
[b] mediakey.iv
Modern encryption needs not only a secret key but also an "initialization
vector" or "nonce". This value is derived from the original mediakey that
was passed into the program via the key expansion step.
[c] mediakey.aeskey
The 256-bit mediakey is not the 256-bit AES key used to decrypt the file.
Instead, the AES key is derived from the mediakey via key expansion.
[d] mediakey.mackey
Modern encryption needs to not only encrypt the data but also verify
that it hasn't been modified or corrupted, often using what's called
a message authentication code. This also needs a key, which we also
derived from the original mediakey.
[e] block[0]
The first 16 decrypted bytes. If you see completely random stuff, then
the encryption key may be bad and it's not working. Most file formats
have a distinctive patterns, such as the numerous 00 bytes seen above.
[f] block[n]
The last decrypted bytes from the last block, minus any padding.
This is usually less than 16 bytes, as in the above example where it's
only 12 bytes. It's also often non-random, as in the above example where
it's mostly 5a bytes.
[g]-padding
Since AES encrypts 16-byte blocks, the last block will be padded out to
16-bytes. The last byte has a value from [1..16], indicating the number
of bytes of padding. It appears that this byte is then repeated for all
padding. We see above that there are 4 bytes of padding, so all the bytes
have the value of 4.
[h]-mac
After all the 16-byte blocks, the encrypted file now ends with 10 bytes
of the "message authentication code", calculated by using a keyed
hash over the entire contents. This code is 32-bytes long, but for
whatever reason, WhatsApp only appends the first 10-bytes. These
10-bytes must match the first 10-bytes of the calculated value
in [i] below.
[i] MAC
The 32-byte message authentication code we calculated when decrypting
the entire file. We only need the first 10-bytes to match the field
above, but we have to calculate the entire 32-byte field, so it's
shown here.
[j] verified/corrupted
This field just reports whether the first 10 bytes of [i] and [j]
matches, in case you couldn't see for yourself.
[k] SHA256(file).hex
The keyed hash is used to tell if the file has been corrupted in
transit. We also calculate other hashes (without a key). This
hash is the SHA256 algorithm applied to the decrypted file,
the same result if your run from the command-line openssl sha256 mbsvid.mp4.
This is reported in hex. Whereas hashes like this are often used
to detect corruption, they are also used as a file's identity.
Two files with the same hash always have identical contents.
[l] SHA256(file).b6
This is the same value as in [k], but encoded in BASE64. This is because
WhatsApp often passes around this value encoded this way. In particular,
in the same SQLite file that contains the mediaurl and mediakey, you'll
find this same value stored under the ZCARDNAME field.
[m] SHA256(file).hex
This is the hash of the encrypted file. In other words, this hashes
the file after it was encrypted. It's the same as running the command
openssl sha256 mbsvid.enc. This, too, is stored in the SQLdatabase.
You'll find it as the second field in the protobuf holding the mediakey.
[n] SHA256(file).b64
This is the same value as in [m], but encoded as BASE64 instead of HEX.
If you are worried about hackers hiding exploits or malware inside the
extra bytes of the encrypted version of the file, the place to look is
the "padding" and "mac" fields described above. As you can see in this
example, the bytes can't contain anything nefarious. The padding
contains all 04 bytes, and the 'mac' is predetermined by the calculation
and can't practically contain anything determined by the hacker.
Trang TopGit này là một snapshot — tab "Readme" hiển thị nguyên văn README của repo (đã bỏ link, giữ ảnh). Repo GitHub ở github.com/robertdavidgraham/whats-dec là nguồn chính thức.
robertdavidgraham/whats-dec có bao nhiêu sao?
robertdavidgraham/whats-dec có 94 sao GitHub — tải lại trang để xem số mới nhất, hoặc xem trực tiếp github.com/robertdavidgraham/whats-dec. TopGit phản chiếu số sao của GitHub nhưng không cam kết đến từng phút.
robertdavidgraham/whats-dec có tag gì không?
Bản đồng bộ chưa ghi nhận topic GitHub nào cho robertdavidgraham/whats-dec. GitHub topics hiển thị ở thanh bên phải trang repo — đó là nơi đáng kiểm tra nhất.
robertdavidgraham/whats-dec còn đang phát triển không?
Commit gần nhất trên robertdavidgraham/whats-dec là 3.5 năm trước (theo timestamp GitHub). Repo có 20 fork — một chỉ báo về mức độ quan tâm của cộng đồng.
robertdavidgraham/whats-dec viết bằng ngôn ngữ gì?
robertdavidgraham/whats-dec chủ yếu viết bằng C. Trường "language" của GitHub dựa trên phần lớn byte ở nhánh mặc định.
Đọc đầy đủ README ở tab phía trên.
Muốn nghe thêm một ý kiến về whats-dec?
Hỏi một AI đọc được trang này — một cú bấm là có ngay nhận định về whats-dec.