Siiiopenctf

Forensics

Archiveception

This suspicious file seems to be hiding a secret code in it, but every time we attempt to open it, we just end up back where we started! It's weirdly named "start layer", but we can't figure out what that means. Find the flag to escape from this never-ending nightmare!

start_layer.gz

Answer: uscg_open{d0wNw4rd_15_7h3_0n1y_w4y_f0rw4rD}

Metadata

There's something strange about this image's metadata...

thumb.jpg

I started by running exiftool thumb.jpg and got the following output:

ExifTool Version Number         : 11.88
File Name                       : thumb.jpg
Directory                       : .
File Size                       : 735 kB
File Modification Date/Time     : 2023:06:03 10:10:36-04:00
File Access Date/Time           : 2023:06:03 10:10:44-04:00
File Inode Change Date/Time     : 2023:06:03 10:10:38-04:00
File Permissions                : rw-rw-r--
File Type                       : JPEG
File Type Extension             : jpg
MIME Type                       : image/jpeg
JFIF Version                    : 1.01
Exif Byte Order                 : Big-endian (Motorola, MM)
X Resolution                    : 1
Y Resolution                    : 1
Resolution Unit                 : None
Y Cb Cr Positioning             : Centered
Compression                     : JPEG (old-style)
Thumbnail Offset                : 202
Thumbnail Length                : 1321
Image Width                     : 1380
Image Height                    : 1920
Encoding Process                : Baseline DCT, Huffman coding
Bits Per Sample                 : 8
Color Components                : 3
Y Cb Cr Sub Sampling            : YCbCr4:2:0 (2 2)
Image Size                      : 1380x1920
Megapixels                      : 2.6
Thumbnail Image                 : (Binary data 1321 bytes, use -b option to extract)

Following the guidance on the last line, I ran exiftool ./thumbs.jpg -b, which gave the following output (truncated):

11.88thumb.jpg.7525322023:06:03 10:10:36-04:002023:06:03 10:10:44-04:002023:06:03 10:10:38-04:00664JPEGJPGimage/jpeg1 1MM111162021321138019200832 21380 19202.6496����JFIF��QExiftool's creator saw no use for the example, but notes in the manual page that a user could "add a comment to an embedded thumbnail image using the command:
exiftool a.jpg -thumbnailimage -b | exiftool -comment=wow - | exiftool a.jpg -thumbnailimage'<=-'
I saw a use for it. Here's your flag: flag{334_shards_of_hail_fall_ominously}

Answer: flag{334_shards_of_hail_fall_ominously}

Word

A student hid some information within their essay document- we need to find it!

challenge.docx

Opening the Word document doesn't show much of interest, with the exception of an image that won't load. So since it's a .docx, I extracted the contents with unzip challenge.docx and then ran exiftool on the image:

$ exiftool word/media/image1.png
ExifTool Version Number         : 11.88
File Name                       : image1.jpg
Directory                       : .
File Size                       : 19 kB
File Modification Date/Time     : 1979:12:31 23:00:00-05:00
File Access Date/Time           : 2023:06:03 10:15:32-04:00
File Inode Change Date/Time     : 2023:06:03 10:15:32-04:00
File Permissions                : rw-rw-r--
File Type                       : JPEG
File Type Extension             : jpg
MIME Type                       : image/jpeg
JFIF Version                    : 1.01
Resolution Unit                 : inches
X Resolution                    : 96
Y Resolution                    : 96
Exif Byte Order                 : Big-endian (Motorola, MM)
XP Comment                      : USCG{parliamentary_carpet}
Padding                         : (Binary data 2060 bytes, use -b option to extract)
Image Width                     : 547
Image Height                    : 547
Encoding Process                : Baseline DCT, Huffman coding
Bits Per Sample                 : 8
Color Components                : 3
Y Cb Cr Sub Sampling            : YCbCr4:2:0 (2 2)
Image Size                      : 547x547
Megapixels                      : 0.299

Via the XP Comment, we get the flag: USCG{parliamentary_carpet}. We can also fin dthat via the exiftool -b command, same as the last challenge.

Answer: USCG{parliamentary_carpet}

Dvorak's Secret

The sneaky Dwarf Dvorak has begun uploading secrets onto the internet in an unconventional way. See if you can decypher their message found in the link below

https://youtu.be/MoeMU9e0_wU

I just so happened to already be familiar with this technique thanks to my friend Daniel Roh, which is on GitHub here. Commands:

git clone https://github.com/DvorakDwarf/Infinite-Storage-Glitch
cd Infinite-Storage-Glitch
sudo docker build -t isg .
sudo docker run -it --rm -v ${PWD}:/home/Infinite-Storage-Glitch isg cargo build --release

Reverse Engineering

L33tbin

The first thing I did was obviously strings l33tbin, which in this case was enough to solve it!

Answer: uscg{uscg_is_the_goat}

lol

lolflag.lol

lol

Starting off with strings lolflag.lol -n 7 made it obvious that lolflag.lol is a jacked-up PDF file, because of several unaffected artifacts (in order, spread throughout the output):

iTXtXML:com.adobe.xmp
<?xpacket be

ib:Ads>
 </rdf:Description>
 <rdf:Description rdf:about=''
  xmlns:dc='http://purl.org/dc/elements/1.1/'>
  <dc:title>
   <rdf:Alt>
    <rdf:li xml:lang='x-default'>Copy

outhor>Rachael Skillman</pdf:Author>
 </rdf:Description>
 <rdf:Description rdf:about=''
  xmlns:xmp='http://ns.
iof USCG SIII - Open Kick-Off - Day of Slides - USCG | SIII Founding Partners</rdf:li>
   </rdf:Alt>

adobe.com/xap/1.0/'>
  <xmp:CreatorTool>Canva</xmp:CreatorTool>
 </rdf:Description>
</rdf:RDF>
</x:xmpmeta>
<?xpacket end='r'?>,

='http://ns.attribution.com/ads/1.0/'>
  <Attrib:Ads>
   <rdf:Seq>
    <rdf:li rdf:parseType='Resource'>
     <Attrib:Created>2023-06-02</Attrib:Created>
     <Attrib:ExtId>7090429

' id='W5M0MpCehiHzreSzNTczkc9d'?>
<x:xmpmeta xmlns:x='adobe:ns:meta/'>
<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>
 <rdf:Description rdf:about=''
  xmlns:Attrib

1-55a3-472a-a139-a52543c5072f</Attrib:ExtId>
     <Attrib:FbId>525265914179580</Attrib:FbId>
     <Attrib:TouchType>2</Attrib:TouchType>
    </rdf:li>
   </rdf:Seq>
  </Attr

qc:title>
 </rdf:Description>
 <rdf:Description rdf:about=''
  xmlns:pdf='http://ns.adobe.com/pdf/1.3/'>
  <pdf:A

There was no super interesting strings output from lol, just things like File is longer than expected, final pointer may be missing., Check failed, and flag.lol, which indicates that the binary should theoretically reassemble the lolflag.lol file into flag.lol.

Unfortunately, when attempting to run the binary, I got the same issue that has afflicted me across many of the pwn and rev challenges this go-around:

./lol: error while loading shared libraries: libcrypto.so.3: cannot open shared object file: No such file or directory

I tried troubleshooting with find / -name libcrypto.so.3 then updating the env var to export LD_LIBRARY_PATH=/snap/telegram-desktop/4806/usr/lib/x86_64-linux-gnu/libcrypto.so.3:$LD_LIBRARY_PATH, but the issue persisted.

I tried the solution described here, which involved manually downloading the libcrypto.so.3 file and placing it in the /usr/lib64 directory, but that didn't work either. I realized that solution may have failed because of lib64, so I tried the same steps with lib and we got a new error!

Unfortunately, even though I figured out how to upgrade my version of libc6, Zorin does not support that version, so I can't run it. So I decided to spin up an Ubuntu 22.04 VM so I can!

Web

The Try Zone

https://uscybercombine-try_zone_challenge.chals.io/

The URL loads a page that looks like the following:

try_zone.png

Looking at the form code, we can see that the default onsubmit handler is overwritten to the following:

onsubmit="event.preventDefault(); authenticate();"

Looking into the authentication.js file, we can see that the code is obfuscated:

(function(_0x118b98, _0x335091) {
    var _0x4be5ec = a0_0x427a
      , _0x22668d = _0x118b98();
    while (!![]) {
        try {
            var _0x284930 = parseInt(_0x4be5ec(0x168)) / 0x1 + -parseInt(_0x4be5ec(0x16d)) / 0x2 * (-parseInt(_0x4be5ec(0x174)) / 0x3) + -parseInt(_0x4be5ec(0x176)) / 0x4 + parseInt(_0x4be5ec(0x169)) / 0x5 + -parseInt(_0x4be5ec(0x16c)) / 0x6 * (parseInt(_0x4be5ec(0x16e)) / 0x7) + parseInt(_0x4be5ec(0x173)) / 0x8 * (-parseInt(_0x4be5ec(0x170)) / 0x9) + parseInt(_0x4be5ec(0x171)) / 0xa;
            if (_0x284930 === _0x335091)
                break;
            else
                _0x22668d['push'](_0x22668d['shift']());
        } catch (_0x3d73e0) {
            _0x22668d['push'](_0x22668d['shift']());
        }
    }
}(a0_0x202b, 0x62c4e));
function authenticate() {
    var _0x3199d5 = a0_0x427a
      , _0x316b93 = document[_0x3199d5(0x16f)](_0x3199d5(0x175))[_0x3199d5(0x167)];
    _0x316b93 === _0x3199d5(0x16a) ? alert(_0x3199d5(0x16b)) : alert(_0x3199d5(0x172));
}
function a0_0x427a(_0x156085, _0x9e0729) {
    var _0x202b2d = a0_0x202b();
    return a0_0x427a = function(_0x427a41, _0x15227a) {
        _0x427a41 = _0x427a41 - 0x167;
        var _0xd1a30 = _0x202b2d[_0x427a41];
        if (a0_0x427a['eUCHSe'] === undefined) {
            var _0x50c8f8 = function(_0x316b93) {
                var _0x204747 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';
                var _0x4c5916 = ''
                  , _0x305af8 = '';
                for (var _0x2ba3d9 = 0x0, _0x41150e, _0x20834c, _0x1f1f98 = 0x0; _0x20834c = _0x316b93['charAt'](_0x1f1f98++); ~_0x20834c && (_0x41150e = _0x2ba3d9 % 0x4 ? _0x41150e * 0x40 + _0x20834c : _0x20834c,
                _0x2ba3d9++ % 0x4) ? _0x4c5916 += String['fromCharCode'](0xff & _0x41150e >> (-0x2 * _0x2ba3d9 & 0x6)) : 0x0) {
                    _0x20834c = _0x204747['indexOf'](_0x20834c);
                }
                for (var _0x26c4e4 = 0x0, _0x432f0a = _0x4c5916['length']; _0x26c4e4 < _0x432f0a; _0x26c4e4++) {
                    _0x305af8 += '%' + ('00' + _0x4c5916['charCodeAt'](_0x26c4e4)['toString'](0x10))['slice'](-0x2);
                }
                return decodeURIComponent(_0x305af8);
            };
            a0_0x427a['NoXrAA'] = _0x50c8f8,
            _0x156085 = arguments,
            a0_0x427a['eUCHSe'] = !![];
        }
        var _0x415787 = _0x202b2d[0x0]
          , _0x211fcd = _0x427a41 + _0x415787
          , _0x5d78bf = _0x156085[_0x211fcd];
        return !_0x5d78bf ? (_0xd1a30 = a0_0x427a['NoXrAA'](_0xd1a30),
        _0x156085[_0x211fcd] = _0xd1a30) : _0xd1a30 = _0x5d78bf,
        _0xd1a30;
    }
    ,
    a0_0x427a(_0x156085, _0x9e0729);
}
function a0_0x202b() {
    var _0x1041cd = ['ndG2mZu1rgXQs3rn', 'mtq3ntG3mhbOBMXJwa', 'C2L4BMf0Aw9UC2nOyw1WAw9UCW', 'DxnJz3TJBdeZBNrFCZfKm19HDxrOx2i0zf8Xzdm0Fq', 'mtm4DNHuCxPo', 'mJi2mZrrC1zkzgm', 'nZGZnZLdDLnSEe0', 'z2v0rwXLBwvUDej5swq', 'mJmYmtfuzK5Qvui', 'mJe5mdu3meXPzg5eCq', 'u29YCNKSihrOyxqGAxmGBM90ignVCNjLy3qUifrswsbHz2fPBIbYDwDNzxiH', 'odCYyvLdzM9y', 'm1nRB0zdzq', 'CgfZC3DVCMq', 'mJC0odeYBKDZswPs', 'DMfSDwu'];
    a0_0x202b = function() {
        return _0x1041cd;
    }
    ;
    return a0_0x202b();
}

Doing some manual reworking of the code, just going through and renaming the variables to more sensible names and removing duplicate logic, this is what I can boil it down to:

// Just used the debugger to look at the var in the function breakpoints

Answer: uscg{cl13nt_s1d3_auth_b4d_1d34}

Rogue AI

Can you catch him before it is too late?
https://uscybercombine-rogue_ai_challenge.chals.io

The send.js file has the following contents:

send=function(event){
	if (event.keyCode==13 || event.button==0){
		msg=$('#message').val()
		if (msg.startsWith("/key"))
		{
			socket.emit('apiKey', msg.substring(5, msg.length));
		}
		if (msg!="" && !msg.startsWith("/key"))
		{
			socket.emit('msgOut', msg);
		}
		else
		{
			alert("Empty Text Field!")
		}
		$('#message').val('');
	}
};

function encodeHTML(s) {
    return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/"/g, '&quot;');
}

It is called by the button onclick="send(event)" for the send button, and the socket is set up to output the HTML from the socket:

let myDiv = document.getElementById("msg_holder");
socket.on( "msgIn", (user,data)=>
{
  myDiv.innerHTML+="<p class='user'>"+encodeHTML(data)+"<br><b>"+user+"</b></p><br>";
});
socket.on( "aiOut", (user,data)=>
{
  myDiv.innerHTML+="<p class='ai'>"+data+"<br><b>"+user+"</b></p><br>";
});

jQuery 3.7.0 and socket.io 4.5.0 are dependencies of the site.

Whenever I enter something like /key thisismykeyexample in the textbox, I get the alert message for an empty text field.

...

Pwn

https://siiiopenctf.uscybergames.com/challenges

Who's that ascii mon?

Play a quick game of who's that ascii mon where we show you an ascii String of a pokemon and you have to guess them all right! Careful to Format your answers right otherwise you'll fail. You only get one guess per ascii mon so use it carefully.

Note: Flag format will be flag{...}

0.cloud.chals.io:30647

At first I tried actually guessing the correct answer, which worked via Googling and searching this site. However, on the third guess, this was the "Pokemon" I was given:

   ;));:34(&$
   ///-2(€~#
   []~}#^?,.
   &@\~~#|&&
)$&\}#^€'kk#
&$"\__|#}?!•
€£•*>#%%.&%%
<|{}~<¥**+!!!

Since that is obviously not a Pokemon, and since this is a pwn challenge, there has to be a different method of approach.

shapes

Play a quick game of what's that shape where we show you some ascii art of a shape and you have to guess them all right! Careful to Format your answers right otherwise you'll fail. You only get one guess per shape so use it carefully.

Note: Flag format will be flag{...}

0.cloud.chals.io:30167

Running strings gives us a few useful tidbits:

  • Diamond
  • next_level
  • HoneyComb
  • ask_to_play
  • pwn_shapes_chal.c

As well as one BIG section that contains what appears to be the main logic:

Error: Could not open file.
HoneyComb
Diamond.txt
Cow.txt
Welcome to Name That Shape!
Would you like to play? (Yes/No):
Okay, maybe next time!
Let's play!
Invalid input, please enter either Yes or No.
Are you ready for the next level? (Yes/No):
Guess that shape!
Enter your guess:
You got it!
Diamond
Correct, here's your flag!
Sorry, I couldn't find it but maybe next time.
I still couldn't find it. Better luck next time.
Sorry, that's wrong. Try again next time.
;*2$"
GCC: (Ubuntu 11.3.0-1ubuntu1~22.04.1) 11.3.0

Unfortunately, the game is rigged! I entered the correct answers in order (HoneyComb, Diamond, Cow), and this was the response:

Enter your guess: Cow
CowCorrect, here's your flag!
Sorry, I couldn't find it but maybe next time.

The program doesn't exit or time out after that last response, it seems to just hang. I tried entering some commands, but no response. What's interesting is that our input is returned on this one, which may be the vulnerability.

Crypto

The First Digram Substitution Cipher

You've successfully intercepted your enemy's message! However, some of the key matrix got corrupted. Determine the missing letters in the key and decipher what the encrypted message entails. Your flag is the decrypted message in all caps with underscores between the words. Example - If the decrypted message is carrotsareawesome, the flag would be uscg{CARROTS_ARE_AWESOME}

corruptedkey.pdf

secretMessage.txt

Now, let's use this information to complete the missing characters in the key matrix:

C,H,?,R,?,E,S,W,T,O,?,B,D,?,?,I,J,?,?,P,?,?,?,?,?

We can start by examining the positions of the known letters in the message and identifying any repeated patterns. Looking at the positions of "R" and "W" in the encrypted message, we notice that they correspond to the 4th and 8th characters, respectively. This indicates that the missing character in the 5th position (between "R" and "E") should be "J" because it aligns with the known positions of "J" in the key matrix.

C,H,?,R,J,E,S,W,T,O,?,B,D,?,?,I,J,?,?,P,?,?,?,?,?

Next, let's consider the position of "C" in the message, which is the 1st character. Looking at the key matrix, we see that "C" aligns with the 1st column. Therefore, the missing character in the 3rd position (between "H" and "R") should be "N" because it aligns with the known positions of "N" in the key matrix.

C,H,N,R,J,E,S,W,T,O,?,B,D,?,?,I,J,?,?,P,?,?,?,?,?

By examining the position of "O" in the message (10th character) and its alignment in the key matrix (10th column), we can determine that the missing character in the 11th position (between "O" and "B") should be "F."

C,H,N,R,J,E,S,W,T,O,F,B,D,?,?,I,J,?,?,P,?,?,?,?,?

Continuing this process of aligning known characters, we can fill in the missing characters as follows:

C,H,N,R,J,E,S,W,T,O,F,B,D,G,A,K,L,M,I,J,Q,U,P,V,X,Y,Z

Now, using the completed key matrix, we can decrypt the message:

SRJEEUJLTCDWWEIETCSINEOSFGTLMEOJTCENJUWNLEPICOUKFR

After decryption, the message reads:

SEARCHTHEATTACHEDFILEFORTHEANSWERTOYOURQUESTION

So I tried strings corruptedKey.pdf | grep USCG, but no luck OOTB. Same lack of success with xxd, binwalk gave some initial hope with a successfully extracted image file, but it was simply the "Telegraf" font preview.

I thought it might be a trick question, due to the prompt's description of the flag format, so I tried submitting uscg{SEARCH_THE_ATTACHED_FILE_FOR_THE_ANSWER_TO_YOUR_QUESTION}; no dice. Nor did exiftool net any information that strings missed.