1 package main // import "vimagination.zapto.org/overthewire/krypton" 2 3 import ( 4 "bytes" 5 "flag" 6 "fmt" 7 "log" 8 "os" 9 "time" 10 11 "golang.org/x/crypto/ssh" 12 13 "vimagination.zapto.org/memio" 14 ) 15 16 const ( 17 host = "krypton.labs.overthewire.org:2222" 18 username = "krypton%d" 19 ) 20 21 var ( 22 commands = [...][]string{ 23 //level 0 24 []string{}, 25 //level 1 26 []string{ 27 "echo -n \"Password:\";cat /krypton/krypton1/krypton2 | tr \"[N-ZA-M]\" \"[A-Z]\" | cut -d' ' -f4;exit\n", 28 }, 29 //level 2 30 31 } 32 passwordBytes = []byte("Password:") 33 sValueBytes = []byte("SVALUE:") 34 newLine = []byte{'\n'} 35 ) 36 37 func main() { 38 var ( 39 level uint 40 password string 41 ) 42 43 flag.UintVar(&level, "l", 1, "level number. > 1 requires password") 44 flag.StringVar(&password, "p", "KRYPTONISGREAT", "password for initial level") 45 flag.Parse() 46 47 stdout := make(memio.Buffer, 0, 41) 48 49 // levels 0-24 50 51 for n, cmds := range commands[level:] { 52 n += int(level) 53 log.Printf("Level %2d: Sending Commands...\n", n) 54 55 s, err := ssh.Dial("tcp", host, &ssh.ClientConfig{ 56 User: fmt.Sprintf(username, n), 57 Auth: []ssh.AuthMethod{ssh.Password(password)}, 58 HostKeyCallback: ssh.InsecureIgnoreHostKey(), 59 }) 60 if err != nil { 61 log.Printf("Level %2d: error: %s\n", n, err) 62 return 63 } 64 65 session, err := s.NewSession() 66 if err != nil { 67 log.Printf("Level %2d: error: %s\n", n, err) 68 return 69 } else if err = session.RequestPty("vt100", 40, 80, ssh.TerminalModes{ 70 ssh.ECHO: 0, 71 ssh.TTY_OP_ISPEED: 14400, 72 ssh.TTY_OP_OSPEED: 14400, 73 }); err != nil { 74 log.Printf("Level %2d: error: %s\n", n, err) 75 return 76 } 77 78 session.Stdout = &stdout 79 session.Stderr = os.Stderr 80 wc, _ := session.StdinPipe() 81 if err = session.Shell(); err != nil { 82 log.Printf("Level %2d: error: %s\n", n, err) 83 return 84 } 85 86 for _, cmd := range cmds { 87 time.Sleep(time.Second * 2) 88 if cmd == "%s\n" { 89 p := bytes.Index(stdout, sValueBytes) 90 if p < 0 { 91 log.Printf("Level %2d: error: could not find svalue\n", n) 92 return 93 } 94 l := bytes.Index(stdout[p:], newLine) 95 if l < 0 { 96 log.Printf("Level %2d: error: could not find end of svalue\n", n) 97 return 98 } 99 cmd = fmt.Sprintf(cmd, bytes.TrimSpace(stdout[p+len(sValueBytes):p+l])) 100 } 101 _, err = wc.Write([]byte(cmd)) 102 if err != nil { 103 os.Stdout.Write(stdout) 104 log.Printf("Level %2d: error: %s\n", n, err) 105 return 106 } 107 time.Sleep(time.Second) 108 } 109 110 wc.Close() 111 session.Close() 112 s.Close() 113 114 p := bytes.Index(stdout, passwordBytes) 115 if p < 0 { 116 os.Stdout.Write(stdout) 117 log.Printf("Level %2d: error: could not find password\n", n) 118 return 119 } 120 l := bytes.Index(stdout[p:], newLine) 121 if l < 0 { 122 log.Printf("Level %2d: error: could not find end of password\n", n) 123 return 124 } 125 126 password = string(bytes.TrimSpace(stdout[p+len(passwordBytes) : p+l])) 127 128 if password == "" { 129 log.Printf("Level %2d: error: found empty password\n", n) 130 return 131 } 132 133 log.Printf("Level %2d: Password: %s\n", n, password) 134 stdout = stdout[:0] 135 } 136 }