Hacktivity Con CTF 2020

My walk-through to the challenges I had solved. I placed 163rd out of 3663 players.

ctf,

I’m going to order the challenges as it is on the website starting from web to scavenger hunt. I’ll list all my solved challenges on top as well.

  • Web - Ladybug, Bite
  • Binary Exploitation -
  • Cryptography - Perfect XOR
  • Mobile - Mobile One
  • Internet of Things -
  • Steganography - Cold War, Chess Cheater, Unsubscribe
  • Scripting - Misdirection
  • Miscellaneous - Pseudo, Cat Cage, Visualism, His Story
  • Forensics - Opposable Thumbs
  • OSINT -
  • Warmups - Read The Rules, CaesarMirror , Common Place, Internet Cattos, Hexgedit, Private Investigator, Vencryption
  • Scavenger Hunt - Domo Arigato, The Founding Fathers, Million Dollar Jar of Mayo, Like & Subscribe, One of us, The Finn’ishing Move, The Streamer, The Chosen One, Flag Not Found, Hacker101 Discord, Send me a flag and I’ll double, Social Media Influencer, Hawaii Five-0, Security Report Powered by Hackers, Ride Share Disclosures, <a href=”in”>, Lights, Camera, Hacking!, Find Me Treasure.xml, _config.yml#35, Pentesters Unite, The Hacker101, Security@

WEB



Ladybug

As you visit and click around on links you see that the structure is as follows

/file/pagetoopen

Tried fuzzing first, typing a random ‘asassasd’ instead of a valid page. This opened up a error page.

This error page was a python debugger with the tag of

Brought to you by DON'T PANIC, your friendly Werkzeug powered traceback interpreter.

After some Google Fu I got the url to the python debugger which was an interactive console.

/console

Thereafter the process was simpler. Using python I read the flag.txt file.

Bite

For this challenge as I visited the links on the right hand side the url was of the format

/page?=

I tried SQLI which gave nothing. I tried fuzzing next didn’t seem to give anything because it would add the .php extension at the end. So what I tried after researching was that a null byte was to be added. When I did it on the browser it didn’t give a result. But when giving the payload through burp I got a result

The null byte caused a break meaning the .php although added wasn’t read at the end of the file and it was just flag.txt not flag.txt.php.

/page?=../../../../../../../../../flag.txt%00




CRYPTOGRAPHY



Perfect XOR

This gave us an incomplete script to decrypt a message. It’s a relatively short script.

import base64
n = 1
i = 0
cipher_b64=b"MTE0LDg0LDQzNyw4MDk1LDMzNTUwNDM0LDg1ODk4NjkxNzAsMTM3NDM4NjkxMzc2LDIzMDU4NDMwMDgxMzk5NTIyMzUsMjY1ODQ1NTk5MTU2OTgzMTc0NDY1NDY5MjYxNTk1Mzg0MjI0NSwxOTE1NjE5NDI2MDgyMzYxMDcyOTQ3OTMzNzgwODQzMDM2MzgxMzA5OTczMjE1NDgxNjkyOTQsMTMxNjQwMzY0NTg1Njk2NDgzMzcyMzk3NTM0NjA0NTg3MjI5MTAyMjM0NzIzMTgzODY5NDMxMTc3ODM3MjgyMjMsMTQ0NzQwMTExNTQ2NjQ1MjQ0Mjc5NDYzNzMxMjYwODU5ODg0ODE1NzM2Nzc0OTE0NzQ4MzU4ODkwNjYzNTQzNDkxMzExOTkxNTIyMTYsMjM1NjI3MjM0NTcyNjczNDcwNjU3ODk1NDg5OTY3MDk5MDQ5ODg0Nzc1NDc4NTgzOTI2MDA3MTAxNDMwMjc1OTc1MDYzMzcyODMxNzg2MjIyMzk3MzAzNjU1Mzk2MDI2MDA1NjEzNjAyNTU1NjY0NjI1MDMyNzAxNzUwNTI4OTI1NzgwNDMyMTU1NDMzODI0OTg0Mjg3NzcxNTI0MjcwMTAzOTQ0OTY5MTg2NjQwMjg2NDQ1MzQxMjgwMzM4MzE0Mzk3OTAyMzY4Mzg2MjQwMzMxNzE0MzU5MjIzNTY2NDMyMTk3MDMxMDE3MjA3MTMxNjM1Mjc0ODcyOTg3NDc0MDA2NDc4MDE5Mzk1ODcxNjU5MzY0MDEwODc0MTkzNzU2NDkwNTc5MTg1NDk0OTIxNjA1NTU2NDcwODcsMTQxMDUzNzgzNzA2NzEyMDY5MDYzMjA3OTU4MDg2MDYzMTg5ODgxNDg2NzQzNTE0NzE1NjY3ODM4ODM4Njc1OTk5OTU0ODY3NzQyNjUyMzgwMTE0MTA0MTkzMzI5MDM3NjkwMjUxNTYxOTUwNTY4NzA5ODI5MzI3MTY0MDg3NzI0MzY2MzcwMDg3MTE2NzMxMjY4MTU5MzEzNjUyNDg3NDUwNjUyNDM5ODA1ODc3Mjk2MjA3Mjk3NDQ2NzIzMjk1MTY2NjU4MjI4ODQ2OTI2ODA3Nzg2NjUyODcwMTg4OTIwODY3ODc5NDUxNDc4MzY0NTY5MzEzOTIyMDYwMzcwNjk1MDY0NzM2MDczNTcyMzc4Njk1MTc2NDczMDU1MjY2ODI2MjUzMjg0ODg2MzgzNzE1MDcyOTc0MzI0NDYzODM1MzAwMDUzMTM4NDI5NDYwMjk2NTc1MTQzMzY4MDY1NTcwNzU5NTM3MzI4MjQy"

def a(n):
    b = 0
    for i in range(1, n):
        if(n % i == 0):
            b += i
    return b == n
n=0

print("flag{", end='', flush=True)
cipher = base64.b64decode(cipher_b64).decode().split(",")
while(i < len(cipher)):
    if (a(n)):
        print(chr(int(cipher[i]) ^ int(arr[n])), end='', flush=True)
        i += 1
    n+=1

print("}")

On first glance the a(n) function looks interesting. I made the mistake of thinking it was a prime function which made me spend over 20 minutes trying to use more efficient ways of prime like traversing to the square root of the number instead. But looking further I saw they were adding up the factors. A quick google search revealed Perfect Numbers. Instead of using n from 1 upwards I used google to find perfect numbers. They were much larger than expected.

arr=[6,28,496,8128,'33550336','8589869056','137438691328','2305843008139952128','2658455991569831744654692615953842176','191561942608236107294793378084303638130997321548169216','13164036458569648337239753460458722910223472318386943117783728128','14474011154664524427946373126085988481573677491474835889066354349131199152128','23562723457267347065789548996709904988477547858392600710143027597506337283178622239730365539602600561360255566462503270175052892578043215543382498428777152427010394496918664028644534128033831439790236838624033171435922356643219703101720713163527487298747400647801939587165936401087419375649057918549492160555646976','141053783706712069063207958086063189881486743514715667838838675999954867742652380114104193329037690251561950568709829327164087724366370087116731268159313652487450652439805877296207297446723295166658228846926807786652870188920867879451478364569313922060370695064736073572378695176473055266826253284886383715072974324463835300053138429460296575143368065570759537328128']

While running I used a print function to check how many cipher array elements were present(to check how many perfect numbers were to be hard-coded) and then modified the script as follows.

import base64
n = 1
i = 0
cipher_b64 = b"MTE0LDg0LDQzNyw4MDk1LDMzNTUwNDM0LDg1ODk4NjkxNzAsMTM3NDM4NjkxMzc2LDIzMDU4NDMwMDgxMzk5NTIyMzUsMjY1ODQ1NTk5MTU2OTgzMTc0NDY1NDY5MjYxNTk1Mzg0MjI0NSwxOTE1NjE5NDI2MDgyMzYxMDcyOTQ3OTMzNzgwODQzMDM2MzgxMzA5OTczMjE1NDgxNjkyOTQsMTMxNjQwMzY0NTg1Njk2NDgzMzcyMzk3NTM0NjA0NTg3MjI5MTAyMjM0NzIzMTgzODY5NDMxMTc3ODM3MjgyMjMsMTQ0NzQwMTExNTQ2NjQ1MjQ0Mjc5NDYzNzMxMjYwODU5ODg0ODE1NzM2Nzc0OTE0NzQ4MzU4ODkwNjYzNTQzNDkxMzExOTkxNTIyMTYsMjM1NjI3MjM0NTcyNjczNDcwNjU3ODk1NDg5OTY3MDk5MDQ5ODg0Nzc1NDc4NTgzOTI2MDA3MTAxNDMwMjc1OTc1MDYzMzcyODMxNzg2MjIyMzk3MzAzNjU1Mzk2MDI2MDA1NjEzNjAyNTU1NjY0NjI1MDMyNzAxNzUwNTI4OTI1NzgwNDMyMTU1NDMzODI0OTg0Mjg3NzcxNTI0MjcwMTAzOTQ0OTY5MTg2NjQwMjg2NDQ1MzQxMjgwMzM4MzE0Mzk3OTAyMzY4Mzg2MjQwMzMxNzE0MzU5MjIzNTY2NDMyMTk3MDMxMDE3MjA3MTMxNjM1Mjc0ODcyOTg3NDc0MDA2NDc4MDE5Mzk1ODcxNjU5MzY0MDEwODc0MTkzNzU2NDkwNTc5MTg1NDk0OTIxNjA1NTU2NDcwODcsMTQxMDUzNzgzNzA2NzEyMDY5MDYzMjA3OTU4MDg2MDYzMTg5ODgxNDg2NzQzNTE0NzE1NjY3ODM4ODM4Njc1OTk5OTU0ODY3NzQyNjUyMzgwMTE0MTA0MTkzMzI5MDM3NjkwMjUxNTYxOTUwNTY4NzA5ODI5MzI3MTY0MDg3NzI0MzY2MzcwMDg3MTE2NzMxMjY4MTU5MzEzNjUyNDg3NDUwNjUyNDM5ODA1ODc3Mjk2MjA3Mjk3NDQ2NzIzMjk1MTY2NjU4MjI4ODQ2OTI2ODA3Nzg2NjUyODcwMTg4OTIwODY3ODc5NDUxNDc4MzY0NTY5MzEzOTIyMDYwMzcwNjk1MDY0NzM2MDczNTcyMzc4Njk1MTc2NDczMDU1MjY2ODI2MjUzMjg0ODg2MzgzNzE1MDcyOTc0MzI0NDYzODM1MzAwMDUzMTM4NDI5NDYwMjk2NTc1MTQzMzY4MDY1NTcwNzU5NTM3MzI4MjQy"

def a(n):
    b = 0
    for i in range(1, n):
        if(n % i == 0):
            b += i
            if(b>n):
                return False
    return b == n
n=0
arr=[6,28,496,8128,'33550336','8589869056','137438691328','2305843008139952128','2658455991569831744654692615953842176','191561942608236107294793378084303638130997321548169216','13164036458569648337239753460458722910223472318386943117783728128','14474011154664524427946373126085988481573677491474835889066354349131199152128','23562723457267347065789548996709904988477547858392600710143027597506337283178622239730365539602600561360255566462503270175052892578043215543382498428777152427010394496918664028644534128033831439790236838624033171435922356643219703101720713163527487298747400647801939587165936401087419375649057918549492160555646976','141053783706712069063207958086063189881486743514715667838838675999954867742652380114104193329037690251561950568709829327164087724366370087116731268159313652487450652439805877296207297446723295166658228846926807786652870188920867879451478364569313922060370695064736073572378695176473055266826253284886383715072974324463835300053138429460296575143368065570759537328128']
print("flag{", end='', flush=True)
cipher = base64.b64decode(cipher_b64).decode().split(",")
#print(len(cipher))
while(i < len(cipher)):
    if (n<len(arr)):
        print(chr(int(cipher[i]) ^ int(arr[n])), end='', flush=True)
        i += 1
    n+=1

print("}")




MOBILE



Mobile One

To be perfectly honest I hit a block so I tried various challenges. I don’t know anything about mobile security. I by default was opening most files in VSCode and noticed the flag in the unpacked file. As an alternative strings in the terminal has the same effect and would get the flag.




STEGANOGRAPHY



I stayed away from the image ones because I don’t know my way around image editors like photos hop. Later/After the CTF I found about stegsolve.jar .

Cold War

This was just a text file with the text as

The Cold War continues to influence world affairs. The post-Cold War world is considered to be unipolar, with the United States the sole remaining superpower.The Cold War defined the political role of the United States after World War II—by 1989 the United States had military alliances with 50 countries, with 526,000 troops stationed abroad, with 326,000 in Europe (two-thirds of which were in West Germany) and 130,000 in Asia (mainly Japan and South Korea). The Cold War also marked the zenith of peacetime military–industrial complexes, especially in the United States, and large-scale military funding of science. These complexes, though their origins may be found as early as the 19th century, snowballed considerably during the Cold War. 

My first thought was there was no {} in the text of the file so it wasn’t a map kinda steganography. I knew of steghide and searched for text alternatives. This was perfect as I got ‘stegsnow’. This gave me the flag.

Chess Cheater

This gave an audio file titled ‘morse’. It had to be a morse code flag. Playing the file gave a series of “beeps”. I don’t know morse code but luckily the internet is there. I searched google to get a tool for the same. As a general rule I prefer to solve online rather than download a tool. Found a website for it Audio to Text Morse

Unsubscribe

This took me a little bit of time to figure out what the trick was. I tried searching for nigerian prince scams as the prompt for the challenge was that, but to no avail. Eventually spam email steganography gave me a hit.

The full text file is uploaded to my github with my rough work of the labs, here.

Email Spam Decoder




SCRIPTING



These set of challenges made me realize how weak my scripting in bash actually was, python as well. I solved only one and that too manually.

Misdirection

I have burp running as the proxy whenever I’m doing ctfs so for this I saw the following in my burp site map.

There was a major amount of redirection with flag characters in the body. I used manually scrolling as well as guesswork to get the flag. Like the last word of the flag all i got was ‘redi’ I just assumed it would be redirected or redirection or redirect. That worked.




Miscellaneous



Pseudo

They gave an ssh to an ip and port with the password for the user ‘user’ that we were using.

user:userpass

You get logged in to the home directory of ‘user’. Change directory one level up gave 35 users. That seemed a bit much to manually go through all the homes.

ls -al 

revealed that they were all the same size. I did explore some more but no information.

The prompt revealed that one of these users was special. I tried

cat /etc/passwd

Nothing really popped up. The name of this challenge was Pseudo. That had to mean ‘sudo’ right.

sudo -l 

Revealed nothing, our current user wasn’t in sudoers list. I tried cat on many files in the etc folder. Then I noticed the sudoers.d file. Read that and there was todd and his password listed at the bottom of the file.

I switched to Todd with the password and that worked. Initially I thought that was the flag but it wasn’t.

su todd 

I tried

cat /root/flag.txt

That worked!

Cat Cage

SSH into a machine. The name made me sure it had to do something with the ‘cat’ command. I tried it as just cat a prompt appeared saying the flag was already given. Off to check the MAN page for cat. Came across ‘-e’. This worked flawlessly.

Visualism

This one I had a lot of problems. Shoutout to the H101 discord who nudged me in the right direction on this.

For the previous challenges when you would ssh in and ls -al there would only be 2 files bash related. This time there was a “.vimrc” file. Little bit of google fu revealed it to be a vim configuration file.

After much frustration I found the following line in the file

let secrets=system('echo '.CACQW.NPLsJ.UNUfX.tEygA.HMLSA.YaTdJ.xlyvl.dcsaU.' | base64 -d')

This was clearly a base64 encoded text. The '.' implied it was a concatenation of variables which were scattered throughout the document. Simply combining those and decoding it gave the flag.

His Story

A search revealed a command called hsitory. For me I typed it five or six times before I got the result. I heard that printf worked as well.




FORENSICS



Opposable Thumbs

A file thumbs_256.db was the challenge. A search revealed that they were thumbnails for a windows machine. I found a tool to view the thumbnails and there was the file.




WARMUPS



Read the Rules

Read the rule webpage on ctf.hacktivitycon and view the source code.

CaesarMirror

It was a text document with gibberish. Caesar Cipher means moving the character by a fixed number. If the number is 2 then a becomes c and b becomes d and so on. I brute forced the numbers until I got 10 which made sense, however it was only half.

The rest was however mirrored. Read from right to left to get second and third part of the flag.

I have marked the flags with <>

Common Place

The prompt before the website was

asd7138: can you find the flag here?
tcm3137: no, i dont see it
jwh8163: i cant find it either
rfc5785: i found it
asd7138: what!? where?!
jwh8163: tell us!

A search of rfc5785 revealed RFC 5785 - Defining Well-Known Uniform.
This gave us the url /.well-known/ which gave the flag.

InternetCattos

For this unfortunately I don’t have a screenshot.
I visited the url in the browser. Nothing. I then used curl to the website and saw this

Oh, we already sent the flag! Did you see it?

I then used the -v flag to get a verbose result and stored the output to a file(-o). This revealed the flag one character per line.

Hexgedit

The name suggests something to do with the hex. The file was as follows.

I looked online for a hex viewer and started manually typing it in from the top. To be honest it seemed too tedious so I looked up what “{“ was in hex and searched through the image to get that as the starting point as we all know the flag format.

Private Investigator

I tried using the key to connect to the server.

Error 1 - The permissions were too much. So I made the permissions lesser.

chmod 400 id_rsa

Error 2 - Incorrect Format I read in a stack overflow thread about the new line needing to be added. I added the new line to the key and that logged me in where I got the flag.

Vencryption

For this I viewed the file which showed,

VimCrypt~03

This has to be a feature of vim to encrypt the file. I couldn’t even get my version of vim to use the -X the encryption option to work. Reinstalling vim worked by installing the full version. But to decrypt it I needed the password. I tried common ones like password,pass,password123,vencryption…. None worked. Then I learned of a brute forcing tool for vim decryption. VimDecrypt
Using that with rockyou.txt I got the password: computer.

This then decrypted the file with the flag.




SCAVENGER HUNT



With a lot of these I used google tricks to find the answers, a lot of these I found the flag then the challenge. “hackerone” site:hackerone.com site:twitter.com site:linkedin.com along with “flag{“ gave me a lot of the flags. Two I found on github. “” implies on google to search for exact terms and the search must contain that text.

  • Domo Arigato - This revealed the song Domo Arigato Mr. Roboto. The prompt to the challenge had mister… That was robot. Hence the robots.txt file of hackerone.

  • TheFounding Fathers - The founders of hackerone had this flag on the bio of their twitter profiles. Twitter here

  • Million Dollar Jar of Mayo - Mayonaise hackerone profile He became a millionaire through bounties.

  • Like & Subscribe - Youtube hackerone bio.

  • One of us - Hackerone email alias

  • The Finn’ishing Move - The finnish ceo Marten Mickos of Hackerone. His twitter bio had it.

  • The Streamer - Twitch bio of hackerone.

  • The Chosen One - NYC2017MVH meant most valuable hacker @ziot. His hackerone profile had the flag in base 64.

  • Flag Not Found - Force a error 404 on hackerone to get the flag in the source code.

  • Hacker101 Discord - I must admit I did try !flag in the discord. It was in the bio of the IOT-Village channel under hactivitycon.

  • Send me a flag and I’ll double - Based on the twitter scam recently. Hackerone Twitter Bio.

  • Social Media Influencer - Hackerone Instagram Post

  • Hawaii Five-0 - I found this here and then saw it was the hawaii one.

  • Security Report Powered by Hackers - Hacker One 2020 report

  • Ride Share Disclosures - It had lift in the prompt meaning lyft. Got it here.

  • <a href=”in”> - LinkedIn hackerone.

  • Lights, Camera, Hacking! - The captions of this video had the flag in the middle of the video.

  • Find Me Treasure.xml - Got this here

  • _config.yml#35 - This one I found on Github

  • Pentesters Unite - Found this one hacker101

  • The Hacker101 - Log into hacker101 and go to the CTF tab. It’s there at the bottom.

  • Security@ - This was the Security@ conference on hackerone. It wasn’t visible you needed to ctrl+f to get it or use source code.

Copy Link