Một chương trình có thể cho biết nó đang được chạy dưới sudo?


27

Tôi có một chương trình nên hoạt động khác đi nếu nó đang được chạy trong "sudo". Có cách nào nó có thể tìm ra nếu nó được chạy theo sudo không?

Cập nhật: Có người hỏi tại sao tôi muốn làm điều này. Trong trường hợp này, trên máy Mac sử dụng MacPorts, có đầu ra cho bạn biết cắt và dán một lệnh cụ thể. Nếu lệnh MacPorts được chạy với "sudo", thì nó sẽ bao gồm sudo trong lệnh mẫu:

$ sudo port selfupdate 
--->  Updating MacPorts base sources using rsync
MacPorts base version 2.2.1 installed,
MacPorts base version 2.2.1 downloaded.
--->  Updating the ports tree
--->  MacPorts base is already the latest version

The ports tree has been updated. To upgrade your installed ports, you should run
  port upgrade outdated

^^^^^^^^^ it would be really sweet if it output "sudo port upgrade outdated" instead.  It would be even better if it just did it for you :-)

Tôi tò mò: bạn có thể giải thích nó nên cư xử khác nhau như thế nào không?
tọa

1
@sciurus thường là trường hợp sử dụng phổ biến nằm trong tập lệnh cài đặt yêu cầu quyền root; nếu bạn không có chúng, hãy chết ngay lập tức.
Nick T

3
Điều này nghe có vẻ như meta.stackexchange.com/questions/66377/what-is-the-xy-pro Hiệu / . Bạn thực sự muốn làm gì?
Jenny D nói Phục hồi lại

Tôi mơ hồ nhớ một số lệnh nhận thức được rằng nó có chạy bằng root hay không ... Tôi nghĩ câu trả lời là "có"
Rolf

Câu trả lời:


48

Có, có 4 biến môi trường được đặt khi chương trình đang chạy trong sudo:

$ sudo env |grep SUDO
SUDO_COMMAND=/usr/bin/env
SUDO_USER=tal
SUDO_UID=501
SUDO_GID=20

Lưu ý rằng những cái này có thể được làm giả bằng cách đơn giản là đặt chúng. Đừng tin tưởng họ cho bất cứ điều gì quan trọng.

Ví dụ: Trong chương trình này, chúng tôi cần yêu cầu người dùng chạy một số chương trình khác. Nếu cái hiện tại được chạy với sudo, cái khác cũng sẽ như vậy.

#!/bin/bash

echo 'Thank you for running me.'

if [[ $(id -u) == 0 ]]; then
  if [[ -z "$SUDO_COMMAND" ]]; then
    echo 'Please now run: next_command'
  else
    echo 'Please now run: sudo next_command'
  fi
else  echo 'Error: Sadly you need to run me as root.'
  exit 1
fi

Lưu ý rằng nó chỉ kiểm tra biến SUDO_ * nếu trước tiên nó có thể chứng minh rằng nó đang chạy dưới quyền root. Thậm chí sau đó nó chỉ sử dụng nó để thay đổi một số văn bản hữu ích.


2
Tôi sẽ sử dụng cái gì cho "bất cứ điều gì quan trọng?"
Kevin - Tái lập Monica

3
@Kevin nếu ai đó bắt vít với môi trường của họ để giả mạo ở các đặc quyền nâng cao, thì họ hy vọng biết họ đang làm gì và sẽ chấp nhận hậu quả.
Nick T

Bị từ chối bởi vì bất kỳ câu trả lời nào phải đủ điều kiện bởi "không tin tưởng họ cho bất cứ điều gì quan trọng" không phải là một câu trả lời, mà là một hack xấu xí.
Stephen C

Đây là một câu trả lời hoàn toàn chấp nhận được cho câu hỏi đã được hỏi. Cảnh báo cần phải có cho những người có thể cố gắng ngăn chặn việc sử dụng sudo, thay vì chỉ phát hiện ra nó. Phòng ngừa nên được thực hiện bằng cách sử dụng các bí danh lệnh của sudo để hạn chế những lệnh nào người dùng có thể chạy.
lùn

11

Điều này không trả lời trực tiếp câu hỏi nhưng tôi không nghĩ câu hỏi đúng đang được hỏi ở đây. Đối với tôi, người hỏi muốn một chương trình sẽ hoạt động khác nhau có lẽ là nó có quyền nhất định hay không, tuy nhiên tôi cho rằng việc kiểm tra sudo không phải là cách để làm điều đó. Thứ nhất, nhiều hệ thống có thể không thực hiện "sudo", điều đó không có nghĩa là bắt buộc đối với Linux hoặc nhiều Unix.

Ví dụ, người dùng có thể đã đăng nhập với quyền root, làm cho sudo vô nghĩa hoặc có lẽ hệ thống không có người dùng root vẫn có khả năng thực hiện tác vụ quản trị mà chương trình có thể muốn thực hiện. Cuối cùng, có lẽ hệ thống không có root hay sudo nào cả và thay vào đó sử dụng một hệ thống kiểm soát truy cập bắt buộc với các khả năng khác nhau và không bắt tất cả các siêu người dùng để sudo vào. Hoặc người dùng có thể bị sudo, nhưng vào một tài khoản không có quyền hơn tài khoản của họ vì lý do bảo mật (tôi thường chạy mã không tin cậy với người dùng không có đặc quyền tạm thời chỉ có thể ghi vào ramdisks để bỏ, không tăng quyền của tôi ). Nhìn chung, một ý tưởng tồi là giả định một mô hình quyền cụ thể như sudo hoặc sự tồn tại của root hoặc giả sử người dùng bị sudo có bất kỳ đặc quyền cụ thể nào.

Nếu bạn muốn tìm hiểu xem bạn có quyền thực hiện một thao tác hay không, cách tốt nhất thường là chỉ cần thử và thực hiện sau đó kiểm tra lỗi cho các vấn đề về quyền nếu thất bại hoặc nếu đó là một hoạt động nhiều giai đoạn phải thất bại hoặc tất cả đều thành công bạn có thể kiểm tra xem một hoạt động có hoạt động với các chức năng như chức năng truy cập POSIX không (hãy cẩn thận với các điều kiện cuộc đua có thể ở đây nếu quyền được tích cực thay đổi)

Ngoài ra, bạn cần biết người dùng thực sự đằng sau sudo, bạn có thể sử dụng chức năng getlogin , hoạt động cho bất kỳ phiên tương tác nào với thiết bị đầu cuối bên dưới và sẽ cho phép bạn tìm ai đó 'thực sự' đang chạy lệnh để kiểm tra hoặc tìm thư mục nhà của người dùng thực để lưu nhật ký.

Cuối cùng, nếu điều bạn thực sự muốn là tìm hiểu xem người dùng có quyền truy cập root hay không (Vẫn là một ý tưởng tồi nhưng ít triển khai cụ thể hơn), bạn có thể sử dụng getuid để kiểm tra uid bằng 0 và do đó root.


7

Có hai cơ chế có thể được sử dụng.

  • Kiểm tra các biến môi trường có thể được làm giả bằng một trong hai cách, nhưng là cách dễ nhất để làm. growisofskhông thích chạy theo SUDO, vì vậy tôi bỏ đặt các biến SUDO trong các tập lệnh nơi tôi sử dụng nó. Nó có thể được làm giả theo cách khác. (Biến SUDO cũng được đưa vào môi trường cho các tập lệnh chạy theo lệnh at và batch.)
  • Một cách khác để xem bạn có đang chạy theo sudo hay không là đi theo danh sách quy trình từ quy trình cha mẹ của bạn để tìm kiếm sudo. Sẽ rất khó để che giấu rằng bạn đang chạy theo sudo theo cách này, nhưng phức tạp hơn. Vẫn có thể giả mạo rằng bạn đang chạy theo sudo.

Nó là phổ biến hơn để kiểm tra nếu bạn đang chạy như người dùng thích hợp. Các idlệnh có thể được sử dụng để làm điều này. Kịch bản của TomOnTime sử dụng idlệnh để xác định xem sudocó thể được yêu cầu chạy lệnh tiếp theo không.


1
> Thật khó để che giấu rằng bạn đang chạy theo sudo theo cách này Bạn không thể đơn giản đổi tên sudonhị phân thành một cái gì khác? Hoặc đặt tên cho một số thực thi khác sudođể giả mạo ngược lại? Không phải là tôi thực sự mong đợi ai đó sẽ làm điều đó ...
Bob

@Bob Bạn sẽ cần rootquyền truy cập để đổi tên sudothực thi. Một người dùng bình thường sẽ không thể làm điều này. Tôi đã lưu ý rằng bạn có thể giả mạo rằng bạn đang chạy theo sudo. Đổi tên một chương trình hiện có sẽ làm việc. Mã cần thiết cho một sudochương trình giả chuyên dụng là tầm thường.
BillThor

bạn chỉ có thể tải xuống nhị phân sudo từ một nơi nào đó và cấp cho nó quyền ...
Jens Timmerman

@JensTimmerman Bạn cần quyền truy cập root để cấp quyền cho nó. Nếu bạn chỉ có thể đổi tên nó hoặc liên kết cứng nó. Không cần phải tải nó. Nếu bạn cài đặt SUID cho id người dùng đích (nếu hoạt động theo cách đó), bạn phải thỏa hiệp id người dùng đích.
BillThor

à, đúng rồi, nó từ chối làm việc mà không có setuid, xấu của tôi ...
Jens Timmerman

2

Bạn có thể so sánh hiệu quả với id người dùng thực.

Điều này không hoàn toàn có nghĩa là nó đang chạy hoàn tác sudo (cũng có thể được thiết lập), nhưng chỉ ra rằng chương trình có nhiều quyền hơn người dùng mong đợi. (ví dụ: trong một chương trình thường được thực thi mà không có các quyền đó, nhưng cần được chạy cùng với chúng trong khi cài đặt hoặc cài đặt các bản cập nhật. Sau đó, bạn có thể sử dụng điều này để đưa ra một số phản hồi cảnh báo về điều đó).


2
Không, sudođặt cả id hiệu quả và thực. Trái ngược với suid, mà không. Đây là một chương trình C tầm thường mà bạn có thể sử dụng để kiểm tra (xin lỗi, nhận xét sẽ xóa dòng mới, bạn sẽ phải thêm lại chúng):#include <stdio.h> #include <unistd.h> #include <sys/types.h> int main() { printf("real = %i, effective = %i\n", getuid(), geteuid()); return 0; }
derobert

... Hoặc, cách khác,perl -E 'say $<, "\n", $>'
derobert

2

Bạn có thể kiểm tra biến UID (EUID) hiệu quả, như sau:

if [[ $EUID -eq 0 ]]; then
    echo "running as root"
else
    echo "not running as root"
fi

Điều này không trả lời câu hỏi. Mã này cho cùng một đầu ra khi chạy như root như khi chạy như sudo.
Stephen C

@StephenC - Tôi nghĩ rằng đối với các mục đích của OP, không có sự khác biệt. IMHO mục tiêu của họ là xác định thực thi sudo hoặc thực thi từ một vỏ gốc xác thực mà không có sự phân biệt.
Eliran Malka

1
Tôi nghĩ bạn có thể đúng. Tôi đến đây vì tôi không hiểu tại sao lại sudo echo $USERin tên người dùng không có đặc quyền (biến được thay thế TRƯỚC KHI sudo). Tôi thực sự đã kết thúc bằng cách sử dụng mã của bạn trong kịch bản của tôi. Cảm ơn bạn!
Stephen C

chào mừng nhất :)
Eliran Malka

-1

Bạn có thể chạm vào một tập tin /rootvà sau đó if -enó. Và nếu -e là đúng, rm(kiểm tra mã lỗi) để kiểm tra của bạn hoạt động vào lần tiếp theo.

Kiểm tra mã lỗi (hoặc mã trả về) sau khi rm ngăn người khác sử dụng quyền hạn sudo để tạo tệp để chơi khăm bạn.


4
Câu trả lời này kiểm tra xem quy trình có quyền ghi vào /root(không nhất thiết giống như chạy như UID 0), nhưng không kiểm tra xem nó có đạt được các quyền đó hay không sudo.
Ladadadada

Vâng, "ngàn cách để lột da một con mèo"; Khi tôi viết câu trả lời, tôi nghĩ đến 4 hoặc 5 điều khác, vì vậy tôi đã gói nó lại.
Chris K

-2

Tôi thấy rằng điều này hoạt động tốt cho việc này

[ $(cat /proc/$PPID/loginuid) -ne 0 ] && [ "$USER" == "root" ]

Điều này không hoạt động khi tôi dùng thử trên FreeBSD, Centos7 hoặc MacOS X. Tôi nghĩ bạn có nghĩa là "/ Proc" thay vì "/ etc". Nhưng ngay cả với sự thay đổi đó, nó cũng không hoạt động với bất kỳ ai trong số ba người đó. "$ USER" được đặt lại bởi sudo. Ý bạn là $ SUDO_USER? Ngoài ra, ý của bạn là "[[" thay vì "["?
TomOnTime

1
tôi đã sửa ví dụ về cơ bản kiểm tra loginuid không bằng 0, nhưng người dùng đã root.
ruckc
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.