OverTheWire is a great way to learn Linux commands, and a bit of “““hacking”””.

From their own site:

The wargames offered by the OverTheWire community can help you to learn and practice security concepts in the form of fun-filled games.

There are a few wargames/rooms that are offered. I’ll be going through the ‘Bandit’ room, which is the easiest/first.

The Bandit wargame is aimed at absolute beginners. It will teach the basics needed to be able to play other wargames.


Level 0

We only need to know the ssh command for this room, which is pretty easy to use. Let’s give it a shot.

The Goal for this level is stated below:

The goal of this level is for you to log into the game using SSH. The host to which you need to connect is bandit.labs.overthewire.org, on port 2220. The username is bandit0 and the password is bandit0. Once logged in, go to the Level 1 page to find out how to beat Level 1.

So, let’s do that with the following command:

ssh bandit.labs.overthewire.org -l bandit0 -p 2220

This will then show:

Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '[bandit.labs.overthewire.org]:2220' (ED25519) to the list of known hosts.
                         _                     _ _ _
                        | |__   __ _ _ __   __| (_) |_
                        | '_ \ / _` | '_ \ / _` | | __|
                        | |_) | (_| | | | | (_| | | |_
                        |_.__/ \__,_|_| |_|\__,_|_|\__|


                      This is an OverTheWire game server.
            More information on http://www.overthewire.org/wargames

bandit0@bandit.labs.overthewire.org's password:

From here we then enter the password given in the Level Goal, bandit0 (Super secure!) Once you log in you’ll get some rules, tips, and a nice message (and some even nicer ASCII art).

      ,----..            ,----,          .---.
     /   /   \         ,/   .`|         /. ./|
    /   .     :      ,`   .'  :     .--'.  ' ;
   .   /   ;.  \   ;    ;     /    /__./ \ : |
  .   ;   /  ` ; .'___,/    ,' .--'.  '   \' .
  ;   |  ; \ ; | |    :     | /___/ \ |    ' '
  |   :  | ; | ' ;    |.';  ; ;   \  \;      :
  .   |  ' ' ' : `----'  |  |  \   ;  `      |
  '   ;  \; /  |     '   :  ;   .   \    .\  ;
   \   \  ',  /      |   |  '    \   \   ' \ |
    ;   :    /       '   :  |     :   '  |--"
     \   \ .'        ;   |.'       \   \ ;
  www. `---` ver     '---' he       '---" ire.org


Welcome to OverTheWire!

If you find any problems, please report them to the #wargames channel on
discord or IRC.

--[ Playing the games ]--

  This machine might hold several wargames.
  If you are playing "somegame", then:

    * USERNAMES are somegame0, somegame1, ...
    * Most LEVELS are stored in /somegame/.
    * PASSWORDS for each level are stored in /etc/somegame_pass/.

  Write-access to homedirectories is disabled. It is advised to create a
  working directory with a hard-to-guess name in /tmp/.  You can use the
  command "mktemp -d" in order to generate a random and hard to guess
  directory in /tmp/.  Read-access to both /tmp/ is disabled and to /proc
  restricted so that users cannot snoop on eachother. Files and directories
  with easily guessable or short names will be periodically deleted! The /tmp
  directory is regularly wiped.
  Please play nice:

    * don't leave orphan processes running
    * don't leave exploit-files laying around
    * don't annoy other players
    * don't post passwords or spoilers
    * again, DONT POST SPOILERS!
      This includes writeups of your solution on your blog or website!

--[ Tips ]--

  This machine has a 64bit processor and many security-features enabled
  by default, although ASLR has been switched off.  The following
  compiler flags might be interesting:

    -m32                    compile for 32bit
    -fno-stack-protector    disable ProPolice
    -Wl,-z,norelro          disable relro

  In addition, the execstack tool can be used to flag the stack as
  executable on ELF binaries.

  Finally, network-access is limited for most levels by a local
  firewall.

--[ Tools ]--

 For your convenience we have installed a few useful tools which you can find
 in the following locations:

    * gef (https://github.com/hugsy/gef) in /opt/gef/
    * pwndbg (https://github.com/pwndbg/pwndbg) in /opt/pwndbg/
    * peda (https://github.com/longld/peda.git) in /opt/peda/
    * gdbinit (https://github.com/gdbinit/Gdbinit) in /opt/gdbinit/
    * pwntools (https://github.com/Gallopsled/pwntools)
    * radare2 (http://www.radare.org/)

--[ More information ]--

  For more information regarding individual wargames, visit
  http://www.overthewire.org/wargames/

  For support, questions or comments, contact us on discord or IRC.

  Enjoy your stay!

Cool! That’s technically Level 0 done and dusted. Let’s move on.

Level 1

This has the Level Goal of:

The password for the next level is stored in a file called readme located in the home directory. Use this password to log into bandit1 using SSH. Whenever you find a password for a level, use SSH (on port 2220) to log into that level and continue the game.

We’re already logged in as bandit0, so let’s see what is visible to us from location…

bandit0@bandit:~$ ls
readme

There’s the readme file that was mentioned in the Level Goal, let’s cat the contents of the file to grab the password.

bandit0@bandit:~$ cat readme
NH2SXQwcBdpmTEzi3bvBHMM9H66vVXjL

Easy peasy. Now we can exit and log back in to the bandit1 account using the password we just got:

ssh bandit.labs.overthewire.org -l bandit1 -p 2220
                         _                     _ _ _
                        | |__   __ _ _ __   __| (_) |_
                        | '_ \ / _` | '_ \ / _` | | __|
                        | |_) | (_| | | | | (_| | | |_
                        |_.__/ \__,_|_| |_|\__,_|_|\__|


                      This is an OverTheWire game server.
            More information on http://www.overthewire.org/wargames

bandit1@bandit.labs.overthewire.org's password:

After entering the password we’ll get the same welcome message/tips/rules as before, which i’ll omit from here on.

Level 2

The password for the next level is stored in a file called - located in the home directory

This level deals with the cat command. It’s a pretty basic command but it’s good to know how it works for hidden/weirdly named files. We know that the file is named ‘-’ and is in the current directory (using ls), but if we just try to run cat - we won’t see anything.

bandit1@bandit:~$ ls
-
bandit1@bandit:~$ cat -

We know that the file is in the current directory, so we can use the relative path of ‘-’ to cat it.

bandit1@bandit:~$ cat ./-
rRGizSaX8Mk1RTb1CNQoXTcYZWU6lgzi

That worked, and we have the password for the bandit2 account.

Level 3

The password for the next level is stored in a file called spaces in this filename located in the home directory

Let’s log out (with exit) and log back in to bandit2 with the password we just got.

ssh bandit.labs.overthewire.org -l bandit2 -p 2220

This is similar to the above level. We can use the relative path, this time with escape characters (\) for the spaces.

bandit2@bandit:~$ ls
spaces in this filename
bandit2@bandit:~$ cat ./spaces\ in\ this\ filename
aBZ0W5EmUfAf7kHTQeOwd8bauFJ2lAiG

Onwards to the next level!

Level 4

The password for the next level is stored in a hidden file in the inhere directory.

The ls command is usually the first you learn when using Linux. It has a few options, but the only one we need to use for this level is -a. Let’s take a quick look at the man page.

       -a, --all
              do not ignore entries starting with .

Let’s login with the bandit3 account and run ls -a in the inhere directory.

bandit3@bandit:~$ ls -a inhere
.  ..  .hidden

There’s the hidden file, named .hidden. We can just cat this to grab the password for the next level.

bandit3@bandit:~$ cat inhere/.hidden
2EW7BBsr6aMMoJ2HjW067dm8EgX26xNe

Level 5

The password for the next level is stored in the only human-readable file in the inhere directory. Tip: if your terminal is messed up, try the “reset” command.

Interesting level goal. Let’s log in and see what’s happening in the inhere directory.

ssh bandit.labs.overthewire.org -l bandit4 -p 2220
bandit4@bandit:~$ ls inhere
-file00  -file01  -file02  -file03  -file04  -file05  -file06  -file07  -file08  -file09
bandit4@bandit:~$

We can use the file command to get the gist of each file.

bandit4@bandit:~$ file ./inhere/-file*
./inhere/-file00: data
./inhere/-file01: data
./inhere/-file02: data
./inhere/-file03: data
./inhere/-file04: data
./inhere/-file05: data
./inhere/-file06: data
./inhere/-file07: ASCII text
./inhere/-file08: data
./inhere/-file09: data

The file -file07 is the only one that jumps out as containing text, so we’ll grab the password from it.

bandit4@bandit:~$ cat ./inhere/-file07
lrIWWI6bB37kxfiCQZqUdOIYfr6eEeqR

Level 6

The password for the next level is stored in a file somewhere under the inhere directory and has all of the following properties: human-readable 1033 bytes in size not executable

Looks like we’ll need to use the find command for this one! Before we log in, let’s look at the man page for the find command. There’s a lot of options, but I’ll only focus on the ones we need.

       -size
              File uses less than, more than or exactly n units of space, rounding up.  The following suffixes can be used:

              ‘c'    for bytes

       -type f
              File is of type f:

              f      regular file

       -executable
              Matches  files  which are executable and directories which are searchable (in a file name resolution sense) by the current user.

Let’s put that all together. We’ll ssh in using the bandit5 username and password we gathered above. Then run the find command, matching what we know about the file from the level goal. Quick note that we can use ! in front of the -executable option to find something that is not executable. ! is commonly used as shorthand for not.

bandit5@bandit:~$ find -size 1033c -type f ! -executable
./inhere/maybehere07/.file2
bandit5@bandit:~$ cat ./inhere/maybehere07/.file2
P4L4vucdmLnm8I7Vl7jG1ApGSfjYKqJU

The only file that matched all the requirements was maybehere07/.file2. So we can cat that and get the password.

Level 7

The password for the next level is stored somewhere on the server and has all of the following properties: owned by user bandit7 owned by group bandit6 33 bytes in size

This is also similar to the previous level. We can check the man page for find once again to find the options we need.

       -size
              File uses less than, more than or exactly n units of space, rounding up.  The following suffixes can be used:

              ‘c'    for bytes

       -group gname
              File belongs to group gname (numeric group ID allowed).

       -user uname
              File is owned by user uname (numeric user ID allowed).

We can log in to bandit6 and run our new find command. We’ll cd into the root of the filesystem and run a system-wide scan. This is hinted at in the level goal

The password for the next level is stored somewhere on the server

bandit6@bandit:/$ cd /
bandit6@bandit:/$ find -size 33c -group bandit6 -user bandit7 | grep -v find
find: ‘./etc/ssl/private’: Permission denied
find: ‘./etc/polkit-1/localauthority’: Permission denied
find: ‘./etc/sudoers.d’: Permission denied
find: ‘./etc/multipath’: Permission denied
find: ‘./root’: Permission denied
find: ‘./boot/efi’: Permission denied
find: ‘./var/spool/bandit24’: Permission denied
find: ‘./var/spool/cron/crontabs’: Permission denied
find: ‘./var/spool/rsyslog’: Permission denied
find: ‘./var/lib/ubuntu-advantage/apt-esm/var/lib/apt/lists/partial’: Permission denied
find: ‘./var/lib/snapd/cookie’: Permission denied
find: ‘./var/lib/snapd/void’: Permission denied
find: ‘./var/lib/private’: Permission denied
find: ‘./var/lib/chrony’: Permission denied
find: ‘./var/lib/polkit-1’: Permission denied
find: ‘./var/lib/apt/lists/partial’: Permission denied
find: ‘./var/lib/update-notifier/package-data-downloads/partial’: Permission denied
find: ‘./var/lib/amazon’: Permission denied
find: ./var/lib/dpkg/info/bandit7.password
‘./var/log’: Permission denied
find: ‘./var/cache/private’: Permission denied
find: ‘./var/cache/pollinate’: Permission denied
find: ‘./var/cache/apparmor/30d07b40.0’: Permission denied
find: ‘./var/cache/apparmor/a4dd844e.0’: Permission denied
find: ‘./var/cache/apt/archives/partial’: Permission denied
find: ‘./var/cache/ldconfig’: Permission denied

This worked! Except, there’s a lot of errors.

We can use 2> /dev/null to send any errors to /dev/null (AKA The Void). Technically the correct file is in the list above, but going through the whole list would take far too much time.

bandit6@bandit:/$ find -size 33c -group bandit6 -user bandit7 2> /dev/null
./var/lib/dpkg/info/bandit7.password
bandit6@bandit:/$ cat ./var/lib/dpkg/info/bandit7.password
z7WtoNQU2XfjmMtWA8u5rN4vzqu4v99S

Password got, let’s move on.

Level 8

The password for the next level is stored in the file data.txt next to the word millionth

From the sounds of it. We’ll be looking at just the grep command with this level.

We get the hint that the password is ’next to’ the word millionth. We can use the -A option to list the lines after our search term.

bandit.labs.overthewire.org -p 2220 -l bandit7
bandit7@bandit:~$ grep millionth data.txt -A1
millionth       TESKZC0XvTetK0S9xNwm25STk5iWrBvP

That seems to have worked. We can give this password a go when we log into the bandit8 account.

Level 9

The password for the next level is stored in the file data.txt and is the only line of text that occurs only once

I haven’t mentioned until now, but each level also has a ‘Commands you may need to solve this level’ section. These are pretty useful if you come across a level (like this one) that confuses you at first.

At least, it did for me.

I had to do some reading before I eventually read up on the uniq command. Here’s the man page:

DESCRIPTION
       Filter adjacent matching lines from INPUT (or standard input), writing to OUTPUT (or standard output).

       With no options, matching lines are merged to the first occurrence.

       Mandatory arguments to long options are mandatory for short options too.

       -u, --unique
              only print unique lines

Seems like we need to use uniq -u, though if we just try that on the data.txt file…

bandit8@bandit:~$ uniq -u data.txt
kjIuqjobFBhKw9Mmfj2wAnWbXB2VxSfv
5Y76FifuxKStZi4CVovF2uPhgLrZnLzG
AiYd84lOOVTA4gqJPX7f6DH8eG3zwq1W
A16BW831T94qcsYcGDSkgzYhxnX2xUdK
vlsSKqk3yVx2PZxIkBuZPR3KKIf8hGi1
cEqNrEqHVIIi9fQKdcvAxaip1brmsSxT
FQIgwPiuPKftkFhIy9Nzm94sWdNGTlHd
P8jd7Kr8GXVKTLhe1Y7cVYAARwh4lN4A
Rlaj8VWIHkYsAg42TsFplgAd4ekjgR2X
365RauAVsFlxktPMpoLtIf1uxijU1TfV
KYISscbRkhzx8A10I54jgdbq1sEO98lG
ahwL1iJ5EDLt9wpBjrP2DY8pv6FLdrLy
swXvCokPAhVazCnl9rPeLXWYHIC5yj8h

Doesn’t seem to be working.

The uniq command is often used with sort. So we’ll first sort the text, then just find unique entries.

bandit8@bandit:~$ sort data.txt | uniq -u
EN632PlfYiZbn3PhVK3XOGSlNInNE00t

Easy peasy.

Level 10

The password for the next level is stored in the file data.txt in one of the few human-readable strings, preceded by several ‘=’ characters.

Well, we know that there are several ’=’ characters ahead of the password, so we can just grep for that and hope for the best!

bandit9@bandit:~$ grep ==== data.txt
grep: data.txt: binary file matches

That’s not what we want. What if we try escape the ‘=’ character?

bandit9@bandit:~$ grep \=\=\=\= data.txt
grep: data.txt: binary file matches

Foiled again.

I did some digging (on StackOverflow this time, check out my previous post about that…) and found this thread.

Let’s give that a shot, using the -F option with grep

bandit9@bandit:~$ grep -F '====' data.txt
grep: data.txt: binary file matches

Still getting the same message. What does that actually mean though? I searched this up (once again finding a StackOverflow thread). It seems like because this is a binary file (maybe? Or the text is) grep will not output anything.

We can use -a or --text to display this properly.

andit9@bandit:~$ grep \=\=\=\= data.txt -a
"x����$�WI��G���gq��B�ș�q6�p�|r9����K�|��[�l������#0jb�7u��uf`e�Y�▒o�   ?>��?�▒��F��){�x%�1�c3  ��l�XQz�U0��
                                                                                                            ��O-@����E�8�jr��i��$�]�:[������x]T========== theG)"�)<�!G���{��X8�?��5�&���O:�@N��s~�i\6�Xz    ����==��S�igy�����>�m���P�I�ݰ���C+x�[ڋ�e▒22�a�
�{��\nF���<��D� �M�f*I�`��@oݗn�ײ�p�n��Y�����x�n��▒���ۓ�4j\9̷�n:�J�Va���K��▒+     ����f��Z9�)��Q�Ѻ?��r��.���O[��6�^FS�========== passwordk^�ټ�����1>���jg�▒S�>�����5~�I▒�-�"��G|�����6L�"�� �T�'�����j�T=������2_�q+T6(�p
                                                                                                   '
�T����T�p#fz:�LJ�r*;�o#�E�hϻ��/]��&x��:!�Oη��[%ug�Z��▒hݹkj��D����▒ZH���Ed����ZE������4K�?�p������z�iw?������J�������^`t d�;T��ڪ`��M�T�/�j�M�Ł��$����O�Ms▒h��������8��========== is�w
.�Ze�x��J���i���_qhlbw���X�yϪ�.�-3������7�T��                  K▒e@�&,]D���%�v�
��g����yV�M]��Vf��̤��i�L�u#�&ZR�7٬.׳?L6>�D�▒GC�:jЂ��}��=��T�k�@I]j5�}0Ļ�_�zW5E��f3c�ᦩ�a��Ozݏ������:�Dr%[+��*2lk���X�齲g/$�%��g�Z"g��x�
A�tL[��#��Ƴ���wv..ک!�5��nH�mwQ!2�w�Fu�cp��B�;ݍ�UH�NEz+�w�'�w$F��6�L�l��ܤ
�(���k�}�N l�E������*�9�<u2����_0�Y���4�`▒�w�j:6�ek�{OXr���/��?d��mH�m�3�EM`��om�x��۽��>���Ihe�X��N�tz�xb�(X�1��oPZ�ɱ�ݿQ��{▒�%�xV��{TbJ;=l��J�Q�/��,��??r)SՒ98UU��jߗc-�?4���6�[�$�J��S��ۿv��P��u$��4+�2ʾ�$�oI�[=lI���a6�ȁ
                                                                                                     ×/%Â���w�����l�u-)E��f���n���%��Ƙ�p��~��L�]wPP�J��O1#�{"@Ip�I�2��Di�����T�m�Gf�rSa
���LN�|�r1�7�6��8������<D�_o��kV�Jx�#���[�����딭��E�����O.x�s�薲�Ҋ����I��t�.�RF�L�V¡G�D�5c
                                                                                          %�0d�������^b�C�EX��I��,S߫��)o��8/�-��ďRj$�e0G�rx70yJ{��|Ƞ��ÒX     5��a���C�2�����{�5���8+�dm)��R��
                                                                        |�q����E▒�C��[�qX2R^{X�����WH   fU�����B�|��������j��n�c�����`����yq��      ����������E�0�Mhr��Xw��<Ͱ�[     �N�iޑ2KYl��A���)�#pJ_�)�]�PJoZP�EW��-"�ְ��D��Yq5� �G^xu�,-ҏ����i�o}2��j��Ֆ�����[:ˇ52��)"t    jh�y��========== G7w8LIi6J3kTb8A7j9LgrywtEUlyyp6s

This immediately jumped out to me when I saw it, but i’ll clean the output up a bit.

========== theG)"�)<�!G���{��X8�??��r��.���O[��6�^FS�========== passwordk^�ټ�����1>���jg�▒S�>�����5~�I▒�-�"��G|�����6L�"
========== is�w
.   jh�y�========== G7w8LIi6J3kTb8A7j9LgrywtEUlyyp6s

(I’ve still kept some of the useless stuff in there, I hope I made it clear what the password was though)

Onto the next one!

Level 11

The password for the next level is stored in the file data.txt, which contains base64 encoded data

I’ve worked with base64 strings before at work, so I already know that they will often end with ‘==’. (The output padding)

So we’ll just grep the data.txt file for that and see what we get. We already know that it’s encoded in base64, so we can pipe this into base64 -d

bandit10@bandit:~$ grep \=\= data.txt | base64 -d
The password is 6zPeziLdR2RKNdNYFNb6nVCKzphlXHBM

Another easy level!

Level 12

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

This shit boggled my mind for a moment. I know what ROT13 is, but i’ve never decoded it using linux before.

One of the suggested commands is tr. Let’s have a looksee at the man page:

NAME
       tr - translate or delete characters

DESCRIPTION
       Translate, squeeze, and/or delete characters from standard input, writing to standard output.  STRING1 and
       STRING2 specify arrays of characters ARRAY1 and ARRAY2 that control the action.

This seems like the answer. Wikipedia has a [neat page](https://en.wikipedia.org/wiki/Tr_(Unix)) on the tr command which helps to clear it up, but searching ‘rot13 linux’ will also set you on the right track.

If we rotate the alphabet by 13, A becomes N, B becomes O, etc etc. We can show this with the tr command like so;

tr 'A-Za-z' 'N-ZA-Mn-za-m'

In the lab itself we can get the password using the above line:

bandit11@bandit:~$ cat data.txt
Gur cnffjbeq vf WIAOOSFzMjXXBC0KoSKBbJ8puQm5lIEi
bandit11@bandit:~$ cat data.txt | tr 'A-Za-z' 'N-ZA-Mn-za-m'
The password is JVNBBFSmZwKKOP0XbFXOoW8chDz5yVRv

Level 13

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!)

The /tmp directory is periodically deleted, so you don’t need to worry about your work being leaked. Please note not to put any private infomation in there though…

If we just cat the data.txt file, we’ll get the below:

bandit12@bandit:~$ cat data.txt
00000000: 1f8b 0808 6855 1e65 0203 6461 7461 322e  ....hU.e..data2.
00000010: 6269 6e00 013d 02c2 fd42 5a68 3931 4159  bin..=...BZh91AY
00000020: 2653 5948 1b32 0200 0019 ffff faee cff7  &SYH.2..........
00000030: f6ff e4f7 bfbc ffff bff7 ffb9 39ff 7ffb  ............9...
00000040: bd31 eeff b9fb fbbb b9bf f77f b001 3b2c  .1............;,
00000050: d100 0d03 d200 6868 0d00 0069 a00d 0340  ......hh...i...@
00000060: 1a68 00d0 0d01 a1a0 0001 a680 0003 46d4  .h............F.
00000070: 6434 3234 611a 340d 07a4 c351 068f 5000  d424a.4....Q..P.
00000080: 069a 0680 0000 0006 8006 8da4 681a 6868  ............h.hh
00000090: 0d06 8d00 6834 3400 d07a 9a00 01a0 0341  ....h44..z.....A
000000a0: ea1e a190 da40 3d10 ca68 3468 6800 00c8  .....@=..h4hh...
000000b0: 1a1a 1b50 0683 d434 d069 a0d0 3100 d000  ...P...4.i..1...
000000c0: 001e a680 00d0 1a00 d0d0 6864 d0c4 d0d0  ..........hd....
000000d0: 000c 8641 7440 0108 032e 86b4 4cf0 22bb  ...At@......L.".
000000e0: 6682 2b7e b3e2 e98d aa74 dacc 0284 330d  f.+~.....t....3.
000000f0: bbb2 9494 d332 d933 642a 3538 d27e 09ce  .....2.3d*58.~..
00000100: 53da 185a 505e aada 6c75 59a2 b342 0572  S..ZP^..luY..B.r
00000110: 249a 4600 5021 25b0 1973 c18a 6881 1bef  $.F.P!%..s..h...
00000120: 3f9b 1429 5b1d 3d87 68b5 804f 1d28 42fa  ?..)[.=.h..O.(B.
00000130: 16c2 3241 98fb 8229 e274 5a63 fe92 3aca  ..2A...).tZc..:.
00000140: 70c3 a329 d21f 41e0 5a10 08cb 888f 30df  p..)..A.Z.....0.
00000150: f3da ce85 418b 0379 6a65 cfa2 eeb7 9f01  ....A..yje......
00000160: 782c da0e 288b e0c3 fe13 7af5 45ab 2b22  x,..(.....z.E.+"
00000170: a432 bf2f e32d b9e6 1465 2296 d805 a45e  .2./.-...e"....^
00000180: d1c1 eacb 7483 6aac ca0e cf24 8864 bd40  ....t.j....$.d.@
00000190: 118c 644a 1dc6 a127 375c b7a6 c124 bdae  ..dJ...'7\...$..
000001a0: 6d31 63a0 a223 3ea0 61d4 bdf0 450f 56fb  m1c..#>.a...E.V.
000001b0: a546 8d34 08a2 4f1d 43d3 9063 404d dd43  .F.4..O.C..c@M.C
000001c0: b4f2 e65d bcb7 5932 0f5e 6802 3892 a988  ...]..Y2.^h.8...
000001d0: 443d 8e89 7e09 4fb0 499d ee4e 4470 46c0  D=..~.O.I..NDpF.
000001e0: 2ba6 7c62 234a 7f76 151b aec0 23ee 4a97  +.|b#J.v....#.J.
000001f0: bc64 e34c de8a 5724 a1c3 9b89 cd96 1879  .d.L..W$.......y
00000200: d560 0cbb 5c26 09e4 efaf 5b94 402a 7780  .`..\&....[.@*w.
00000210: 4d87 30ce b8a3 946e 72c1 a643 1db7 a060  M.0....nr..C...`
00000220: 6524 629c 0c7e 8e7b e0f8 820c d5cb 60a0  e$b..~.{......`.
00000230: 003c a584 d4c1 61ef eb02 3f65 3a54 a3a2  .<....a...?e:T..
00000240: a565 c154 34c2 b162 d206 1ff8 bb92 29c2  .e.T4..b......).
00000250: 8482 40d9 9010 b3a9 e478 3d02 0000       ..@......x=...

Love me a good hexdump.

The suggested reading for this lab is the wikipedia entry on hex dumps. It’s a pretty boring read, but it does mention xxd as a tool, which is suggested in the commands to use.

Let’s first make a directory in the /tmp/ location, then copy the data.txt file into it.

bandit12@bandit:~$ mkdir /tmp/ligni/
bandit12@bandit:~$ cp data.txt /tmp/ligni/

Now what?

Let’s check the man page of xxd and see what it does.

NAME
       xxd - make a hexdump or do the reverse.

       -r | -revert
              Reverse operation: convert (or patch) hexdump into binary.  If not writing to stdout, xxd writes into its output file without truncating it. Use the combination -r -p to read plain hexadecimal dumps without line num‐
              ber information and without a particular column layout. Additional Whitespace and line-breaks are allowed anywhere.

Looks like a good starting point. Let’s give it a shot!

bandit12@bandit:/tmp/ligni$ xxd -r data.txt > reversed
bandit12@bandit:/tmp/ligni$ cat reversed
�h44�z��A����@=�h4hh�▒▒�)[=�h��O(B��2A���)�tZc��:�pã)�A�ˈ�0���΅A�yjeϢx,�(����z�E�+"�2�/�-��e"���^����t�j���$�d�@�dJơ'7\���$��m1c��#>�aԽ�EV��F��OCӐc@M�C���]��Y2^h8���D=��~ O�I��NDpF�+�|b#Jv��d�LފW$�Û�͖▒y�`
                                                                                        �\&     ���[�@*w�M�0�nr��C��`e$b�
       ~�{���
             ��`�<����a��?e:T���e�T4±b����)�@ِ���x=bandit12@bandit:/tmp/ligni$

I tried skipping ahead and hoped that it was just a hexdump, but in the level goal it specifically states ‘a hexdump of a file that has been repeatedly compressed’.

We can use gzip here to unzip it.

bandit12@bandit:/tmp/ligni$ gzip -d ./reversed
gzip: ./reversed: unknown suffix -- ignored
bandit12@bandit:/tmp/ligni$ mv reversed reversed.gz
bandit12@bandit:/tmp/ligni$ gzip -d reversed.gz

I didn’t realize (until now) that gzip -d or gunzip only really works if there’s a .gz file present. Good to know going forwards.

If we take a closer look at the reversed file we see it’s not a bzip-ed compressed file.

bandit12@bandit:/tmp/ligni$ file reversed
reversed: bzip2 compressed data, block size = 900k

We’ll do the same as we did with the gzip-ed file:

bandit12@bandit:/tmp/ligni$ bzip2 -d reversed
bzip2: Can't guess original name for reversed -- using reversed.out

Then the same for the new reversed.out file (And all the compressions done):

bandit12@bandit:/tmp/ligni$ file reversed.out
reversed.out: gzip compressed data, was "data4.bin", last modified: Thu Oct  5 06:19:20 2023, max compression, from Unix, original size modulo 2^32 20480
bandit12@bandit:/tmp/ligni$ mv reversed.out reversed.out.gz
bandit12@bandit:/tmp/ligni$ gzip -d reversed.out.gz
bandit12@bandit:/tmp/ligni$ file reversed.out
reversed.out: POSIX tar archive (GNU)
bandit12@bandit:/tmp/ligni$ tar -xf reversed.out
bandit12@bandit:/tmp/ligni$ ls
data5.bin  data.txt  file  reversed.out
bandit12@bandit:/tmp/ligni$ file data5.bin
data5.bin: POSIX tar archive (GNU)
bandit12@bandit:/tmp/ligni$ tar -xf data5.bin
bandit12@bandit:/tmp/ligni$ ls
data5.bin  data6.bin  data.txt  file  reversed.out
bandit12@bandit:/tmp/ligni$ file data6.bin
data6.bin: bzip2 compressed data, block size = 900k
bandit12@bandit:/tmp/ligni$ bzip2 -d data6.bin
bzip2: Can't guess original name for data6.bin -- using data6.bin.out
bandit12@bandit:/tmp/ligni$ file data6.bin.out
data6.bin.out: POSIX tar archive (GNU)
bandit12@bandit:/tmp/ligni$ tar -xf data6.bin.out
bandit12@bandit:/tmp/ligni$ ls
data5.bin  data6.bin.out  data8.bin  data.txt  file  reversed.out
bandit12@bandit:/tmp/ligni$ file data8.bin
data8.bin: gzip compressed data, was "data9.bin", last modified: Thu Oct  5 06:19:20 2023, max compression, from Unix, original size modulo 2^32 49
bandit12@bandit:/tmp/ligni$ mv data8.bin data8.bin.gz
bandit12@bandit:/tmp/ligni$ gzip -d data8.bin.gz
bandit12@bandit:/tmp/ligni$ file data8.bin
data8.bin: ASCII text
bandit12@bandit:/tmp/ligni$ cat data8.bin
The password is wbWdlBxEir4CaE8LaPhauuOo6pwRmrDw

Wow, that was a lot of compresison. The file command was very helpful here in identifing which tool we should use!

Level 14

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

SSH time!

I’ll be honest I had no clue what to do here. This blog post has been written over a month or two. Between level 13 and 14 there was about a month of… not doing the wargames.

Anyway, enough about ligniform’s life. Let’s get to the hacking.

Let’s not properly read the level goal and just try read the file

bandit13@bandit:~$ cd /etc/bandit_pass/
bandit13@bandit:/etc/bandit_pass$ cat bandit14
cat: bandit14: Permission denied

Okay, that won’t work.

Let’s look in the home directory for anything that might help us out.

bandit13@bandit:/etc/bandit_pass$ cd ~/
bandit13@bandit:~$ ls
sshkey.private

Okay, we have an ssh key now. We can download that locally and use it to ssh in as the bandit14 user.

bandit13@bandit:~$ scp ./sshkey.private .
cp: './sshkey.private' and './sshkey.private' are the same file
bandit13@bandit:~$ scp ./sshkey.private localhost
cp: cannot create regular file 'localhost': Permission denied

Or not.

I tried downloading this ssh key locally but it… doesn’t really seem to be working. Time to ssh while already ssh-ing!

bandit13@bandit:~$ ssh bandit14@bandit.labs.overthewire.org -p 2220 -i ./sshkey.private
The authenticity of host '[bandit.labs.overthewire.org]:2220 ([127.0.0.1]:2220)' can't be established.
ED25519 key fingerprint is SHA256:C2ihUBV7ihnV1wUXRb4RrEcLfXC5CXlhmAAM/urerLY.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
bandit14@bandit:~$ whoami
bandit14

Yay, we’re… In? Time to grab the flag located in /etc/bandit_pass/bandit14 as per the level goal.

bandit14@bandit:~$ cat /etc/bandit_pass/bandit14
fGrHPx402xGC7U7rXKDaxiWFTOiF0ENq

Level 15

The password for the next level can be retrieved by submitting the password of the current level to port 30000 on localhost.

One of the suggested commands is telnet, which I’ve had a little bit of experience with.

bandit14@bandit:~$ telnet localhost 30000
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
fGrHPx402xGC7U7rXKDaxiWFTOiF0ENq
Correct!

Connection closed by foreign host.

Thanks to my previous experience with telnet I found this level pretty easy. I’ve seen writeups using netcat to do this too.

Level 16

The password for the next level can be retrieved by submitting the password of the current level to port 30001 on localhost using SSL encryption.

The first thing I did was search for sending data using SSL encryption on DDG. The first site I saw seemed pretty promising.

bandit15@bandit:~$ openssl s_client -connect localhost:30001 -ign_eof
CONNECTED(00000003)
Can't use SSL_get_servername
depth=0 CN = localhost
verify error:num=18:self-signed certificate
verify return:1
depth=0 CN = localhost
verify error:num=10:certificate has expired
notAfter=Mar 19 15:48:54 2024 GMT
verify return:1
depth=0 CN = localhost
notAfter=Mar 19 15:48:54 2024 GMT
verify return:1
---
(We get a bunch of certificate stuff here, I'll skip to entering the password)
jN2kgmIXJ6fShzhT2avhotn4Zcka6tnt
Correct!
JQttfApK4SeyHwDlI9SXGR50qclOAil1

closed
bandit15@bandit:~$

Yay, password for bandit17 got!


Conclusion

That’s it! For now anyway.

This is the halfway point in the ‘bandit’ rooms.

It’s been fun writing this! It’s also been fun doing the labs. As I said in my stack overflow blogpost, the best way to learn is by just doing it yourself.

I have added the passwords for each level, but if you’ve made it this far I encourage you to not use the passwords and to find them yourself.

That’s all for this blog post. Thanks for reading!