n00bzCTF
Well, this was a blessing in disguise as it was made made for n00bz by n00bz.
1
Authors: AbuCTF, MrRobot, SHL, PattuSai
Cryptography
RSA
The cryptography category is incomplete without RSA. So here is a simple RSA challenge. Have fun! Author: noob_abhinav
Attachments
Ah, the OG RSA challenge.
1
2
3
e = 3
n = 135112325288715136727832177735512070625083219670480717841817583343851445454356579794543601926517886432778754079508684454122465776544049537510760149616899986522216930847357907483054348419798542025184280105958211364798924985051999921354369017984140216806642244876998054533895072842602131552047667500910960834243
c = 13037717184940851534440408074902031173938827302834506159512256813794613267487160058287930781080450199371859916605839773796744179698270340378901298046506802163106509143441799583051647999737073025726173300915916758770511497524353491642840238968166849681827669150543335788616727518429916536945395813
This is a straight forward challenge, of course you can take these values and paste it in any RSA decoders like dcode
or RsaCtfTool
and it would work. But let’s study the theory behind the reason that we’re able to crack the cipher.
Don’t Rush The Process, Trust The Process.
Here’s an example with the RsaCtfTool
.
1
2
3
4
5
6
7
8
9
└─$ python3 RsaCtfTool.py -n 135112325288715136727832177735512070625083219670480717841817583343851445454356579794543601926517886432778754079508684454122465776544049537510760149616899986522216930847357907483054348419798542025184280105958211364798924985051999921354369017984140216806642244876998054533895072842602131552047667500910960834243
-e 3 --decrypt 13037717184940851534440408074902031173938827302834506159512256813794613267487160058287930781080450199371859916605839773796744179698270340378901298046506802163106509143441799583051647999737073025726173300915916758770511497524353491642840238968166849681827669150543335788616727518429916536945395813
Decrypted data :
HEX : 0x6e3030627a7b6372797074305f31735f316e63306d706c3374335f773174683075745f72733421217d
INT (big endian) : 235360648501923597413504426673122110620436456645077837051697081536135487875222175025616363200782717
INT (little endian) : 267274803801739728615674650006248742190143184448285803664400617962080516309180649444183969553723502
utf-8 : n00bz{crypt0_1s_1nc0mpl3t3_w1th0ut_rs4!!}
STR : b'n00bz{crypt0_1s_1nc0mpl3t3_w1th0ut_rs4!!}'
Note: I deep dive into theoretical mathematics and cryptography. If you good, skip to the next challenge.
Okay, this challenge involves the vulnerability in the exponent being a small number. We call this the small public exponent attack.
In RSA encryption, the security comes from the difficulty of reversing the encryption process without the private key. The process is based on modular arithmetic, where a message m is raised to the power of an exponent e and then reduced modulo n. The encryption formula is:
\[c=m^emodn\]Here, c is the ciphertext, e is the public exponent, and n is the modulus, which is a product of two large prime numbers.
When e is small, like e = 3 , and the message m is also small, something unusual can happen.
This is because, In typical RSA encryption, m^e should be much larger than n, so that the operation m^emodn effectively “wraps around
” [I’ll come back on what wraps around really means] and gives a number within the range of 0 to n -1. This wrapping ensures that the original message $m$ cannot be easily derived from the ciphertext c.
However, if the message m is small, then m^e might still be smaller than . For example, if m is small and e =3, then:
\[m^3 < n\]In this case, the operation m^3 modn does nothing because m^e is already smaller than n. Therefore, the ciphertext c will just be m^e without any reduction. So, we can write:
\[c = m^3\]So if an attacker intercepts this ciphertext c , they can easily recover the original message m by taking the cube root of c :
\[m = \sqrt[3]{c}\]This works because the ciphertext is just m^e, and taking the cube root of m^e gives back m. No special mathematical tricks or complex calculations are needed—just a simple cube root operation.
But funnily, there is a unique case for this, even thought what happens when m^e equals to n, I’ll leave this as an exercise for the reader to think about LOL.
Exploit Time
1
2
3
4
5
6
7
8
9
10
11
12
13
import gmpy2
e = 3
n = 135112325288715136727832177735512070625083219670480717841817583343851445454356579794543601926517886432778754079508684454122465776544049537510760149616899986522216930847357907483054348419798542025184280105958211364798924985051999921354369017984140216806642244876998054533895072842602131552047667500910960834243
c = 13037717184940851534440408074902031173938827302834506159512256813794613267487160058287930781080450199371859916605839773796744179698270340378901298046506802163106509143441799583051647999737073025726173300915916758770511497524353491642840238968166849681827669150543335788616727518429916536945395813
m = gmpy2.iroot(c, e)[0]
mInt = int(m)
mBytes = mInt.to_bytes((mInt.bit_length() + 7) // 8, byteorder='big')
flag = mBytes.decode('utf-8')
print("Flag:", flag)
Output:
1
2
└─$ python3 solve.py
Flag: n00bz{crypt0_1s_1nc0mpl3t3_w1th0ut_rs4!!}
Flag: n00bz{crypt0_1s_1nc0mpl3t3_w1th0ut_rs4!!}
Vinegar
Can you decode this message? Note: Wrap the decrypted text in n00bz{}. Author: noob_abhinav
Attachments
1
2
Encrypted flag: nmivrxbiaatjvvbcjsf
Key: secretkey
We’ve been given the ciphertext and key, and this totally points to Vigenere
Cipher.
Head on to dCode
to decode it.
Flag: n00bz{vigenerecipherisfun}
Vinegar 2
Never limit yourself to only alphabets! Author: NoobMaster
Attachments
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
alphanumerical = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*(){}_?'
matrix = []
for i in alphanumerical:
matrix.append([i])
idx=0
for i in alphanumerical:
matrix[idx][0] = (alphanumerical[idx:len(alphanumerical)]+alphanumerical[0:idx])
idx += 1
flag=open('../src/flag.txt').read().strip()
key='5up3r_s3cr3t_k3y_f0r_1337h4x0rs_r1gh7?'
assert len(key)==len(flag)
flag_arr = []
key_arr = []
enc_arr=[]
for y in flag:
for i in range(len(alphanumerical)):
if matrix[i][0][0]==y:
flag_arr.append(i)
for y in key:
for i in range(len(alphanumerical)):
if matrix[i][0][0]==y:
key_arr.append(i)
for i in range(len(flag)):
enc_arr.append(matrix[flag_arr[i]][0][key_arr[i]])
encrypted=''.join(enc_arr)
f = open('enc.txt','w')
f.write(encrypted)
1
2
└─$ cat enc.txt
*fa4Q(}$ryHGswGPYhOC{C{1)&_vOpHpc2r0({
So, we’ve been given an another implementation of the Vigenere
Cipher. But this time around dCode
or CyberChef
won’t be able to decode it since we have a much larger character set and hence the matrix is alphanumeric when compared to the traditional alphabetic matrices that dCode
uses.
Another thing to note is that the key is the same length of the ciphertext and it includes special characters and all of that.
Key: 5up3r_s3cr3t_k3y_f0r_1337h4x0rs_r1gh7?
Cipher: *fa4Q(}$ryHGswGPYhOC{C{1)&_vOpHpc2r0({
- For each character in the flag and key, the code finds the index of that character in the
alphanumerical
string. This index is stored inflag_arr
andkey_arr
. - Encryption:
- The encryption is performed by iterating over each character in the flag and key simultaneously. For each character in the flag, the code finds the corresponding row in the matrix using
flag_arr
(the index of the flag character). - Then, it uses the corresponding index from
key_arr
to find the character in that row, which becomes part of the encrypted message. - The resulting encrypted message is stored in
enc.txt
.
- The encryption is performed by iterating over each character in the flag and key simultaneously. For each character in the flag, the code finds the corresponding row in the matrix using
Now, we write a script that reverses the encryption by using the key to map the encrypted characters back to the original characters in the flag.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
alphanumerical = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*(){}_?'
matrix = []
for i in alphanumerical:
matrix.append([i])
for idx, i in enumerate(alphanumerical):
matrix[idx][0] = (alphanumerical[idx:] + alphanumerical[:idx])
cipher = '*fa4Q(}$ryHGswGPYhOC{C{1)&_vOpHpc2r0({'
key = '5up3r_s3cr3t_k3y_f0r_1337h4x0rs_r1gh7?'
keyIndices = []
for y in key:
for i in range(len(alphanumerical)):
if matrix[i][0][0] == y:
keyIndices.append(i)
decrypted = []
for i, encChar in enumerate(cipher):
keyIDX = keyIndices[i]
for j, char in enumerate(matrix[keyIDX][0]):
if char == encChar:
decrypted.append(alphanumerical[j])
break
flag = ''.join(decrypted)
print(flag)
Flag: n00bz{4lph4num3r1c4l_1s_n0t_4_pr0bl3m}
Random
I hid my password behind an impressive sorting machine. The machine is very luck based, or is it?!?!?!? Author: Connor Chang
Attachments:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include<chrono>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<string>
#include<fstream>
#include<thread>
#include<map>
using namespace std;
bool amazingcustomsortingalgorithm(string s) {
int n = s.size();
for (int i = 0; i < 69; i++) {
cout << s << endl;
bool good = true;
for (int i = 0; i < n - 1; i++)
good &= s[i] <= s[i + 1];
if (good)
return true;
random_shuffle(s.begin(), s.end());
this_thread::sleep_for(chrono::milliseconds(500));
}
return false;
}
int main() {
string s;
getline(cin, s);
map<char, int> counts;
for (char c : s) {
if (counts[c]) {
cout << "no repeating letters allowed passed this machine" << endl;
return 1;
}
counts[c]++;
}
if (s.size() < 10) {
cout << "this machine will only process worthy strings" << endl;
return 1;
}
if (s.size() == 69) {
cout << "a very worthy string" << endl;
cout << "i'll give you a clue'" << endl;
cout << "just because something says it's random mean it actually is" << endl;
return 69;
}
random_shuffle(s.begin(), s.end());
if (amazingcustomsortingalgorithm(s)) {
ifstream fin("flag.txt");
string flag;
fin >> flag;
cout << flag << endl;
}
else {
cout << "UNWORTHY USER DETECTED" << endl;
}
}
1
2
3
4
└─$ nc challs.n00bzunit3d.xyz 10208
4761058239
0123456789
n00bz{5up3r_dup3r_ultr4_54f3_p455w0rd_1fa89f63a437}
Flag: n00bz{5up3r_dup3r_ultr4_54f3_p455w0rd_1fa89f63a437}
Web
Passwordless
Tired of storing passwords? No worries! This super secure website is passwordless! Author: NoobMaster
Attachments
- app.py
- https://24.199.110.35:40150/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#!/usr/bin/env python3
from flask import Flask, request, redirect, render_template, render_template_string
import subprocess
import urllib
import uuid
global leet
app = Flask(__name__)
flag = open('/flag.txt').read()
leet=uuid.UUID('13371337-1337-1337-1337-133713371337')
@app.route('/',methods=['GET','POST'])
def main():
global username
if request.method == 'GET':
return render_template('index.html')
elif request.method == 'POST':
username = request.values['username']
if username == 'admin123':
return 'Stop trying to act like you are the admin!'
uid = uuid.uuid5(leet,username) # super secure!
return redirect(f'/{uid}')
@app.route('/<uid>')
def user_page(uid):
if uid != str(uuid.uuid5(leet,'admin123')):
return f'Welcome! No flag for you :('
else:
return flag
if __name__ == '__main__':
app.run(host='0.0.0.0', port=1337)
Just a simple website that took in the username admin123
and password to log the user in.
1
2
3
4
if username == 'admin123':
return 'Stop trying to act like you are the admin!'
uid = uuid.uuid5(leet,username) # super secure!
return redirect(f'/{uid}')
In this part of the flask code, you see that the server accepts the username admin123
and returns the strings “Stop trying to act like you are the admin!” and for other usernames then there is a page route that redirects to /{uid}
.
Here is a simple script that calculate the UUID of the admin123 user.
1
2
3
4
5
6
7
import uuid
leet = uuid.UUID('13371337-1337-1337-1337-133713371337')
target = 'admin123'
UUID = uuid.uuid5(leet, target)
print(UUID)
1
2
└─$ python3 generate.py
3c68e6cc-15a7-59d4-823c-e7563bbb326c
Now, paste this UUID in the URL and get the flag.
Flag: n00bz{1337-13371337-1337-133713371337-1337}
Focus on yourSELF
Have you focused on yourself recently? Author: NoobHacker
Attachments
So, first of all I’m not a web guy, but I gave it a try anyways.
1
2
3
4
5
6
7
8
9
10
└─$ cat docker-compose.yaml
# CHANGE THE FLAG WHEN HANDING THIS OUT TO PLAYERS
services:
web:
build: .
ports:
- "4000:1337"
environment:
- FLAG="n00bz{f4k3_fl4g_f0r_t3st1ng}"
We were also given a web instance,
Instance Info
You see the SELF capitalized in the title of the challenge, that and the flag in the environment in the docker-compose.yaml
file lead me to conclude that the flag is located in the environment of the site.
A quick google on where the environment variables get stores, gives me /proc/self/environ
. This also means the site is vulnerable to LFI [Local File Inclusion]
. Let’s check if it’s actually vulnerable to LFI.
Going to the view
page, we see an image with the URL,
so instead of /view?image=nature.jpeg
let’s do /view?image=../../../../etc/passwd
.
It didn’t print out the detail then and there, going to the source.
We see a huge base64
string.
Turns out it actually is the etc/passwd
file. Crazy. Now let’s find out the environment variables.
/view?image=../../../../proc/self/environ
and decoding the base64, we get the flag.
1
2
3
4
5
PATH=/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin␀
HOSTNAME=bed1b2061841␀FLAG=n00bz{Th3_3nv1r0nm3nt_det3rmine5_4h3_S3lF_d542cc29d35c}
␀LANG=C.UTF-8␀GPG_KEY=A035C8C19219BA821ECEA86B64E628F8D684696D␀
PYTHON_VERSION=3.10.14␀PYTHON_PIP_VERSION=23.0.1␀PYTHON_SETUPTOOLS_VERSION=65.5.1␀
PYTHON_GET_PIP_URL=https://github.com/pypa/get-pip/raw/66d8a0f637083e2c3ddffc0cb1e65ce126afb856/public/get-pip.py␀PYTHON_GET_PIP_SHA256=6fb7b781206356f45ad79efbb19322caa6c2a5ad39092d0d44d0fec94117e118␀HOME=/home/chall␀
Flag: n00bz{Th3_3nv1r0nm3nt_det3rmine5_4h3_S3lF_d542cc29d35c}
Misc
Sanity Check
Welcome to n00bzCTF 2024! Join our discord server to get the flag! Author: n00bzUnit3d
Join discord and scroll into #Announcements.
Flag: n00bz{w3lc0m3_t0_n00bzCTF2024!}
Addition
My little brother is learning math, can you show him how to do some addition problems? Author: Connor Chang
Attachments
- server.py
- nc 24.199.110.35 42189
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import time
import random
questions = int(input("how many questions do you want to answer? "))
for i in range(questions):
a = random.randint(0, 10)
b = random.randint(0, 10)
yourans = int(input("what is " + str(a) + ' + ' + str(b) + ' = '))
print("calculating")
totaltime = pow(2, i)
print('.')
time.sleep(totaltime / 3)
print('.')
time.sleep(totaltime / 3)
print('.')
time.sleep(totaltime / 3)
if yourans != a + b:
print("You made my little brother cry 😭")
exit(69)
f = open('/flag.txt', 'r')
flag = f.read()
print(flag[:questions])
In the server code, it does additions and checks the answer, but sighs
To determine how long it would take for the entire script to run, let’s break it down step-by-step:
But start playing around with it, try inputting different numbers in the instance, remember there’s not just positive numbers in the world. Once you figure it out. Flag!
- Negative or Zero Questions:
- If you enter
1
or0
, therange(questions)
loop won’t execute any iterations. This is becauserange(-1)
andrange(0)
result in an empty sequence. As a result, no questions are processed, and no delays are introduced.
- If you enter
- Immediate Access to the Flag:
- Since no questions are processed, the code immediately proceeds to open the
/flag.txt
file and print the flag. - In the specific case of
1
, the loop effectively does nothing, and the script directly accesses the flag file.
- Since no questions are processed, the code immediately proceeds to open the
Truly a big-brain moment LOL.
1
2
3
└─$ nc 24.199.110.35 42189
how many questions do you want to answer? -1
n00bz{m4th_15nt_4ll_4b0ut_3qu4t10n5}
Flag: n00bz{m4th_15nt_4ll_4b0ut_3qu4t10n5}
Agree
I hope you like our Terms of Service and Privacy Policy of our website! Author: NoobMaster
Can you believe I opened a ticket to solve this challenge ?! LOL.
Just visit both these URLs
Thanks for agreeing to our Terms of Service! Here’s 1/2 of your flag: n00bz{Terms_0f_Serv1c3s_
This is our Privacy Policy! Here’s 2/2 of your flag: 4nd_pr1v4cy_p0l1cy_6f3a4d}
Flag: n00bz{Terms_0f_Serv1c3s_4nd_pr1v4cy_p0l1cy_6f3a4d}
Reverse
Vacation
My friend told me they were going on vacation, but they sent me this weird PowerShell script instead of a postcard! Author: 0xBlue
Attachments
1
2
3
4
5
6
7
8
9
10
└─$ cat run.ps1
$bytes = [System.Text.Encoding]::ASCII.GetBytes((cat .\flag.txt))
[System.Collections.Generic.List[byte]]$newBytes = @()
$bytes.ForEach({
$newBytes.Add($_ -bxor 3)
})
$newString = [System.Text.Encoding]::ASCII.GetString($newBytes)
echo $newString | Out-File -Encoding ascii .\output.txt
└─$ cat output.txt
m33ayxeqln\sbqjp\twk\{lq~
In the given PowerShell script, it reads the flag and does the XOR operation with each character in the flag.txt file. The result of the XOR operation is then added to the newBytes
list. The XORed byte list newBytes
is converted back into a string using ASCII encoding. Finally, the output is printed to output.txt.
CyberChef
does the job.
Flag: n00bz{from_paris_wth_xor}
Brain
Help! A hacker said that this “language” has a flag but I can’t find it! Author: NoobMaster
Attachments
1
>+++++++++++[<++++++++++>-]<[-]>++++++++[<++++++>-]<[-]>++++++++[<++++++>-]<[-]>++++++++++++++[<+++++++>-]<[-]>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++[<++>-]<[-]>+++++++++++++++++++++++++++++++++++++++++[<+++>-]<[-]>+++++++[<+++++++>-]<[-]>+++++++++++++++++++[<+++++>-]<[-]>+++++++++++[<+++++++++>-]<[-]>+++++++++++++[<++++>-]<[-]>+++++++++++[<++++++++++>-]<[-]>+++++++++++++++++++[<+++++>-]<[-]>+++++++++++[<+++++++++>-]<[-]>++++++++[<++++++>-]<[-]>++++++++++[<++++++++++>-]<[-]>+++++++++++++++++[<+++>-]<[-]>+++++++++++++++++++[<+++++>-]<[-]>+++++++[<+++++++>-]<[-]>+++++++++++[<++++++++++>-]<[-]>+++++++++++++++++++[<+++++>-]<[-]>++++++++++++++[<+++++++>-]<[-]>+++++++++++++++++++[<++++++>-]<[-]>+++++++++++++[<++++>-]<[-]>+++++++[<+++++++>-]<[-]>+++++++++++[<++++++++++>-]<[-]>+++++++++++++++++[<++++++>-]<[-]>+++++++[<++++++>-]<[-]>+++++++++++[<+++++++++>-]<[-]>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++[<+>-]<[-]>+++++++++++[<+++>-]<[-]>+++++++++++++++++++++++++[<+++++>-]<[-]
This was a common esolang
called BrainFuck
. And it actually drove me mental. Maybe, a terrible skill issue. Thing is, I used this esolang
as the description for my LinkedIn account. Yea, who in the world even does that ! but I did. OSINT challenge for the reader HAHA.
After some study about the language, we find out that .
outputs the current element in the stack [I used the work stack, just cause I felt like it LOL] to the screen. If you noticed the program closely, you find this [-]
to be strange, by adding .
before the [-]
, it prints the flag.
1
>+++++++++++[<++++++++++>-]<.[-]>++++++++[<++++++>-]<.[-]>++++++++[<++++++>-]<.[-]>++++++++++++++[<+++++++>-]<.[-]>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++[<++>-]<.[-]>+++++++++++++++++++++++++++++++++++++++++[<+++>-]<.[-]>+++++++[<+++++++>-]<.[-]>+++++++++++++++++++[<+++++>-]<.[-]>+++++++++++[<+++++++++>-]<.[-]>+++++++++++++[<++++>-]<.[-]>+++++++++++[<++++++++++>-]<.[-]>+++++++++++++++++++[<+++++>-]<.[-]>+++++++++++[<+++++++++>-]<.[-]>++++++++[<++++++>-]<.[-]>++++++++++[<++++++++++>-]<.[-]>+++++++++++++++++[<+++>-]<.[-]>+++++++++++++++++++[<+++++>-]<.[-]>+++++++[<+++++++>-]<.[-]>+++++++++++[<++++++++++>-]<.[-]>+++++++++++++++++++[<+++++>-]<.[-]>++++++++++++++[<+++++++>-]<.[-]>+++++++++++++++++++[<++++++>-]<.[-]>+++++++++++++[<++++>-]<.[-]>+++++++[<+++++++>-]<.[-]>+++++++++++[<++++++++++>-]<.[-]>+++++++++++++++++[<++++++>-]<.[-]>+++++++[<++++++>-]<.[-]>+++++++++++[<+++++++++>-]<.[-]>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++[<+>-]<.[-]>+++++++++++[<+++>-]<.[-]>+++++++++++++++++++++++++[<+++++>-]<.[-]
NGL, this was pretty guessy. Use dCode
to decode the program.
Flag: n00bz{1_c4n_c0d3_1n_br41nf*ck!}
FlagChecker
Why did the macros hide its knowledge? Because it didn’t want anyone to “excel”! Note: char_21
is the SAME as char_22
Note 2: The correct flag has ALL LOWERCASE, NUMBERS, n00bz{}
AND UNDERSCORES (There’s two underscores in the entire flag) Author: NoobMaster
Attachments
We’ve been given a XLSM file, and it was quite obvious that contains macros
. I had no hesitations to go straight to ole-tools
more specifically olevba
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
└─$ olevba FlagChecker.xlsm
olevba 0.60.2 on Python 3.11.9 - http://decalage.info/python/oletools
===============================================================================
FILE: FlagChecker.xlsm
Type: OpenXML
WARNING For now, VBA stomping cannot be detected for files in memory
-------------------------------------------------------------------------------
VBA MACRO ThisWorkbook.cls
in file: xl/vbaProject.bin - OLE stream: 'VBA/ThisWorkbook'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(empty macro)
-------------------------------------------------------------------------------
VBA MACRO Sheet1.cls
in file: xl/vbaProject.bin - OLE stream: 'VBA/Sheet1'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(empty macro)
-------------------------------------------------------------------------------
VBA MACRO Module1.bas
in file: xl/vbaProject.bin - OLE stream: 'VBA/Module1'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Sub FlagChecker()
Dim chars(1 To 24) As String
guess = InputBox("Enter the flag:")
If Len(guess) <> 24 Then
MsgBox "Nope"
End If
char_1 = Mid(guess, 1, 1)
char_2 = Mid(guess, 2, 1)
char_3 = Mid(guess, 3, 1)
char_4 = Mid(guess, 4, 1)
char_5 = Mid(guess, 5, 1)
char_6 = Mid(guess, 6, 1)
char_7 = Mid(guess, 7, 1)
char_8 = Mid(guess, 8, 1)
char_9 = Mid(guess, 9, 1)
char_10 = Mid(guess, 10, 1)
char_11 = Mid(guess, 11, 1)
char_12 = Mid(guess, 12, 1)
char_13 = Mid(guess, 13, 1)
char_14 = Mid(guess, 14, 1)
char_15 = Mid(guess, 15, 1)
char_16 = Mid(guess, 16, 1)
char_17 = Mid(guess, 17, 1)
char_18 = Mid(guess, 18, 1)
char_19 = Mid(guess, 19, 1)
char_20 = Mid(guess, 20, 1)
char_21 = Mid(guess, 21, 1)
char_22 = Mid(guess, 22, 1)
char_23 = Mid(guess, 23, 1)
char_24 = Mid(guess, 24, 1)
If Asc(char_1) Xor Asc(char_8) = 22 Then
If Asc(char_10) + Asc(char_24) = 176 Then
If Asc(char_9) - Asc(char_22) = -9 Then
If Asc(char_22) Xor Asc(char_6) = 23 Then
If (Asc(char_12) / 5) ^ (Asc(char_3) / 12) = 130321 Then
If char_22 = char_11 Then
If Asc(char_15) * Asc(char_8) = 14040 Then
If Asc(char_12) Xor (Asc(char_17) - 5) = 5 Then
If Asc(char_18) = Asc(char_23) Then
If Asc(char_13) Xor Asc(char_14) Xor Asc(char_2) = 121 Then
If Asc(char_14) Xor Asc(char_24) = 77 Then
If 1365 = Asc(char_22) Xor 1337 Then
If Asc(char_10) = Asc(char_7) Then
If Asc(char_23) + Asc(char_8) = 235 Then
If Asc(char_16) = Asc(char_17) + 19 Then
If Asc(char_19) = 107 Then
If Asc(char_20) + 501 = (Asc(char_1) * 5) Then
If Asc(char_21) = Asc(char_22) Then
MsgBox "you got the flag!"
End If
End If
End If
End If
End If
End If
End If
End If
End If
End If
End If
End If
End If
End If
End If
End If
End If
End If
End Sub
+----------+--------------------+---------------------------------------------+
|Type |Keyword |Description |
+----------+--------------------+---------------------------------------------+
|Suspicious|Xor |May attempt to obfuscate specific strings |
| | |(use option --deobf to deobfuscate) |
|Suspicious|Hex Strings |Hex-encoded strings were detected, may be |
| | |used to obfuscate strings (option --decode to|
| | |see all) |
|Suspicious|Base64 Strings |Base64-encoded strings were detected, may be |
| | |used to obfuscate strings (option --decode to|
| | |see all) |
+----------+--------------------+---------------------------------------------+
As expected, there’s a VBA macro script that’s checks each character with basic operations. I don’t know about others, but I did it manually and it didn’t take much time. So here’s a high level overview, since we know the flag format [n00bz{}
] we can consider each of the flag character to represent the individual characters in the VBA script. Now, since we know some character and others are unknown, we can build on the given knowledge slowly unwrapping more unknown characters and get the flag.
Flag: n00bz{3xc3l_y0ur_sk1lls}