-
Notifications
You must be signed in to change notification settings - Fork 60
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #79 from pensivepaddle/main
dragonslayerz - chatlog and shrunk writeup
- Loading branch information
Showing
9 changed files
with
197 additions
and
0 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
# Chatlog | ||
Writeup by slayyy @ Dragonslayerz | ||
|
||
__Lesson learned:__ Respect the KISS principle. | ||
|
||
### Introduction | ||
We are given a text file containing a brief conversation between misters Rivest and Adleman. The names are a reference to two of the three inventors of the RSA encryption algorithm ([Wikipedia](https://en.wikipedia.org/wiki/RSA_(cryptosystem))). | ||
|
||
In this challenge, we were given the following parameters for an RSA encryption: | ||
- `n` (modulus) | ||
- `e` (public exponent) | ||
- `ct` (ciphertext) | ||
|
||
Our goal was to decrypt the ciphertext `ct` to retrieve the original message. | ||
|
||
### Solution | ||
The first thing that popped out is the use of a huge public exponent, `e`. After an extensive time used within the team trying to solve the puzzle, after the food was served at the venue, one team member used Google for research with the following query: | ||
|
||
![Google Search Query - ](0_google.png) | ||
|
||
The first page of results indicated quite certain that huge exponents are vulnerable to [Wiener's Attack](https://en.wikipedia.org/wiki/Wiener%27s_attack). | ||
|
||
The next step was finding appropriate tools in our programming language of choice, which led us to the `owiener` module ([PyPI](https://pypi.org/project/owiener/)). | ||
|
||
|
||
#### Finding the `d` | ||
```find_the_d.py | ||
import owiener | ||
|
||
e = 6251728305055461128215101113791542074487626873355761684912706796947820318045025894574010369655098754702916182673592159941529716341070091220295342244632166182377719507598162603755176681008223777597129409701832290624714334993812111228876927501848766224885363439534844304635205290155102644689388281018248057599 | ||
n = 109773001979060500556771371722004589561407766472974181720301601504038097307183054327771414952722378616410690575654297998413723333283006388834687489519816814313970602740394095998728900971165525449666220812031401613319432338039749036919424709291358478655637030475075112370396605574403821950130705107292457546429 | ||
d = owiener.attack(e, n) | ||
|
||
if d is None: | ||
print("Failed") | ||
else: | ||
print("Hacked d={}".format(d)) | ||
|
||
``` | ||
|
||
```output1: | ||
Hacked d=18381494291594953056777362005644517143007478836617600171835005250178126922947 | ||
``` | ||
|
||
#### Decrypting the message | ||
```rsa_solve.py | ||
def rsa_decrypt(c, d, n): | ||
# Decrypt the message using RSA decryption formula: m = c^d mod n | ||
m = pow(c, d, n) | ||
return m | ||
|
||
def int_to_bytes(n): | ||
return n.to_bytes((n.bit_length() + 7) // 8, 'big') | ||
|
||
def main(): | ||
# Integer values of c, d, and n | ||
d = 18381494291594953056777362005644517143007478836617600171835005250178126922947 | ||
e = 6251728305055461128215101113791542074487626873355761684912706796947820318045025894574010369655098754702916182673592159941529716341070091220295342244632166182377719507598162603755176681008223777597129409701832290624714334993812111228876927501848766224885363439534844304635205290155102644689388281018248057599 | ||
n = 109773001979060500556771371722004589561407766472974181720301601504038097307183054327771414952722378616410690575654297998413723333283006388834687489519816814313970602740394095998728900971165525449666220812031401613319432338039749036919424709291358478655637030475075112370396605574403821950130705107292457546429 | ||
ct = 69065966519105922162577567455261680573815854481710157074477507437933398566834762071577601999308205592512262422922008600362846112148013817314127895526875891430442404421013800492060589763419224572960632800381314756724351337523874069656512900871727433364755041357985429952615910953420906893665747562715489326060 | ||
|
||
# Decrypt the message | ||
decrypted_int = rsa_decrypt(ct, d, n) | ||
decrypted_bytes = int_to_bytes(decrypted_int) | ||
|
||
# Print the raw bytes in hexadecimal format | ||
print(f"Decrypted message (hex): {decrypted_bytes.hex()}") | ||
|
||
# Attempt to convert bytes to string (assuming the message is in UTF-8) | ||
try: | ||
decrypted_message = decrypted_bytes.decode('utf-8') | ||
print(f"Decrypted message (UTF-8): {decrypted_message}") | ||
except UnicodeDecodeError: | ||
print("Decrypted message is not valid UTF-8") | ||
|
||
if __name__ == "__main__": | ||
main() | ||
``` | ||
|
||
```output2 | ||
Decrypted message (hex): 02da0cfd3c2fa076d1642cc6d70ff8fea57fad89223396b4f3f732ece93da360b50d8261d13c6756cc67063eaf7f3b56b01f91a318095561b7fceda5dff9c9e4b10b47896124e69f09cb2f9907a63b6027e2a0753aa86ee833b39e6ebc403042b7004550547b5368616d69725f69735f75705f325f736f6d657468696e677d | ||
Decrypted message is not valid UTF-8 | ||
``` | ||
|
||
For some reason or other, the decrypted message, when decoded in UTF-8, was invalid strings, but we still figured we should let Cyberchef take a whack at it - and voila, after some gibberish/invalid UTF-8, the flag was visible: | ||
|
||
![cyberchef - flag](1_cyberchef.png) | ||
|
||
In addition to the flag itself, we also get the reference to the missing party of the trio behind the encryption algorithm. | ||
|
||
### Tools Used | ||
- Python | ||
- owiener package | ||
- Cyberchef | ||
|
||
### Conclusion | ||
By leveraging the Wiener Attack, we successfully decrypted the RSA-encrypted message. This challenge highlighted the importance of choosing secure parameters for RSA encryption to avoid such vulnerabilities. |
Binary file added
BIN
+135 KB
writeups/forensics/Honey, I shrunk the skids/dragonslayerz/0_wireshark_files.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+174 KB
writeups/forensics/Honey, I shrunk the skids/dragonslayerz/1_gpedit_msc.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+360 KB
writeups/forensics/Honey, I shrunk the skids/dragonslayerz/2_hexdata.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+31.4 KB
writeups/forensics/Honey, I shrunk the skids/dragonslayerz/3_auth_req.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+12.4 KB
writeups/forensics/Honey, I shrunk the skids/dragonslayerz/4_flagdisk.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
99 changes: 99 additions & 0 deletions
99
writeups/forensics/Honey, I shrunk the skids/dragonslayerz/README.md
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
# Honey, I shrunk the skids | ||
Writeup by slayyy @ Dragonslayerz | ||
|
||
__Lesson learned:__ Don't trust the AI. | ||
|
||
#### Note | ||
This was unfortunately not completely finished until after the CTF was over. | ||
|
||
### Introduction | ||
We are presented with a zip containing two files | ||
- FlagDisk.vhdx | ||
- shrunk.pcap | ||
|
||
The challange points in the direction of a ransomware of a disk, and to decrypt the VHDX by finding information within the PCAP file. | ||
|
||
|
||
### Solution steps | ||
Opening the PCAP in Wireshark and doing a quick-and-dirty `File --> Export Objects --> HTTP..` is nice to us for once, and shows some interesting options: | ||
|
||
![Wireshark screenshot showing exportable objects](0_wireshark_files.png) | ||
|
||
As seen in the screenshot, `gpedit.zip` is downloaded from windowsupdater[.]com, while the posting of the `updatelog` is towards IP 192[.]186[.]77[.]136. | ||
|
||
The two files exported were `updatelog` and `gpedit.zip`. The first was a simple text file, containing single string `upgrade=REVTS1RPUC01OUMxQzNECTQzOTA2Ljgz`. | ||
|
||
Base 64 decode of the string gives the following: `DESKTOP-59C1C3D 43906.83`, of which one might assume this is the computer name in question. | ||
|
||
The gpedit archive, named such that it might imply relation to the native Group Policy editor, contains a single `.msc` file, for use in Microsoft Managment Console. | ||
|
||
At a first glance, it might seem plausible enough | ||
|
||
![Top of the gpedit.msc file](1_gpedit_msc.png) | ||
|
||
but further down it we see huge chunk of URL encoded (or HEX) data. | ||
|
||
![Gibbberish?](2_hexdata.png) | ||
|
||
While this could possibly be a benign use case, see the Base64 encoded icons for instance, it is worthy of another look. | ||
|
||
By doing URL decode of the string in Cyberchef, we get a XML file containing a VBScript. | ||
|
||
The VBScript contains a function `Stream_StringToBinary` that converts a given text string into its binary representation using the ADODB.Stream object. | ||
|
||
Furthermore, we see references to the IP previously seen related to `updatelog`. Backtracking the variables, we see that it file consists of the following | ||
|
||
``` | ||
upgrade=" & oNode.Text | ||
``` | ||
|
||
|
||
where `oNode.Text` in turn is `computerName & vbTab & seed`. | ||
|
||
|
||
`vbTab` is the tab character for use in strings, meaning that the number found when b64 decoding the string from the file before (`43906.83`), indeed is the seed used for generating the encryption key. | ||
|
||
The seed is used within the "randomization" part of the script for generating the encryption key. However, it sets the `Rnd(-1)` which according to documentation ([ref](https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/rnd-function)) states it shall give "The same number every time, using Number as the seed.". | ||
|
||
This means it should be possible to recover the enryption key based on the seed we got, and a modification of the key generation function in the following way: | ||
|
||
|
||
```vbscript modified to print out the encryption key | ||
Dim strRandom | ||
characters = "THEQUICKBROWNFOXJUMPSOVERTHELAZYDOG!@#$&*-+=_;0123456789thequickbrownfoxjumpsoverthlazydog" | ||
|
||
' Generate the seed | ||
Dim seed | ||
seed = 43906.83 'From the b64 decode of updatelog from before | ||
Rnd(-1) | ||
Randomize seed | ||
|
||
' Generate the random string | ||
For i = 1 To 64 | ||
randomNum = Int(Len(characters) * Rnd(2)) | ||
randomChar = Mid(characters, randomNum + 1, 1) | ||
strRandom = strRandom & randomChar | ||
Next | ||
|
||
' Print the generated random string (encryption key) | ||
WScript.Echo "Generated Random String: " & strRandom | ||
``` | ||
|
||
This returns the following output, which should indeed be the encryption key: | ||
|
||
```output1 | ||
C:\Users\Administrator\Desktop>cscript.exe script.vbs | ||
Microsoft (R) Windows Script Host Version 5.812 | ||
Copyright (C) Microsoft Corporation. All rights reserved. | ||
Generated Random String: _tfeTIO$*Vy##f@GyRfDEJvRvNerHHDrE=GHr0CRFgSX3VYD4koa-LUU&OTDe;rb | ||
``` | ||
|
||
Mounting the vhdx in Kali makes it available in Thunar File manager, where it can be mounted. Upon mounting it requests a passphrase, which should be our encryption key | ||
|
||
![AuthenticationRequired](3_auth_req.png) | ||
|
||
Entering the key seems to decrypt the disk, and indeed we can now open the `flag.txt` | ||
|
||
![FlagDisk](4_flagdisk.png) | ||
|
||
The `flag.txt` indeed contains the flag: `EPT{it_works_the_machine_works!}`. |