Contents

OverTheWire Bandit

OverTheWire Bandit is a capture the flag (CTF) game for beginners. I’ve recently regained interest in security and found this a fun way to get back into what originally led me to learn programming. These are quick notes for my solutions on level 0-27.

Level 0 -> Level 1

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.

→ ssh bandit.labs.overthewire.org -p 2220 -l bandit0
bandit0@bandit:~$ ls -al
total 24
drwxr-xr-x  2 root    root    4096 Nov 13 15:58 .
drwxr-xr-x 29 root    root    4096 Nov 13 15:57 ..
-rw-r--r--  1 root    root     220 Sep  1  2015 .bash_logout
-rw-r--r--  1 root    root    3771 Sep  1  2015 .bashrc
-rw-r--r--  1 root    root     655 Jun 24  2016 .profile
-rw-r-----  1 bandit1 bandit0   33 Nov 13 15:58 readme
bandit0@bandit:~$ cat readme
boJ9jbbUNNfktd78OOpsqOltutMc3MY1

Level 1 -> Level 2

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

bandit1@bandit:~$ cat ./-
CV1DtqXWVFXTvM2F0k09SHz0YwRINYA9

Level 2 -> Level 3

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

bandit2@bandit:~$ cat spaces\ in\ this\ filename
UmHadQclWmgdLOKQ3YNgjWxGoRMb5luK

Level 3 -> Level 4

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

bandit3@bandit:~$ cd inhere
bandit3@bandit:~/inhere$ ls -al
total 12
drwxr-xr-x 2 root    root    4096 Nov 13 15:58 .
drwxr-xr-x 3 root    root    4096 Nov 13 15:58 ..
-rw-r----- 1 bandit4 bandit3   33 Nov 13 15:58 .hidden
bandit3@bandit:~/inhere$ cat .hidden
pIwrPrtPN36QITSp3EQaw936yaFoFgAB

Level 4 -> 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.

I decided to use the file command to determine which files are human-readable.

bandit4@bandit:~/inhere$ file ./*
./-file00: data
./-file01: data
./-file02: data
./-file03: data
./-file04: data
./-file05: data
./-file06: data
./-file07: ASCII text
./-file08: data
./-file09: data
bandit4@bandit:~/inhere$ file ./* | grep "ASCII text"
./-file07: ASCII text
bandit4@bandit:~/inhere$ ls -al
total 48
-rw-r----- 1 bandit5 bandit4   33 Nov 13 15:58 -file00
-rw-r----- 1 bandit5 bandit4   33 Nov 13 15:58 -file01
-rw-r----- 1 bandit5 bandit4   33 Nov 13 15:58 -file02
-rw-r----- 1 bandit5 bandit4   33 Nov 13 15:58 -file03
-rw-r----- 1 bandit5 bandit4   33 Nov 13 15:58 -file04
-rw-r----- 1 bandit5 bandit4   33 Nov 13 15:58 -file05
-rw-r----- 1 bandit5 bandit4   33 Nov 13 15:58 -file06
-rw-r----- 1 bandit5 bandit4   33 Nov 13 15:58 -file07
-rw-r----- 1 bandit5 bandit4   33 Nov 13 15:58 -file08
-rw-r----- 1 bandit5 bandit4   33 Nov 13 15:58 -file09
drwxr-xr-x 2 root    root    4096 Nov 13 15:58 .
drwxr-xr-x 3 root    root    4096 Nov 13 15:58 ..
bandit4@bandit:~/inhere$ file ./* | grep "ASCII text"
./-file07: ASCII text
bandit4@bandit:~/inhere$ cat ./-file07
koReBOKuIDDepwhWk7jZC0RTdopnAYKh

Level 5 -> 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

I looked for files with size 1033 bytes that are not executable. Since I only returned one output, I’m able to check to see if it’s human-readable using cat.

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

Level 6 -> 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

Using find again with the arguments that fit the above requirements. I routed all STDERR outputs to /dev/null for a cleaner output.

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

Level 7 -> Level 8

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

Using grep to see what the file looks like around the word ‘millionth’. Once I had a sense of how the file is structured, I used awk to get my desired output.

bandit7@bandit:~$ grep -C 3 millionth data.txt
go  vilygVSBNRzRXSZFzIeSbajhHHRrjgln
controversially p1JE4gkWuFxTpk55Zfo3xqLe3RqhWtHX
conspiracies    tbkj5iLjadNfPTCslAvnU9nyFeHBfu1o
millionth   cvX2JJa4CFALtqS87jk27qwqGhBM9plV
wardrooms   ERG4eyK8q5eIP554LQysscc5oQuEGV8c
admissions  4vOZpSuzFUMNqJtrXVcNaheXuGDbrPCo
wearying    kS75kziqMp5mUopzJTKaJRf0SIBDWLGf
bandit7@bandit:~$ awk '/millionth/ {print $2}' data.txt
cvX2JJa4CFALtqS87jk27qwqGhBM9plV

Level 8 -> 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.

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

Level 9 -> Level 10

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

strings prints out human-readable strings. My initial output using regex filtering was missing the password, so I used a simpler search.

bandit9@bandit:~$ strings data.txt | grep -e "^[=+]"
========== theOkM
=hrV`
========== password
========== is
+3CMz
=GUl
+xOU
=/wW
bandit9@bandit:~$ strings data.txt | grep =
========== theOkM
L=8@
=hrV`
========== password
========== is
H)=QU
>]".x=
{=u/,i_
{=jh
=GUl
e=y:
4H5=
)========== truKLdjsbJ5g7yyJ2X2R0o3a5HQJFuLk
=/wW
~BX=

Level 10 -> Level 11

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

bandit10@bandit:~$ base64 -d data.txt
The password is IFukwKGsFW8MOq3IRFqrxE1hxTNEbUPR

Level 11 -> 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.

[https://en.wikipedia.org/wiki/ROT13]ROT13(https://en.wikipedia.org/wiki/ROT13) is a simple cipher where you rotate 13 places. I used tr to shift my text by 13 letters.

bandit11@bandit:~$ cat data.txt | tr 'A-Za-z' 'N-ZA-Mn-za-m'
The password is 5Te8Y4drgCRfCx8ugdwuEX8KFC6k2EUu

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

As recommended, I created a new directory and copied the file to it.

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

Since this is a hexdump, I used xxd to convert it back to the original binary. then checked its file type.

bandit12@bandit:/tmp/bandit12data$ xxd -r data.txt data.orig
bandit12@bandit:/tmp/bandit12data$ file data.orig
data.orig: gzip compressed data, was "data2.bin", last modified: Mon Nov 13 14:58:07 2017, max compression, from Unix

For gzip, I used zcat to output the decompressed file to one with the original name since I did not want to continually change the suffix. I then check the file information to see what it was compressed with and used the corresponding tool to decompress. Many decompressions later…

bandit12@bandit:/tmp/bandit12data$ gzip -d data.orig
gzip: data.orig: unknown suffix -- ignored
bandit12@bandit:/tmp/bandit12data$ zcat data.orig > data2.bin
bandit12@bandit:/tmp/bandit12data$ file data2.bin
data2.bin: bzip2 compressed data, block size = 900k
bandit12@bandit:/tmp/bandit12data$ bzip2 -d data2.bin
bzip2: Can't guess original name for data2.bin -- using data2.bin.out
bandit12@bandit:/tmp/bandit12data$ file data2.bin.out
data2.bin.out: gzip compressed data, was "data4.bin", last modified: Mon Nov 13 14:58:07 2017, max compression, from Unix
bandit12@bandit:/tmp/bandit12data$ zcat data2.bin.out > data4.bin
bandit12@bandit:/tmp/bandit12data$ file data4.bin
data4.bin: POSIX tar archive (GNU)
bandit12@bandit:/tmp/bandit12data$ tar -xvf data4.bin
data5.bin
bandit12@bandit:/tmp/bandit12data$ file data5.bin
data5.bin: POSIX tar archive (GNU)
bandit12@bandit:/tmp/bandit12data$ tar -xvf data5.bin
data6.bin
bandit12@bandit:/tmp/bandit12data$ file data6.bin
data6.bin: bzip2 compressed data, block size = 900k
bandit12@bandit:/tmp/bandit12data$ bzip2 -d data6.bin
bzip2: Can't guess original name for data6.bin -- using data6.bin.out
bandit12@bandit:/tmp/bandit12data$ file data6.bin.out
data6.bin.out: POSIX tar archive (GNU)
bandit12@bandit:/tmp/bandit12data$ tar -xvf data6.bin.out
data8.bin
bandit12@bandit:/tmp/bandit12data$ file data8.bin
data8.bin: gzip compressed data, was "data9.bin", last modified: Mon Nov 13 14:58:07 2017, max compression, from Unix
bandit12@bandit:/tmp/bandit12data$ zcat data8.bin > data9.bin
bandit12@bandit:/tmp/bandit12data$ file data9.bin
data9.bin: ASCII text
bandit12@bandit:/tmp/bandit12data$ cat data9.bin
The password is 8ZjyCRiBWFYkneahHwxCv3wb2a1ORpYL

Level 13 -> 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.

bandit13@bandit:~$ ls -al
total 24
drwxr-xr-x  2 root     root     4096 Nov 13 15:58 .
drwxr-xr-x 29 root     root     4096 Nov 13 15:57 ..
-rw-r--r--  1 root     root      220 Sep  1  2015 .bash_logout
-rw-r--r--  1 root     root     3771 Sep  1  2015 .bashrc
-rw-r--r--  1 root     root      655 Jun 24  2016 .profile
-rw-r-----  1 bandit14 bandit13 1679 Nov 13 15:58 sshkey.private
bandit13@bandit:~$ cat sshkey.private
[REDACTED]
bandit13@bandit:~$ ssh -i sshkey.private bandit14@localhost
bandit14@bandit:~$ cat /etc/bandit_pass/bandit14
4wcYUJFw0k0XLShlDzztnTBHiqxU3b3e

Level 14 -> Level 15

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

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

Connection closed by foreign host.

Level 15 -> 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.

bandit15@bandit:~$ openssl s_client -connect localhost:30001 -ign_eof
CONNECTED(00000003)
depth=0 CN = bandit
verify error:num=18:self signed certificate
verify return:1
depth=0 CN = bandit
verify return:1
---
Certificate chain
 0 s:/CN=bandit
   i:/CN=bandit
---
Server certificate
-----BEGIN CERTIFICATE-----
MIICsjCCAZqgAwIBAgIJAOiKeDKsXb/8MA0GCSqGSIb3DQEBCwUAMBExDzANBgNV
BAMMBmJhbmRpdDAeFw0xNzExMTEyMDA1MTJaFw0yNzExMDkyMDA1MTJaMBExDzAN
BgNVBAMMBmJhbmRpdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM94
fvfAy+PhF9WCKwCmMccdSooUfl2xTxwJ7l6tE9/uMc43CeCskmUhp6B5VQB5yVqs
nLBmDpBaDN66XqlzGTyB9gEDELOtYsX20Y48Sd7t/OY3xSV/uIkv+hU10lKSMPd/
khxVjoVdebWoTJkwOz6HX0AvaTbDSRG6oBJ4m99ssNZXGymDjENXESkNeOuxKkGH
wIlb6oNLdNTnVWcDtQF6bIofS8v6dRHykKekQ4y9ml7/FzhQJlTMymfSo48GgbNf
PWs8KMHMoCSs9byWXHs5OUScqXdC6aC7onRNODSv1/gZiwBFIjvq8+nlj7P8XgTy
OqsPvIz+FAS8EvcXH0cCAwEAAaMNMAswCQYDVR0TBAIwADANBgkqhkiG9w0BAQsF
AAOCAQEAxD1vr08ahuVDmr3/CHuQUX7w/K3pevWJcjh8xd3Zxbv4WdIEXMrIBMHI
lcmTW2z7ZqcEfnCgbqWjY7Dy1N1JN7fvkUDpJhEdYPzdr6XHlSAO+oqEy27J94xl
a8hwBJg+euFrJ5jwIU7hZqsEWppNm0uZofSlOWcue3q7V8e7dcJWo6lArPjtMWWD
DG2DPDNBIuWktcrQj6eT28Voxjn6iM2ivUWJqsvFSpQ/xwionp8A3ZfiagJKGt/C
4I1QAOqIGVLqOCP+vAjB2utsRP51vXxAeEDu/3hE9Azk/Ap0Z3Nb8XrLSNyfUUm/
oi8cAsr0CunA8qK/B6cVEHm6837xIQ==
-----END CERTIFICATE-----
subject=/CN=bandit
issuer=/CN=bandit
---
No client certificate CA names sent
---
SSL handshake has read 1015 bytes and written 631 bytes
---
New, TLSv1/SSLv3, Cipher is AES128-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1
    Cipher    : AES128-SHA
    Session-ID: 36C277A25E05CBC7F1B468EBD5A4CACE1D5EF117F89E78CBAB122B3EF8A1DD23
    Session-ID-ctx:
    Master-Key: C72B2568A031FC5C3773DA8386058F770C0CEDDB70A5878FC232C9DA8C0F510F45F70D96913F7AFABB7DC4684CAA2B35
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 7200 (seconds)
    TLS session ticket:
    0000 - 8d 8d 08 76 bd 8b dc 4e-f1 f1 6b ed 03 44 22 c5   ...v...N..k..D".
    0010 - a2 c4 d0 9a de fa 4b 9f-a3 df 92 4a 73 f0 08 6d   ......K....Js..m
    0020 - c0 51 85 d0 51 84 30 b5-e7 57 fb c5 fd be 04 2a   .Q..Q.0..W.....*
    0030 - 31 63 59 03 9a ac b8 b5-ce 82 78 72 67 d7 63 78   1cY.......xrg.cx
    0040 - d6 93 b1 c5 4a de 52 de-91 6c 28 03 f6 aa 86 06   ....J.R..l(.....
    0050 - b8 5f 1e 09 52 be a0 21-92 f4 a6 01 05 fd ca e2   ._..R..!........
    0060 - 36 b7 26 28 6c 1a 75 98-b4 12 5d 18 d6 43 52 e7   6.&(l.u...]..CR.
    0070 - a5 22 bc d4 36 a1 49 da-c7 7f db a7 5d ed 2c 7a   ."..6.I.....].,z
    0080 - 87 c1 53 88 75 51 2b 0a-36 d5 03 69 b3 13 f1 f1   ..S.uQ+.6..i....
    0090 - ee 73 6e ca 2a 9d 8a 26-ae b5 20 8b 71 f9 09 06   .sn.*..&.. .q...

    Start Time: 1514325241
    Timeout   : 300 (sec)
    Verify return code: 18 (self signed certificate)
---
BfMYroe26WYalil77FoDi9qh59eK5xNr
Correct!
cluFn7wTiGryunymYOu4RcffSxQluehd

closed

Level 16 -> Level 17

The credentials for the next level can be retrieved by submitting the password of the current level to a port on localhost in the range 31000 to 32000. First find out which of these ports have a server listening on them. Then find out which of those speak SSL and which don’t. There is only 1 server that will give the next credentials, the others will simply send back to you whatever you send to it.

First I scanned the port range to see which ports were open and supports SSLv3.

bandit16@bandit:~$ nmap --script ssl-enum-ciphers -p 31000-32000 localhost

Starting Nmap 7.01 ( https://nmap.org ) at 2017-12-26 23:36 CET
Nmap scan report for localhost (127.0.0.1)
Host is up (0.00015s latency).
Other addresses for localhost (not scanned): ::1
Not shown: 996 closed ports
PORT      STATE SERVICE
31046/tcp open  unknown
31518/tcp open  unknown
| ssl-enum-ciphers:
|   TLSv1.0:
|     ciphers:
|       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|     compressors:
|       NULL
|     cipher preference: indeterminate
|     cipher preference error: Too few ciphers supported
|_  least strength: A
31691/tcp open  unknown
31790/tcp open  unknown
| ssl-enum-ciphers:
|   TLSv1.0:
|     ciphers:
|       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|     compressors:
|       NULL
|     cipher preference: indeterminate
|     cipher preference error: Too few ciphers supported
|_  least strength: A
31960/tcp open  unknown

Nmap done: 1 IP address (1 host up) scanned in 0.84 seconds

I only have 2 ports returned, so I manually tested them.

bandit16@bandit:~$ echo cluFn7wTiGryunymYOu4RcffSxQluehd | openssl s_client -connect localhost:31518 -ign_eof
bandit16@bandit:~$ echo cluFn7wTiGryunymYOu4RcffSxQluehd | openssl s_client -connect localhost:31790 -ign_eof

The latter yieled an RSA private key which I saved to a file and used to ssh into level 17.

bandit16@bandit:/tmp$ mkdir /tmp/bandit17
bandit16@bandit:/tmp$ cd /tmp/bandit17
bandit16@bandit:/tmp$ vim id_rsa
bandit16@bandit:/tmp$ chmod 600 id_rsa
bandit16@bandit:/tmp$ ssh -i id_rsa bandit17@localhost

Level 17 -> Level 18

There are 2 files in the homedirectory: passwords.old and passwords.new. The password for the next level is in passwords.new and is the only line that has been changed between passwords.old and passwords.new

bandit17@bandit:~$ diff passwords.new passwords.old
42c42
< kfBf3eYk5BPBRzwjqutbbfE887SVc5Yd
---
> 7cDk1R96wgw11eEuTk1zgbjAindhpUA5

Level 18 -> Level 19

The password for the next level is stored in a file readme in the homedirectory. Unfortunately, someone has modified .bashrc to log you out when you log in with SSH.

→ ssh bandit.labs.overthewire.org -p 2220 -l bandit18 -t "bash --noprofile --norc"
This is a OverTheWire game server. More information on http://www.overthewire.org/wargames
bandit18@bandit.labs.overthewire.org's password:
bash-4.3$ cat readme
IueksS7Ubh8G3DCwVzrTd8rAVOwq3M5x

Level 19 -> Level 20

To gain access to the next level, you should use the setuid binary in the homedirectory. Execute it without arguments to find out how to use it. The password for this level can be found in the usual place (/etc/bandit_pass), after you have used the setuid binary.

bandit19@bandit:~$ ./bandit20-do cat /etc/bandit_pass/bandit20
GbKksEFF4yrVs6il55v6gwY5aVje5f0j

Level 20 -> Level 21

There is a setuid binary in the homedirectory that does the following: it makes a connection to localhost on the port you specify as a commandline argument. It then reads a line of text from the connection and compares it to the password in the previous level (bandit20). If the password is correct, it will transmit the password for the next level (bandit21).

NOTE: Changes to the infrastructure made this level more difficult. You will need to figure out a way to launch multiple commands in the same Docker instance.

NOTE 2: Try connecting to your own network daemon to see if it works as you think

Due to the infrastructure changes mentioned in note 1, launching a new shell will connect to a newly spawned Docker container. To avoid this, I have two sessions opened in tmux in the same shell. The first shell will listen in on a random port I choose (34100), and the second shell will run the suconnect binary.

Session 1:
bandit20@bandit:~$ nc -l 31400
GbKksEFF4yrVs6il55v6gwY5aVje5f0j
gE269g2h3mw3pwgrj0Ha9Uoqen1c9DGr

Session 2:
bandit20@bandit:~$ ./suconnect 31400
Read: GbKksEFF4yrVs6il55v6gwY5aVje5f0j
Password matches, sending next password

Level 21 -> Level 22

A program is running automatically at regular intervals from cron, the time-based job scheduler. Look in /etc/cron.d/ for the configuration and see what command is being executed.

bandit21@bandit:~$ ls -al /etc/cron.d
total 28
drwxr-xr-x   2 root root 4096 Nov 13 15:58 .
drwxr-xr-x 101 root root 4096 Dec 16 14:19 ..
-rw-r--r--   1 root root  102 Apr  5  2016 .placeholder
-rw-r--r--   1 root root  120 Nov 13 15:58 cronjob_bandit22
-rw-r--r--   1 root root  122 Nov 13 15:58 cronjob_bandit23
-rw-r--r--   1 root root  120 Nov 13 15:58 cronjob_bandit24
-rw-r--r--   1 root root  190 Oct 31 13:21 popularity-contest
bandit21@bandit:~$ cat /etc/cron.d/cronjob_bandit22
@reboot bandit22 /usr/bin/cronjob_bandit22.sh &> /dev/null
* * * * * bandit22 /usr/bin/cronjob_bandit22.sh &> /dev/null
bandit21@bandit:~$ cat /usr/bin/cronjob_bandit22.sh
##!/bin/bash
chmod 644 /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv
cat /etc/bandit_pass/bandit22 > /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv
bandit21@bandit:~$ cat /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv
Yk7owGAcWjwMVRwrTesJEwB7WVOiILLI

Level 22 -> Level 23

A program is running automatically at regular intervals from cron, the time-based job scheduler. Look in /etc/cron.d/ for the configuration and see what command is being executed.

NOTE: Looking at shell scripts written by other people is a very useful skill. The script for this level is intentionally made easy to read. If you are having problems understanding what it does, try executing it to see the debug information it prints.

bandit22@bandit:~$ ls -al /etc/cron.d
total 28
drwxr-xr-x   2 root root 4096 Nov 13 15:58 .
drwxr-xr-x 101 root root 4096 Dec 16 14:19 ..
-rw-r--r--   1 root root  102 Apr  5  2016 .placeholder
-rw-r--r--   1 root root  120 Nov 13 15:58 cronjob_bandit22
-rw-r--r--   1 root root  122 Nov 13 15:58 cronjob_bandit23
-rw-r--r--   1 root root  120 Nov 13 15:58 cronjob_bandit24
-rw-r--r--   1 root root  190 Oct 31 13:21 popularity-contest
bandit22@bandit:~$ cat /etc/cron.d/cronjob_bandit23
@reboot bandit23 /usr/bin/cronjob_bandit23.sh  &> /dev/null
* * * * * bandit23 /usr/bin/cronjob_bandit23.sh  &> /dev/null
bandit22@bandit:~$ cat /usr/bin/cronjob_bandit23.sh
##!/bin/bash

myname=$(whoami)
mytarget=$(echo I am user $myname | md5sum | cut -d ' ' -f 1)

echo "Copying passwordfile /etc/bandit_pass/$myname to /tmp/$mytarget"

cat /etc/bandit_pass/$myname > /tmp/$mytarget
bandit22@bandit:~$ whoami
bandit22
bandit22@bandit:~$ echo I am user bandit23 | md5sum | cut -d ' ' -f 1
8ca319486bfbbc3663ea0fbe81326349
bandit22@bandit:~$ cat /tmp/8ca319486bfbbc3663ea0fbe81326349
jc1udXuA1tiHqjIsL8yaapX5XIAI6i0n

Level 23 -> Level 24

A program is running automatically at regular intervals from cron, the time-based job scheduler. Look in /etc/cron.d/ for the configuration and see what command is being executed.

NOTE: This level requires you to create your own first shell-script. This is a very big step and you should be proud of yourself when you beat this level!

NOTE 2: Keep in mind that your shell script is removed once executed, so you may want to keep a copy around.

bandit23@bandit:/var/spool/bandit24$ cat /usr/bin/cronjob_bandit24.sh
##!/bin/bash

myname=$(whoami)

cd /var/spool/$myname
echo "Executing and deleting all scripts in /var/spool/$myname:"
for i in * .*;
do
    if [ "$i" != "." -a "$i" != ".." ];
    then
    echo "Handling $i"
    timeout -s 9 60 ./$i
    rm -f ./$i
    fi
done

A previous level mentioned that passwords are stored in this file: /etc/bandit_pass/bandit24. Since the script will be executed before it is deleted, the following bash script will export the contents of the file to something accessable to my current bandit23 user. Note that the script has to have execute permissions to run.

bandit23@bandit:~$ cd /var/spool/bandit24
bandit23@bandit:/var/spool/bandit24$ vim script.sh
bandit23@bandit:/var/spool/bandit24$ chmod 777 script.sh
##!/bin/bash
mkdir /tmp/bandit24tmp
cat /etc/bandit_pass/bandit24 > /tmp/bandit24tmp/password.txt
bandit23@bandit:/var/spool/bandit24$ cat /tmp/bandit24tmp/password.txt
UoMYTrfrBFHyQXmg6gzctqAwOmw1IohZ

Level 24 -> Level 25

A daemon is listening on port 30002 and will give you the password for bandit25 if given the password for bandit24 and a secret numeric 4-digit pincode. There is no way to retrieve the pincode except by going through all of the 10000 combinations, called brute-forcing.

I first checked to see the output of sending the password and pin to port 30002 via netcat.

bandit24@bandit:~$ echo UoMYTrfrBFHyQXmg6gzctqAwOmw1IohZ 0000 | nc localhost 30002
I am the pincode checker for user bandit25. Please enter the password for user bandit24 and the secret pincode on a single line, separated by a space.
Wrong! Please enter the correct pincode. Try again.
Exiting.

After inspecting the output, I wrote a quick script to brute force all 10000 combinations and outputted to a file.

bandit24@bandit:~$ mkdir /tmp/bandit24tmp
for i in $(seq -f "%04g" 0 9999); do echo UoMYTrfrBFHyQXmg6gzctqAwOmw1IohZ $i | nc localhost 30002; done > /tmp/bandit24tmp/output.txt

Then we grab the only unique output.

bandit24@bandit:~$ sort /tmp/bandit24tmp/output.txt | uniq -u

Correct!
The password of user bandit25 is uNG9O58gUE7snukf3bvZ0rxhtnjzSGzG

Level 25 -> Level 26

Logging in to bandit26 from bandit25 should be fairly easy… The shell for user bandit26 is not /bin/bash, but something else. Find out what it is, how it works and how to break out of it.

This one took me a while to figure out. The SSH key to log in is clearly located in the home directory, however SSH’ing into bandit26@localhost causes the connection to close.

I first looked at what shell the user was using:

bandit25@bandit:~$ getent passwd bandit26 | cut -d: -f7
/usr/bin/showtext```

Upon further inspection, /usr/bin/showtext is a shell script:

bandit25@bandit:~$ cat /usr/bin/showtext
#!/bin/sh

export TERM=linux

more ~/text.txt
exit 0

I’m not going to give this one away, but the trick to solving this one is exploiting the properties of how more displays text to access one of the files the user has read access to and retrieving the password from there.

Level 26 -> Level 27

At this moment, level 27 does not exist yet.