Continuing where we left of…
Level 10 –> 11
Level credentials
- username : bandit10
- password : G7w8LIi6J3kTb8A7j9LgrywtEUlyyp6s
Level goal
The password for the next level is stored in the file data.txt, which contains base64 encoded data
Level solution
When we cat
the content of data.txt, we obtain the following string :
VGhlIHBhc3N3b3JkIGlzIDZ6UGV6aUxkUjJSS05kTllGTmI2blZDS3pwaGxYSEJNCg==
Now, this is a base64 encoded string.
Base64 encoding is a method to represent binary data as ASCII characters using a set of 64 characters. It is commonly used for transmitting data over channels designed for text only. It is a reversible process allowing the original binary data to be recovered.
We can easily decode our string using base64
linux command with -d
option, but where is the fun doing that?
Let’s create our own python script that will decrypt the password.
You can read this article that explains base64 encoding very well.
Once you have read the article, you can check the script i wrote in my github here.
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
import sys
# creating base64 table index
A_Z = [chr(i) for i in range(65,91)]
a_z = [chr(i) for i in range(97,123)]
zero_nine = [chr(i) for i in range(48,58)]
additional_chars = ['+','/']
base64_index_table = A_Z + a_z + zero_nine + additional_chars
# binary to decimal custom function
def bin_to_int(byte):
#110101
result = 0
for i in range(0,len(byte)):
result += int(byte[len(byte) - 1 - i]) * pow(2 ,i)
return result
def b64_encode(word):
# converting the word into its binary format
binary = []
for c in word:
binary.append(bin(ord(c)).split("b")[-1].rjust(8,'0'))
binary = "".join(binary)
# splitting the binary format into chunks of 6 bits
new_word = []
while len(binary):
new_word.append(binary[0:6])
binary = binary[6:]
# adding padding to the last elem
new_word[-1] = new_word[-1].ljust(6, '0')
# encrypting the text
result = ""
for byte in new_word:
result += base64_index_table[bin_to_int(byte)]
# adding padding of "="
def get_multiple_of_4(num):
while num % 4 != 0:
num += 1
return num
result = result.ljust(get_multiple_of_4(len(result)),'=')
return result
def b64_decode(word):
#stripping away '='
word = word.split("=")[0]
#find index of each character in b64_index_table
indexes = []
for c in word:
indexes.append(base64_index_table.index(c))
# index to binary ( 6 bits)
binary = []
for i in indexes:
binary.append(bin(i).split("b")[-1].rjust(6,'0'))
binary = "".join(binary)
# form group of 8 bits
new_word = []
while len(binary):
new_word.append(binary[0:8])
binary = binary[8:]
# transform each byte to its ascii representation
result = ""
for c in new_word:
result += chr(bin_to_int(c))
return result
#python b64.py
if __name__ == '__main__':
len_args = len(sys.argv)
if (len_args != 3):
print(f"[] Usage : python {sys.argv[0]} <string> (-d | -e )")
exit(0)
option = sys.argv[2]
if (option != '-d' and option != '-e'):
print(f"[] Usage : python {sys.argv[0]} <string> (-d | -e )")
exit(0)
word = sys.argv[1]
if (option == '-d'):
print(f"[+] {word} ---> {b64_decode(word)}")
else:
print(f"[+] {word} ---> {b64_encode(word)}")
1
python b64.py 'VGhlIHBhc3N3b3JkIGlzIDZ6UGV6aUxkUjJSS05kTllGTmI2blZDS3pwaGxYSEJNCg==' -d
We got our password 😃
6zPeziLdR2RKNdNYFNb6nVCKzphlXHBM
Level 11 –> 12
Level credentials
- username : bandit11
- password : 6zPeziLdR2RKNdNYFNb6nVCKzphlXHBM
Level goal
The password for the next level is stored in the file data.txt, where all lowercase (a-z) and uppercase (A-Z) letters have been rotated by 13 positions
Level solution
Basically, each letter of our password is rotated 13 times, meaning that ‘a’ becomes ‘n’ , ‘b’ becomes ‘o’ , …
1
cat data.txt
Gur cnffjbeq vf WIAOOSFzMjXXBC0KoSKBbJ8puQm5lIEi
Let’s create a simple c program to decrypt our password
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include<stdio.h>
#include<string.h>
int main(int ac, char **av)
{
if (ac != 2)
return 0;
char *word = av[1];
for(size_t i = 0 ; i < strlen(word) ; i++)
{
char c = word[i];
if ( 97 <= c && c <= 122)
printf("%c", ((c - 97 + 13 ) % 26 )+ 97);
else if ( 65 <= c && 90)
printf("%c", ((c - 65 + 13 ) % 26) + 65);
else printf("%c",c);
}
return 0;
}
The program loops through the string provided as argument and does the following :
- checks if the current char is lowercase , if so we calculate its position in the alphabet
c - 97
. - we add the offset , which is
13
in our case. - we take the result
%26
, meaning that everytime we overflow, we get back to a valid alphabet position. - then we add 97 to convert the result from the index to the character.
The same operations are valid for uppercase.
And if it is a number, we just print it.
Let’s now compile our rot13.c
program and execute it.
1
2
3
gcc -Wall -Wextra -Werror rot13.c -o rot13
./rot13 "Gur cnffjbeq vf WIAOOSFzMjXXBC0KoSKBbJ8puQm5lIEi"
We got our password 😃
JVNBBFSmZwKKOP0XbFXOoW8chDz5yVRv
Level 12 –> 13
Level credentials
- username : bandit12
- password : JVNBBFSmZwKKOP0XbFXOoW8chDz5yVRv
Level goal
The password for the next level is stored in the file data.txt, which is a hexdump of a file that has been repeatedly compressed. For this level it may be useful to create a directory under /tmp in which you can work using mkdir. For example: mkdir /tmp/myname123. Then copy the datafile using cp, and rename it using mv (read the manpages!)
Level solution
This level is a bit tedious and tiresome…
If we try to cat
our file, we end up with a hexdump.
A hexdump of a file is a representation of the file’s contents in hexadecimal format. It displays the file’s binary data in a readable format, where each byte of the file is represented by two hexadecimal digits, and optionally, their corresponding ASCII characters.
Now, we can reverse that by using a command line utility called xxd
, combining it with -r
.
But first, let’s move to a directory that we have the right to write on => /tmp
.
1
2
3
mkdir /tmp/y4riss
cp data.txt /tmp/y4riss
cd /tmp/y4riss
Now we can start by reversing the hexdump.
1
xxd -r data.txt > data
If we inspect data
file type, it says that it is a gzip compressed, let’s decompresse it using gunzip
1
2
mv data data.gz
gunzip data.gz
Let’s inspect the new file’s type
1
2
3
4
5
bandit12@bandit:/tmp/y4riss$ ls
data
bandit12@bandit:/tmp/y4riss$ file data
data: bzip2 compressed data, block size = 900k
bandit12@bandit:/tmp/y4riss$
Here we go again…, let’s repeat the process
1
2
3
4
5
6
bandit12@bandit:/tmp/y4riss$ mv data data.bz2
bandit12@bandit:/tmp/y4riss$ bunzip2 data.bz2
bandit12@bandit:/tmp/y4riss$ ls
data
bandit12@bandit:/tmp/y4riss$ file data
data: gzip compressed data, was "data4.bin", last modified: Tue Feb 21 22:02:52 2023, max compression, from Unix, original size modulo 2^32 20480
As the level indicated, our file is repeatedly compressed, let’s repeat the same process.
1
2
3
4
5
6
bandit12@bandit:/tmp/y4riss$ mv data data.gz
bandit12@bandit:/tmp/y4riss$ gunzip data.gz
bandit12@bandit:/tmp/y4riss$ ls
data
bandit12@bandit:/tmp/y4riss$ file data
data: POSIX tar archive (GNU)
A tar archive ! we can extract its content using tar -xf
1
2
3
4
5
bandit12@bandit:/tmp/y4riss$ tar -xf data
bandit12@bandit:/tmp/y4riss$ ls
data data5.bin
bandit12@bandit:/tmp/y4riss$ file data5.bin
data5.bin: POSIX tar archive (GNU)
Okey, we are close…
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
bandit12@bandit:/tmp/y4riss$ tar -xf data5.bin
bandit12@bandit:/tmp/y4riss$ ls
data data5.bin data6.bin
bandit12@bandit:/tmp/y4riss$ file data6.bin
data6.bin: bzip2 compressed data, block size = 900k
bandit12@bandit:/tmp/y4riss$ mv data6.bin data6.bz2
bandit12@bandit:/tmp/y4riss$ bunzip2 data6.bz2
bandit12@bandit:/tmp/y4riss$ ls
data data5.bin data6
bandit12@bandit:/tmp/y4riss$ file *
data: POSIX tar archive (GNU)
data5.bin: POSIX tar archive (GNU)
data6: POSIX tar archive (GNU)
bandit12@bandit:/tmp/y4riss$ tar -xf data6
bandit12@bandit:/tmp/y4riss$ ls
data data5.bin data6 data8.bin
bandit12@bandit:/tmp/y4riss$ file data8.bin
data8.bin: gzip compressed data, was "data9.bin", last modified: Tue Feb 21 22:02:52 2023, max compression, from Unix, original size modulo 2^32 49
bandit12@bandit:/tmp/y4riss$ mv data8.bin data8.gz
bandit12@bandit:/tmp/y4riss$ gunzip data8.gz
bandit12@bandit:/tmp/y4riss$ ls
data data5.bin data6 data8
We got it, let’s inspect data8
file type.
1
2
3
4
5
bandit12@bandit:/tmp/y4riss$ file data8
data8: ASCII text
bandit12@bandit:/tmp/y4riss$ cat data8
The password is wbWdlBxEir4CaE8LaPhauuOo6pwRmrDw
We got our password 😃
wbWdlBxEir4CaE8LaPhauuOo6pwRmrDw
Level 13 –> 14
Level credentials
- username : bandit13
- password : wbWdlBxEir4CaE8LaPhauuOo6pwRmrDw
Level goal
The password for the next level is stored in /etc/bandit_pass/bandit14 and can only be read by user bandit14. For this level, you don’t get the next password, but you get a private SSH key that can be used to log into the next level. Note: localhost is a hostname that refers to the machine you are working on
Level solution
If you noticed up until now, we used a password as a sort of authentication to connect to the SSH server.
There is an alternative way to establish the connection : a private SSH key.
You can read more about how ssh private key works in this article
Let’s get back to our challenge, we got a private key, how can we use it ?
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
bandit13@bandit:~$ ls -la
total 24
drwxr-xr-x 2 root root 4096 Feb 21 22:02 .
drwxr-xr-x 70 root root 4096 Feb 21 22:04 ..
-rw-r--r-- 1 root root 220 Jan 6 2022 .bash_logout
-rw-r--r-- 1 root root 3771 Jan 6 2022 .bashrc
-rw-r--r-- 1 root root 807 Jan 6 2022 .profile
-rw-r----- 1 bandit14 bandit13 1679 Feb 21 22:02 sshkey.private
bandit13@bandit:~$ cat sshkey.private
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAxkkOE83W2cOT7IWhFc9aPaaQmQDdgzuXCv+ppZHa++buSkN+
gg0tcr7Fw8NLGa5+Uzec2rEg0WmeevB13AIoYp0MZyETq46t+jk9puNwZwIt9XgB
ZufGtZEwWbFWw/vVLNwOXBe4UWStGRWzgPpEeSv5Tb1VjLZIBdGphTIK22Amz6Zb
ThMsiMnyJafEwJ/T8PQO3myS91vUHEuoOMAzoUID4kN0MEZ3+XahyK0HJVq68KsV
ObefXG1vvA3GAJ29kxJaqvRfgYnqZryWN7w3CHjNU4c/2Jkp+n8L0SnxaNA+WYA7
jiPyTF0is8uzMlYQ4l1Lzh/8/MpvhCQF8r22dwIDAQABAoIBAQC6dWBjhyEOzjeA
J3j/RWmap9M5zfJ/wb2bfidNpwbB8rsJ4sZIDZQ7XuIh4LfygoAQSS+bBw3RXvzE
pvJt3SmU8hIDuLsCjL1VnBY5pY7Bju8g8aR/3FyjyNAqx/TLfzlLYfOu7i9Jet67
xAh0tONG/u8FB5I3LAI2Vp6OviwvdWeC4nOxCthldpuPKNLA8rmMMVRTKQ+7T2VS
nXmwYckKUcUgzoVSpiNZaS0zUDypdpy2+tRH3MQa5kqN1YKjvF8RC47woOYCktsD
o3FFpGNFec9Taa3Msy+DfQQhHKZFKIL3bJDONtmrVvtYK40/yeU4aZ/HA2DQzwhe
ol1AfiEhAoGBAOnVjosBkm7sblK+n4IEwPxs8sOmhPnTDUy5WGrpSCrXOmsVIBUf
laL3ZGLx3xCIwtCnEucB9DvN2HZkupc/h6hTKUYLqXuyLD8njTrbRhLgbC9QrKrS
M1F2fSTxVqPtZDlDMwjNR04xHA/fKh8bXXyTMqOHNJTHHNhbh3McdURjAoGBANkU
1hqfnw7+aXncJ9bjysr1ZWbqOE5Nd8AFgfwaKuGTTVX2NsUQnCMWdOp+wFak40JH
PKWkJNdBG+ex0H9JNQsTK3X5PBMAS8AfX0GrKeuwKWA6erytVTqjOfLYcdp5+z9s
8DtVCxDuVsM+i4X8UqIGOlvGbtKEVokHPFXP1q/dAoGAcHg5YX7WEehCgCYTzpO+
xysX8ScM2qS6xuZ3MqUWAxUWkh7NGZvhe0sGy9iOdANzwKw7mUUFViaCMR/t54W1
GC83sOs3D7n5Mj8x3NdO8xFit7dT9a245TvaoYQ7KgmqpSg/ScKCw4c3eiLava+J
3btnJeSIU+8ZXq9XjPRpKwUCgYA7z6LiOQKxNeXH3qHXcnHok855maUj5fJNpPbY
iDkyZ8ySF8GlcFsky8Yw6fWCqfG3zDrohJ5l9JmEsBh7SadkwsZhvecQcS9t4vby
9/8X4jS0P8ibfcKS4nBP+dT81kkkg5Z5MohXBORA7VWx+ACohcDEkprsQ+w32xeD
qT1EvQKBgQDKm8ws2ByvSUVs9GjTilCajFqLJ0eVYzRPaY6f++Gv/UVfAPV4c+S0
kAWpXbv5tbkkzbS0eaLPTKgLzavXtQoTtKwrjpolHKIHUz6Wu+n4abfAIRFubOdN
/+aLoRQ0yBDRbdXMsZN/jvY44eM+xRLdRVyMmdPtP8belRi2E2aEzA==
-----END RSA PRIVATE KEY-----
To authenticate using the private key, we need to add -i
option and specify the key path, let’s try it inside bandit13
1
bandit13@bandit:~$ ssh -i sshkey.private bandit14@bandit.labs.overthewire.org -p 2220
We are in 😃
Before to move on to the next level, i wanted to mention an alternative way to solve the challenge, which is to download the key to our local machine, and then using it to connect.
To send data across machines, there are plenty of ways, we can setup a quick http webserver, but we need sudo permissions.
Another way is to use scp
.
From your local machine, type the following :
1
scp -P 2220 bandit13@bandit.labs.overthewire.org:/home/bandit13/sshkey.private .
This will copy the sshkey to our current directory.
Now if we try to connect, we will get this message :
Permissions 0640 for ‘sshkey.private’ are too open.
We need to change the secret key permissions so that only its owner has permissions.
1
2
┌──(yariss㉿Kali-VM)-[~]
└─$ chmod 600 sshkey.private
If we retry, it works !
We are in 😃
Level 14 –> 15
Level credentials
- username : bandit14
- password : SSH private key from the previous level
Level goal
The password for the next level can be retrieved by submitting the password of the current level to port 30000 on localhost.
Level solution
Since we are bandit14, we can read our own password in /etc/bandit_pass/bandit14
1
2
bandit14@bandit:~$ cat /etc/bandit_pass/bandit14
fGrHPx402xGC7U7rXKDaxiWFTOiF0ENq
We are told to submit our password to port 30000 on localhost.
A simple nc
would do the trick.
nc
, also known as netcat
, is a command-line utility used for network communication. It can be used as a simple TCP/UDP client or server. It allows users to read and write data across network connections.
When used as a client, nc
establishes a connection to a remote system and sends data to it. When used as a server, nc
listens for incoming connections and accepts data from clients.
Now, the server already listens for incoming connections at port 30000, we can connect to it using nc
.
If we inspect open port on our current level (localhost), we can clearly notice that port 30000 is open.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
bandit14@bandit:~$ nmap localhost
Starting Nmap 7.80 ( https://nmap.org ) at 2023-04-20 17:09 UTC
Nmap scan report for localhost (127.0.0.1)
Host is up (0.00015s latency).
Not shown: 994 closed ports
PORT STATE SERVICE
22/tcp open ssh
1111/tcp open lmsocialserver
1840/tcp open netopia-vo2
4321/tcp open rwhois
8000/tcp open http-alt
30000/tcp open ndmps
Nmap done: 1 IP address (1 host up) scanned in 0.09 seconds
Now let’s actually connect to it.
1
bandit14@bandit:~$ nc localhost 30000
The standard input is open, let’s paste in our password and see what happens.
We got our password 😃
jN2kgmIXJ6fShzhT2avhotn4Zcka6tnt