Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Immediately (Thanks Tom from RTCP!) I spotted that it was hexahue, but it was moving at too fast a pace to transcribe manually.
So, I split the video into frames, and just manually converted the hexahue to text.
(had to guess a couple of things here and there, but it was mostly fine)
Image splitter: https://www.dvdvideosoft.com/download.htm?fname=FreeVideoToJPGConverter.exe&ls=topButton (downloads on visit) Hexahue decoder: https://www.boxentriq.com/code-breaking/hexahue
If we sort the images by size, we can see the 30th is larger.
So i performed standard steg on it and found the password for the pdf in bit plane red 0: covid19
Looking inside the pdf, we have an interesting line of text at the bottom.
this looks like the twitter hidden messages thing, so i used extractpdf.com to get the bytes of the pdf out (after disabling the password), and then used https://holloway.nz/steg/ to get the flag. (i had to do a bit of guessing)
Anyway, continuing on from the previous one.
This one has something to do with unremovable malware. So like, it also said that restarting the computer doesn't remove it so I googled startup tasks and where in a registry this would be.
The registry is SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\
. And if you go into SpecialAccounts\Shell
you find the malware file that starts up.
Connect to the server. Besides exiting, there's two options - get the public key, and encrypt data.
Let's get the publickey and parse it.
the output is e = 3 and n = 19180711545893176513037550390323379574821852830665661812056678865741809891967598330424432450065638550340708416772232861627803383996685973692319978144111094705678356718069839745329804369923049623077146724976343425793942969144731442443607177966505595110345695314223998207352543996470777991272166737723490287258351016452097039979125039319504321174407700539531877444075872453220474913463319033875264101011295681676774076367210997858399851393634010112304767318681335454946488666538950765836709367621997962434256967765320251658524109362889423421160554230180542246491892887129152380892721807921025298941063392821275387956851
Then, there's encrypt. Our message is appended to the flag, then encrypted using the publickey. This makes it vulnerable to franklin-reiter's related message attack, in which RSA with low exponents can be attacked if you have two messages, C1 and C2, such that dec(C1) = f(dec(C2)) where f is a function of form f(x) = ax + b, and b and a are non-zero. If we ask the server to encrypt an empty message(thus getting the encryption of the flag), and then 'A', we now have an encryption of the flag(lets call this C2) and an encryption of the flag + 'A', which is 256*flag + 0x41. So.. We now have the encryption of the flag, and the encryption of f(flag), where f(x) = 256x + 65
Using this, we can execute franklin reiter's related message attack. I copied some sage code and included variables. You can run the sage code on the sage cell server, https://sagecell.sagemath.org/. The output will be the hex encoding of the message, which decodes to "RSA is secure and all but the only thing I want to say is
I didn't actually do any analysis but here we go
So let's review the source code.
It has a count variable that cycles from 1-4. It essentially grabs chunks of 4 of the message, then runs some base on it, then runs bytes_to_long, then prints it with the end being |
so essentially we get |number|number|number etc. First step is to convert these numbers back to bytes to get the pure encoded data. From there, we know it cycles from 1-4 on the count variable. 1 is b64, 2 is b32, 3 is b85, 4 is hexlify. We can write a simple loop to decode the data and get G00DTH3_FIRST_P4RT_I5_D0N3_HER3_I5_4_F14G_F0R_Y0U_H4RD_W0RK=_zh3r0{f4k3_f14g}. It also sends the key of encryption for the second part(the flag), H3ll0_Th3r3_Fir5t_5t4g3_i5_d0n3_n3xt, as a number generated by bytes_to_long.
Now, for the final decryption. The program has a table. The table looks complicated, but it actually just maps one pair of hex characters to another pair of hex characters. It's in the form,
{'hexchar': {'secondhexchar': 'newpair', 'secondhexchar': 'newpair'.....}
I wrote a small loop to make this into a "better" table, which was just {pairofchars : newpair}
It thens splits the flag into groups of 4 chars, and hexlifies each group. Then, it runs a substitution as-per this table a random number between 2-4 times. Then, the key is split into hexlified groups of 4, and the string hex values of the finished flag list and the key list are xored to produce the final ciphertext. I simply reversed this step by step(as we get the key), and then ran a bruteforce of the amount of substitutions there was. I ran this, and one of the outputs was zh3r0{Y0u_4r3_4_v3ry_G00d_4nalys3r!} Script below.
Download the file, open it in Autopsy etc.
Now based on the brief, this challenge has something to do with timezones, and how malware has changed it to something.
So after doing some googling about where timezones are stored in windows filesystems.
I found a registry key HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet
< (in the case of this challenge its ControlSet001)\Control\TimeZoneInformation (access through C:\Windows\system32\config\system) which leads to the flag of.
So download the jpg.
Run exiftool and the author data is base62 encoded.
Decode it to get itrolledyou which you can run on steghide to get a zip.
Unzip dat zip bitch and you find a .png.
Run zsteg and you'll get 30:aDutCu4gwUtnqdVuhLUL6jFueSgRFi
. No idea what the 30: is but remove that and decode the remaining thing.
Its base58 encoded. After that you get the flag but replace the 'o's with '0's.
This one's a whirlwind, and it's a bit complex, so I'll lay it out in parts.
Lots and lots of functions. The structure of the execution of the program is a little nested. Honestly, it doesn't matter much or at all. There are two functions we must focus on - ok, and finallyyouhelpedme
Function: ok. This function has a global counter, on the sixth time it runs, we get an input. It reads 0x29 bytes into rbp-0x20 - giving us full control over RBP and partial control over the return address. By partial, I mean one byte. This is enough to send the binary to 0x40017XX, as the return address saved begins with 0x40017 and we can overwrite one byte of it. What can we do with this?
Function: finallyyouhelpedme. It has two inputs. One that was irrelevant for what I did, but probably useful for other methods. It read into a global variable. The second one is a proper buffer overflow - 0x40 bytes read into rbp-0x20. This gives us control over saved RBP, and enough to make a 24-byte ROP chain.
finallyyouhelpedme is never called - we must redirect ok's return address into it. We can overwrite the first byte of the return address with 0x1f, sending it into the 4th instruction of finallyyouhelped me, where our input begins. I jumped here so that I didn't have to deal with stack alignment, nor things messing up between rbp and rsp.
Now what? a 24-byte ropchain is enough to do poprdi + got address + plt address and leak a libc address, but we cant return back to a function for another input after that.
Wait! The input is at rbp-0x20. 0x20 is 32 - that's exactly enough to do poprdi + got address + plt address + address of finallyyouhelpedme. Perfect!
What we'll do here is called a stack pivot. We can change the location of rsp via a leave ; ret gadget in order to relocate the stack and force the program to start popping ret addresses from somewhere else.
In order to do that, we need to know whereabouts our input is. I accomplished this by controlling saved RBP. Let's think back to our first input in ok. We get full control of saved RBP here, and this will be the RBP that gets passed into finallyouhelpedme(as we ret into the instruction after the whole push rbp;mov rbp,rsp mumbo jumbo). Thus, we can force the stack into a specific place. As there's no PIE, the segment mapped RW is constant, so we can set it somewhere int here.
Ok, back to before. We force RBP into a known place inside of a RW segment, so we know exactly where our input is. Now, we can send:
rop chain + address of input - 8 + leave ret
leave will set rsp to rbp, then pop rbp off the stack. Setting it to input - 8 means some random value will be popped off.
In order to stop problems with this later, we ret straight into the beginning of the finallyyouhelpedme function. As this moves rbp up to rsp, it causes anything we might've messed up in the stack(like that random rbp value...) to be automatically fixed.
Our rop chain will then be poprdi + got address + puts@plt + finallyouhelpedme address
Now, we will receive a libc address(write, specifically) and another input. We can calculate the libc base off of this, and use the classic payload - system("/bin/sh").
Final exploit:
Send 0x20 bytes of junk + address in RW segment + 0x1f
Send poprdi + got address + puts@plt + finallyyouhelpedme address + address of input - 8 + leave;ret gadget address
Receive libc address. Calculate base. Send dummy input(first input, useless) then send 0x28 bytes of junk(rbp doesnt matter anymore) + poprdi + /bin/sh address + system address
Script below.
This time though it wants you to find the origin of the malware that changed the time zone shid.
Since the challenge had IE I had a feeling it had stuff to do with Internet Explorer and URL history.
But looking through the most obvious files like the History folder had nothing sus.
So I had to google like where applications are stored in a registry file (this is because I thought that malware was downloaded and I had to look for a file instead).
I found that NTUSER.dat in the user's directory had this stuff in it.
But looking through I found an Internet Explorer registry key and thought I'd try looking through that stuff again and to my surprise I found a flag in NTUSER.dat\Software\Microsoft\Internet Explorer\TypeURLs\url11. UwU OwO.
Simple ret2win exploit.
It calls read on rbp-0x20, reading 0x38 bytes.
This is enough for 16 bytes after RBP.
We simply send 0x28 junk bytes + ret gadget + win_win function address(win_win is a function executing cat flag.txt whilst the ret gadget is for stack alignment)
For some reason I had to put an interactive session just when I connected to the server and hit control c so that the exploit continued in order for it to work...
Download the file, run zsteg on it and you'll get a pastebin link. https://pastebin.com/hvgCXNcP
.
Visit that and you'll find base64 text that decodes into a zip file.
Save the zip file and open it but its password protected.
So run zip2john and get the hash and dictionary attack it with rockyou.txt
You'll get a password of kitkat.
After catting flag.txt run a ROT47 decryption on it and you get.
Download the file, open it in Autopsy etc.
Now based on the brief, this challenge has something to do with timezones, and how malware has changed it to something.
So after doing some googling about where timezones are stored in windows filesystems, I found a registry key HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet
< (in the case of this challenge its ControlSet001)\Control\TimeZoneInformation (access through C:\Windows\system32\config\system) which leads to the flag of:
You can add commands, edit commands, run commands. Running commands means system will be run on it. Our goal will be to run /bin/sh, and pop a shell. If we try to add a command with value /bin/sh, the program will not allow us. However, there are no checks upon command edits. So we can create a command, add whatever we want, then edit the command and put /bin/sh inside. Then run the command. You'll be dropped into a shell, cat flag.txt Flag: zh3r0{the_intended_sol_useoverflow_change_nextpointer_toFakechunk_in_bssname}
So uh use sherlock (https://github.com/sherlock-project/sherlock) to find that the guy has a livelib.
https://www.livelib.ru/reader/al3xandr0vich1van
Go here to see the image.
This is pigpen, we decode it to get HTTPS TWITTERCOM HAVEVISIT
We go to twitter @HaveVisit to get the flag.
So download the file.
Unzip it and notice the challenge name is Snow so use stegsnow.
Once extracted you get a file called chall.txt which presumably you use stegsnow on.
However theres hidden directories. If you go down it you find .flag.txt
which is a fake flag but if you go further you find .secret.txt
which is the password.
So run stegsnow -C -p "welc0me_to_zh3r0_ctf" chall.txt
and you get the flag.
Looking at the ct file, it starts with "gAAAAAB"
This reminded me of the HTB challenge Decode Me!!!, which used fernet decryption as the first step.
Key1 and Key3 were useless, but applying ROT47 to key2 with key 47 gave us:
key: iQZijGdoX0hepv2wnFZOUsTWU-v6xyGWyqSan_p75CE=
Here's another key for the encryption.
if you are a good cryptographer you can identify the common symmetric encryption.
giving us our key for fernet.
Then, I just plugged the CT and key into a fernet decoder (https://asecuritysite.com/encryption/ferdecode) to get the flag.
nmap all ports to see port 4994 is open, just nc to it to get flag
Going back to port 324 (ftp)
the flag is in .../.../.flag
curling port 22 robots.txt gives you a string in base58, decode to get /clue3349203.txt, curl that to get a lot of jsfuck, decode that to get an employee id, and then use that on port 4994 to get the flag
if we scan port 324, we can see it is an ftp server, which allows anonymous login.
ls -a ing gives us a ... dir (wow thanks hq), and then cding into it and ls -a ing again gives us a .stayhidden file. reading this gives us another employee id, which we can use to login to port 4994 again.
nmap, see http port on port 22, curl it to get flag
From listening to the audio, I realised that it was DTMF tones immediately. (The website I usually use: http://www.dialabc.com/sound/detect/index.html was broken, so I had to do it another way, using a weird tool or somethin and then manually correct stuff with audacity, but lets pretend it worked to make things simple) Once we decoded the tones, we got a string of characters, which was 'A288439640A3A140997B8A9945987B8844838B85847B419298407B447B978186437B99454192877B5870655AA5' From the title, we can guess that this is base12, and since there was a gap between each 2 tones, I guessed that it was just each 2 tones was the base12 of a character. I wrote a short python script to convert it to the flag.