1 package main // import "vimagination.zapto.org/overthewire/bandit" 2 3 import ( 4 "bufio" 5 "bytes" 6 "flag" 7 "fmt" 8 "io" 9 "log" 10 "os" 11 "strings" 12 "time" 13 14 "golang.org/x/crypto/ssh" 15 16 "vimagination.zapto.org/memio" 17 ) 18 19 const ( 20 host = "bandit.labs.overthewire.org:2220" 21 username = "bandit%d" 22 ) 23 24 var ( 25 commands = [...]string{ 26 //level 0 27 "echo -n \"Password:\";cat readme", 28 //level 1 29 "echo -n \"Password:\";cat ./-", 30 //level 2 31 "echo -n \"Password:\";cat \"spaces in this filename\"", 32 //level 3 33 "echo -n \"Password:\";cat inhere/.hidden", 34 //level 4 35 "echo -n \"Password:\";find inhere -type f | while read file; do file \"$file\" | grep \"ASCII text\" > /dev/null && cat \"$file\" && break;done", 36 //level 5 37 "echo -n \"Password:\";find inhere -type f -size 1033c ! -executable | while read file; do file \"$file\" | grep \"ASCII text\" > /dev/null && cat \"$file\" && break;done | tr -d ' '", 38 //level 6 39 "echo -n \"Password:\";find / -type f -group bandit6 -user bandit7 -size 33c 2>/dev/null | while read file; do file \"$file\" | grep \"ASCII text\" > /dev/null && cat \"$file\" && break;done | tr -d ' '", 40 //level 7 41 "echo -n \"Password:\";grep millionth data.txt | sed -e 's/^millionth[ ]*//'", 42 //level 8 43 "echo -n \"Password:\";sort data.txt | uniq -u", 44 //level 9 45 "echo -n \"Password:\";strings ./data.txt | grep \"==\" | cut -d' ' -f2 | tail -n1", 46 //level 10 47 "echo -n \"Password:\";base64 -d data.txt | sed -e 's/.* //'", 48 //level 11 49 "echo -n \"Password:\";cat data.txt | tr '[A-Za-z]' '[N-ZA-Mn-za-m]' | sed -e 's/.* //'", 50 //level 12 51 "echo -n \"Password:\";" + 52 "tmpDir=\"$(mktemp -d)\";" + 53 "cd \"$tmpDir\";" + 54 "xxd -r ~/data.txt ./data.bin;" + 55 "while true; do" + 56 " case \"$(file -b --mime-type data.bin)\" in" + 57 " \"application/gzip\")" + 58 " mv data.bin data.bin.gz;" + 59 " gzip -d data.bin.gz;;" + 60 " \"application/x-bzip2\")" + 61 " mv data.bin data.bin.bz2;" + 62 " bzip2 -d data.bin.bz2;;" + 63 " \"application/x-tar\")" + 64 " mv data.bin data.bin.tar;" + 65 " filename=\"$(tar -tf data.bin.tar)\";" + 66 " tar -xf data.bin.tar;" + 67 " mv \"$filename\" data.bin;;" + 68 " *)" + 69 " sed -e 's/.* //' data.bin;" + 70 " break;;" + 71 " esac;" + 72 "done;" + 73 "cd;" + 74 "rm -rf \"$tmpDir\";", 75 //level 13 76 "echo -n \"Password:\";ssh -o StrictHostKeyChecking=no -i sshkey.private bandit14@127.0.0.1 cat /etc/bandit_pass/bandit14 2> /dev/null", 77 //level 14 78 "echo -n \"Password:\";echo %q | nc 127.0.0.1 30000 | grep -v \"Correct\" | tr -d '\\r\\n';echo", 79 //level 15 80 "echo -n \"Password:\";echo %q | openssl s_client -ign_eof -connect 127.0.0.1:30001 2> /dev/null | grep -A1 \"Correct\" | grep -v \"Correct\" | tr -d '\\r\\n';echo", 81 //level 16 82 "echo -n \"Password:\";" + 83 "tmpFile=\"$(mktemp)\";" + 84 "nmap -p 31000-32000 127.0.0.1 | grep \"/tcp\" | sed -e 's@^\\([0-9]*\\)/.*@\\1@' | while read port; do" + 85 " (echo %q;sleep 2s) | openssl s_client -connect 127.0.0.1:\"$port\";" + 86 "done 2> /dev/null | grep -A 27 Correct | grep -v Correct > \"$tmpFile\";" + 87 "chmod 600 \"$tmpFile\";" + 88 "ssh -o StrictHostKeyChecking=no -i \"$tmpFile\" bandit17@127.0.0.1 cat /etc/bandit_pass/bandit17 2> /dev/null;" + 89 "rm -f \"$tmpFile\";", 90 //level 17 91 "echo -n \"Password:\";diff passwords.old passwords.new | tail -n1 | cut -d' ' -f2", 92 //level 18 93 "echo -n \"Password:\";cat readme", 94 //level 19 95 "echo -n \"Password:\";./bandit20-do cat /etc/bandit_pass/bandit20", 96 //level 20 97 "echo -n \"Password:\";(echo %q | nc -l 127.0.0.1 8080) & sleep 1s;./suconnect 8080 &> /dev/null", 98 //level 21 99 "echo -n \"Password:\";cat \"$(grep chmod \"$(grep -v reboot /etc/cron.d/cronjob_bandit22 | cut -d' ' -f7)\" | cut -d' ' -f3)\"", 100 //level 22 101 "echo -n \"Password:\";cat /tmp/\"$(bash -c \"myname=bandit23;$(cat \"$(grep -v reboot /etc/cron.d/cronjob_bandit23 | cut -d' ' -f7)\" | grep mytarget=);echo \\$mytarget\")\"", 102 //level 23 103 "echo -n \"Password:\";" + 104 "tmpFile=\"$(mktemp)\";" + 105 "chmod 666 \"$tmpFile\";" + 106 "xFile=\"$(mktemp -p /var/spool/bandit24/)\";" + 107 "echo \"cat /etc/bandit_pass/bandit24 > $tmpFile\" > \"$xFile\";" + 108 "chmod 777 \"$xFile\";" + 109 "until [ -s \"$tmpFile\" ]; do" + 110 " sleep 1s;" + 111 "done;" + 112 "cat \"$tmpFile\";" + 113 "rm -f \"tmpFile\";", 114 //level 24 115 "echo -n \"Password:\";" + 116 "for i in {0000..9999};do" + 117 " echo %q\" $i\";" + 118 " sleep 0.01s;" + 119 "done | nc 127.0.0.1 30002 | grep \"The password of user bandit25 is\" | cut -d' ' -f7", 120 } 121 level25Commands = [...]string{ 122 //level 25 - separate code below 123 "ssh -o StrictHostKeyChecking=no -i bandit26.sshkey bandit26@localhost;exit\n", 124 "v", 125 ":e /etc/bandit_pass/bandit26\n", 126 ":q\n", 127 "q", 128 } 129 ) 130 131 func RunCommands(server, username, password, commands string, stdout, stderr io.Writer) error { 132 s, err := ssh.Dial("tcp", server, &ssh.ClientConfig{ 133 User: username, 134 Auth: []ssh.AuthMethod{ssh.Password(password)}, 135 HostKeyCallback: ssh.InsecureIgnoreHostKey(), 136 }) 137 if err != nil { 138 return err 139 } 140 session, err := s.NewSession() 141 if err != nil { 142 return err 143 } 144 145 session.Stdout = stdout 146 session.Stderr = stderr 147 148 err = session.Run(commands) 149 session.Close() 150 if err != nil { 151 return err 152 } 153 return s.Close() 154 } 155 156 func main() { 157 var ( 158 level uint 159 password string 160 ) 161 162 flag.UintVar(&level, "l", 0, "level number. > 0 requires password") 163 flag.StringVar(&password, "p", "bandit0", "password for initial level") 164 flag.Parse() 165 166 stdout := make(memio.Buffer, 0, 41) 167 168 // levels 0-24 169 170 for n, cmds := range commands[level:] { 171 n += int(level) 172 log.Printf("Level %2d: Sending Commands...\n", n) 173 174 if strings.Contains(cmds, "%q") { 175 cmds = fmt.Sprintf(cmds, password) 176 } 177 178 err := RunCommands(host, fmt.Sprintf(username, n), password, cmds, &stdout, os.Stderr) 179 if err != nil { 180 log.Printf("Level %2d: error: %s\n", n, err) 181 return 182 } 183 if string(stdout[:9]) != "Password:" || len(stdout) != 42 || stdout[41] != 10 { 184 log.Printf("Level %2d: invalid password: %s\n", n, stdout[9:]) 185 return 186 } 187 password = string(stdout[9:41]) 188 log.Printf("Level %2d: Password: %s\n", n, password) 189 stdout = stdout[:0] 190 } 191 192 //level 25 193 194 log.Printf("Level 25: Sending Commands...\n") 195 s, err := ssh.Dial("tcp", host, &ssh.ClientConfig{ 196 User: "bandit25", 197 Auth: []ssh.AuthMethod{ssh.Password(password)}, 198 HostKeyCallback: ssh.InsecureIgnoreHostKey(), 199 }) 200 if err != nil { 201 log.Printf("Level 25: error: %s\n", err) 202 return 203 } 204 session, err := s.NewSession() 205 if err != nil { 206 log.Printf("Level 25: error: %s\n", err) 207 return 208 } else if err = session.RequestPty("vt100", 2, 40, ssh.TerminalModes{ 209 ssh.ECHO: 0, 210 ssh.TTY_OP_ISPEED: 14400, 211 ssh.TTY_OP_OSPEED: 14400, 212 }); err != nil { 213 log.Printf("Level 25: error: %s\n", err) 214 return 215 } 216 217 wc, _ := session.StdinPipe() 218 r, _ := session.StdoutPipe() 219 session.Shell() 220 221 pw := make(chan string) 222 223 go func() { 224 buf := bufio.NewReader(r) 225 i := 0 226 for { 227 b, err := buf.ReadBytes('\n') 228 if err == io.EOF { 229 break 230 } else if err != nil { 231 log.Printf("Level 25: error: %s\n", err) 232 close(pw) 233 return 234 } 235 if bytes.Contains(b, []byte("/etc/bandit_pass/bandit26")) { 236 index := bytes.Index(b, []byte("[1;1H")) 237 pw <- string(b[index+5 : index+37]) 238 close(pw) 239 return 240 } 241 i++ 242 } 243 }() 244 245 for _, cmd := range level25Commands { 246 wc.Write([]byte(cmd)) 247 time.Sleep(time.Second) 248 } 249 250 log.Printf("Level 25: Password: %s\n", <-pw) 251 wc.Close() 252 session.Close() 253 s.Close() 254 }