ฉันจัดการกล่อง Gentoo Hardened ที่ใช้ความสามารถของไฟล์เพื่อกำจัดความต้องการไบนารีส่วนใหญ่ของ setuid (เช่น/bin/ping
มี CAP_NET_RAW และอื่น ๆ )
Infact ไบนารีเดียวที่ฉันเหลืออยู่คืออันนี้:
abraxas ~ # find / -xdev -type f -perm -u=s
/usr/lib64/misc/glibc/pt_chown
abraxas ~ #
ถ้าฉันลบบิต setuid หรือติดตั้งระบบไฟล์รูทของฉันnosuid
ใหม่ sshd และ GNU Screen หยุดทำงานเพราะพวกเขาเรียกgrantpt(3)
pesudoterminals หลักและ glibc เรียกใช้โปรแกรมนี้เพื่อ chown และ chmod ทาส pseudoterminal ใต้/dev/pts/
และหน้าจอ GNU ใส่ใจเมื่อฟังก์ชั่นนี้ ล้มเหลว
ปัญหาคือ manpage สำหรับการgrantpt(3)
ระบุอย่างชัดเจนว่าภายใต้ Linux พร้อมกับdevpts
ติดตั้งระบบไฟล์ไม่จำเป็นต้องใช้ตัวช่วยไบนารี เคอร์เนลจะตั้งค่า UID & GID ของ slave ให้เป็น UID จริง & GID ของกระบวนการที่เปิด/dev/ptmx
(โดยการโทรgetpt(3)
) โดยอัตโนมัติ
ฉันได้เขียนโปรแกรมตัวอย่างเล็ก ๆ เพื่อสาธิตสิ่งนี้:
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
int main(void)
{
int master;
char slave[16];
struct stat slavestat;
if ((master = getpt()) < 0) {
fprintf(stderr, "getpt: %m\n");
return 1;
}
printf("Opened a UNIX98 master terminal, fd = %d\n", master);
/* I am not going to call grantpt() because I am trying to
* demonstrate that it is not necessary with devpts mounted,
* the owners and mode will be set automatically by the kernel.
*/
if (unlockpt(master) < 0) {
fprintf(stderr, "unlockpt: %m\n");
return 2;
}
memset(slave, 0, sizeof(slave));
if (ptsname_r(master, slave, sizeof(slave)) < 0) {
fprintf(stderr, "ptsname: %m\n");
return 2;
}
printf("Device name of slave pseudoterminal: %s\n", slave);
if (stat(slave, &slavestat) < 0) {
fprintf(stderr, "stat: %m\n");
return 3;
}
printf("Information for device %s:\n", slave);
printf(" Owner UID: %d\n", slavestat.st_uid);
printf(" Owner GID: %d\n", slavestat.st_gid);
printf(" Octal mode: %04o\n", slavestat.st_mode & 00007777);
return 0;
}
สังเกตมันในทางปฏิบัติด้วยบิต setuid ในโปรแกรมดังกล่าวลบออก:
aaron@abraxas ~ $ id
uid=1000(aaron) gid=100(users) groups=100(users)
aaron@abraxas ~ $ ./ptytest
Opened a UNIX98 master terminal, fd = 3
Device name of slave pseudoterminal: /dev/pts/17
Information for device /dev/pts/17:
Owner UID: 1000
Owner GID: 100
Octal mode: 0620
ฉันมีความคิดเพียงเล็กน้อยเกี่ยวกับวิธีแก้ไขปัญหานี้:
1) แทนที่โปรแกรมด้วยโครงกระดูกที่ส่งกลับค่า 0
2) Patch allowpt () ใน libc ของฉันไม่ทำอะไรเลย
ฉันสามารถทำทั้งสองอย่างนี้โดยอัตโนมัติ แต่ไม่มีใครมีข้อเสนอแนะสำหรับอีกคนหนึ่งหรือคำแนะนำสำหรับวิธีอื่นในการแก้ปัญหานี้
mount -o remount,nosuid /
ครั้งนี้จะแก้ไขได้ผมจนสามารถ
pty
(เท่าที่ควร) แต่สำหรับโปรแกรม?