আমার কাছে এমন একটি প্রক্রিয়া রয়েছে যা মূল হিসাবে চলমান কোনও শয়তান দ্বারা শুরু হয়, এখন আমি আপনার গড় ব্যবহারকারীর কাছে এই প্রক্রিয়াটির সুবিধাগুলি "ডাউনগ্রেড" করতে চাই। এটা কি সম্ভব? হ্যাঁ কিভাবে?
পিএস: ম্যাকের উপর ইউনিক্স চালানো
আমার কাছে এমন একটি প্রক্রিয়া রয়েছে যা মূল হিসাবে চলমান কোনও শয়তান দ্বারা শুরু হয়, এখন আমি আপনার গড় ব্যবহারকারীর কাছে এই প্রক্রিয়াটির সুবিধাগুলি "ডাউনগ্রেড" করতে চাই। এটা কি সম্ভব? হ্যাঁ কিভাবে?
পিএস: ম্যাকের উপর ইউনিক্স চালানো
উত্তর:
প্রক্রিয়া নিজেই সেটুইড কল করতে হবে (2)। আপনার যদি এটি ইতিমধ্যে না থাকে তবে এটিকে ক্রুট (8) এর মধ্যে চালানোও তদন্ত করা উচিত। আমি যতদূর জানি, অন্য কোনও প্রক্রিয়ার জোড় পরিবর্তন করার জন্য রুটের কোনও উপায় নেই।
যদি আপনি এটিকে মূল হিসাবে চালাচ্ছেন বন্দরগুলি আবদ্ধ করার জন্য, আমি এটি উচ্চতর বন্দরে সাধারণ ব্যবহারকারী হিসাবে চালানো এবং ওএস এক্স-তে আইপিএফডাব্লু (8) ব্যবহার করে 80/443 / ইত্যাদি পোর্টকে উচ্চতর বন্দরে ফরোয়ার্ড করার পরামর্শ দিচ্ছি:
http://support.crashplanpro.com/doku.php/recipe/forward_port_443_to_pro_server_on_mac_osx
setuid()
একা কল করা একেবারেই যথেষ্ট নয়।
sudo tcpdump -Z
নিজস্ব প্রক্রিয়াটির মূল সুবিধাগুলি ছাড়তে initgroups (3), setgid (2) এবং setuid (2) ব্যবহার করে।
# code taken from:
# http://www.opensource.apple.com/source/tcpdump/tcpdump-32/tcpdump/tcpdump.c
/* Drop root privileges and chroot if necessary */
static void
droproot(const char *username, const char *chroot_dir)
{
...
if (initgroups(pw->pw_name, pw->pw_gid) != 0 ||
setgid(pw->pw_gid) != 0 || setuid(pw->pw_uid) != 0) {
fprintf(stderr, "tcpdump: Couldn't change to '%.32s' uid=%lu gid=%lu: %s\n",
username,
(unsigned long)pw->pw_uid,
(unsigned long)pw->pw_gid,
pcap_strerror(errno));
exit(1);
}
...
}
initgroups
, setgid
, setuid
(শেষ!) অবিকল UNIX ডানে দৃষ্টান্ত, এবং সবসময় অনুসরণ করা উচিত। তদ্ব্যতীত, একটি দায়বদ্ধ "ড্রপরুট" ফাংশন পরীক্ষা করে যে এটির ইউআইডি এবং গিডটি সত্যই সেট করা হয়েছে, এমনকি তিনটি প্রাথমিক ফাংশনই সাফল্য ফিরে পেয়েছে।
আপনি অন্যান্য ব্যবহারকারী হিসাবে কমান্ড চালাতে পারেন su
:
su USERNAME -c COMMAND
COMMAND
নামিয়ে দেওয়া সুবিধাগুলি দিয়ে চলবে USER
।
উল্লেখ্য, ডিফল্টরূপে, su
কমান্ডটি চালানোর জন্য লক্ষ্য ব্যবহারকারীর শেল ইন্টারপ্রেটার ব্যবহার করবে। বিপরীতে, এর ডিফল্ট আচরণ sudo
হ'ল COMMAND
স্থায়ী প্রোগ্রাম হিসাবে আচরণ করা , যা বর্তমান পরিবেশটি চালিত হয়। অবশ্যই এই ডিফল্ট আচরণগুলি বিভিন্ন সুইচ এবং পরিবেশের ভেরিয়েবলের মাধ্যমে পরিবর্তন করা যেতে পারে be
su
যে USERNAME- তে কোনও শেল সংজ্ঞায়িত (বা /bin/false
) না থাকলে সেখানে সুডো কাজ করে work
su
এটি প্রতিফলিত করবে। তবে -s
স্যুইচটি ব্যবহার করে যে কেউ সর্বদা ওভাররাইড করতে পারে। মনে রাখবেন যে su
প্রদত্ত ব্যবহারকারীর আচরণ নকল করা - এর উদ্দেশ্যটি সাধারণত তার শেল দ্বারা প্রভাবিত হয়। বিপরীতে, sudo
(ডিফল্টভাবে) লক্ষ্য ব্যবহারকারীর শেল সেটিং উপেক্ষা করবে।
সুবিধাগুলি ছাড়তে, আপনাকে এড়াতে কোনও রুটবিহীন ব্যবহারকারীর প্রয়োজন। তারপরে এটি কেবল সেই ব্যবহারকারীর কাছে স্যুইচ করার বিষয়:
#define UNPRIV_UID 48
#define UNPRIV_GID 48
if (getuid() == 0) { // we are root
// setting UID/GID requires root privileges, so if you don't set
// the GID first, you won't be able to do it at all.
if (setgid(UNPRIV_GID)!=0) die("Failed to set nonroot GID");
if (setuid(UNPRIV_UID)!=0) die("Failed to set nonroot UID");
}
ASSERT(getuid() != 0);
নোট করুন যে এটি একটি মোড়কের স্ক্রিপ্টের পরিবর্তে প্রোগ্রামের মধ্যেই করা হয়ে থাকে। অনেকগুলি প্রোগ্রামের নির্দিষ্ট উদ্দেশ্যে (যেমন একটি স্বল্প সংখ্যাযুক্ত বন্দরকে আবদ্ধ করা) জন্য মূল অধিকারগুলির প্রয়োজন হয়, তবে এর পরে মূলের প্রয়োজন হয় না। সুতরাং এই প্রোগ্রামগুলি রুট হিসাবে শুরু হবে, তবে তার পরে আর প্রয়োজনের পরে সুযোগগুলি বাদ দিন।
আপনার যদি মোটামুটি রুট সুবিধার দরকার না হয় তবে কেবল এটি রুট হিসাবে চালাবেন না। উদাহরণ:
# Change this:
myprog -C /my/config/file
# To this:
sudo -u someuser myprog -C /my/config/file
# Or this
su someuser -c "myprog -C /my/config/file"
setuid
ফাংশন শুধুমাত্র সেট করে কার্যকর ইউআইডি না বাস্তব ইউআইডি। আপনি setreuid
যদি প্রক্রিয়াটি সুবিধাগুলি ফিরে পেতে সক্ষম না করতে চান তবে আপনার ব্যবহার করা উচিত । (এবং উপরের কোডটি পরিপূরক গোষ্ঠী সুবিধার সাথেও কাজ করে না It's এটি কেবল বেশিরভাগ বিশ্বস্ত কোড চালু করার জন্য উপযুক্ত))
setuid()
বাস্তব এবং সংরক্ষিত ব্যবহারকারীদের সেট করে; আপনি চিন্তা করা হতে পারে seteuid()
। সমস্ত সিস্টেমে নেই setreuid()
, তাই এটি সর্বত্র ব্যবহার করা যায় না। এর সঠিক শব্দার্থবিজ্ঞানগুলি setuid()
জটিল, তবে আপনি যদি 0 ইইড করেন তবে আপনি সমস্ত traditionalতিহ্যবাহী ব্যবহারকারী-আইডি সুবিধাগুলি বাদ দিতে সক্ষম হবেন setuid()
। এই উত্তরের মধ্যে সবচেয়ে বড় ভুলটি হ'ল সেই সাথে initgroups
বা setgroups
অবশ্যই বলা হবে setgid
এবং setuid
এবং আরও পুঙ্খানুপুঙ্খ বক্তব্য শেষে করা উচিত।
আপনি যদি execve
অন্য কোনও exec
নির্বাহযোগ্যকে কার্যকর করছেন, যেমন আপনি কল করছেন বা কোনও ফ্যামিলির পরিবারকে কল করছেন , সম্ভবত পরোক্ষভাবে system
বা এর মতো কোনও ফাংশনের মাধ্যমে popen
, এবং শিশু প্রক্রিয়াটি শুরু থেকে কোনও সুযোগ সুবিধা ছাড়াই চলতে হবে, তবে সবচেয়ে সহজ উপায় হ'ল একটি শেল জড়িত, এবং কল su
। কোডটি পার্লের মতো দেখতে কেমন হতে পারে তার একটি সংক্ষিপ্ত বিবরণ এখানে দেখানো হয়েছে:
$shell_command = quotemeta($path_to_executable) . " --option";
$shell_command =~ s/'/'\\''/; # protect single quotes for the use as argument to su
$su_command = sprintf("su -c '%s' %s", $shell_command, quotemeta($user_name));
open(PIPE, "$su_command |") or die;
যদি শিশু প্রক্রিয়াটি মূল হিসাবে শুরু করতে হয় তবে পরে সুবিধাগুলি বাদ দেয় তবে এই উত্তরের কোডটি দেখুন , যা কোনও প্রক্রিয়াতে কীভাবে সুযোগ-সুবিধাগুলি ডাউনগ্রেড করতে হবে তা চিত্রিত করে।