เครื่องมือสำหรับแสดงไฟล์ใดบ้างที่โปรแกรมเข้าถึง?


12

ฉันจะไม่ใช้เครื่องมือที่ซับซ้อนเช่นโหมดบ่น AppArmor ฉันต้องการเครื่องมือง่าย ๆ ที่จะบอกฉันว่าไฟล์ใดบ้างที่เข้าถึงได้โดยโปรแกรมเฉพาะ


7
ภายใต้ระบบปฏิบัติการใด
Jeff Schaller

อาจเป็นประโยชน์ในการอธิบายว่าคุณคาดหวังว่าโปรแกรมจะเข้าถึงไฟล์ในทางใด - การอ่านการเขียนการต่อท้ายการรับfstat()หรือlstat()ข้อมูลเท่านั้น
Sergiy Kolodyazhnyy

ทั้ง Suse และ Ubuntu
Boll19

ไม่มีหนทางที่ฉันจะต้องรู้ว่ามันคือ fstat () หรือ lstat () กำลังเขียนโปรแกรมอยู่หรือเปล่า?
Boll19

ความคิดเห็นของ Sergiy Kolodyazhnyy ในคำอื่น ๆ : หากโปรแกรมตรวจสอบความยาวของไฟล์, วันที่แก้ไข, การอนุญาตหรือคุณสมบัติอื่น ๆ แต่ไม่ได้เข้าถึงข้อมูลของไฟล์คุณจะนับว่าเป็น "การเข้าถึงไฟล์" หรือไม่?
telcoM

คำตอบ:


12

สำหรับ Chris Down คุณสามารถใช้strace -pเพื่อตรวจสอบกระบวนการที่กำลังรันอยู่เพื่อดูว่าไฟล์จะเปิดขึ้นมาตั้งแต่บัดนี้จนถึงเวลาที่คุณสิ้นสุด strace หรือกระบวนการเสร็จสิ้น

หากคุณต้องการที่จะเห็นไฟล์ที่เปิดตลอดระยะเวลาของกระบวนการตั้งแต่เริ่มต้นให้ใช้straceกับชื่อปฏิบัติการ การเพิ่ม-fทำให้แน่ใจว่ากระบวนการย่อยที่ถูกแยกใด ๆ จะได้รับการรายงานเช่นกัน ตัวอย่าง

# strace -e open -f /bin/id
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libselinux.so.1", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libpcre.so.1", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
open("/proc/thread-self/attr/current", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/proc/self/task/1581/attr/current", O_RDONLY|O_CLOEXEC) = 3
open("/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 3
open("/usr/share/locale/en_US.UTF-8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en_US.utf8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en_US/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en.UTF-8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en.utf8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/etc/nsswitch.conf", O_RDONLY|O_CLOEXEC) = 3
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libnss_files.so.2", O_RDONLY|O_CLOEXEC) = 3
open("/etc/passwd", O_RDONLY|O_CLOEXEC) = 3
open("/etc/group", O_RDONLY|O_CLOEXEC)  = 3
open("/etc/group", O_RDONLY|O_CLOEXEC)  = 3
uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
+++ exited with 0 +++
#

ใช้lsofเพื่อดูว่าไฟล์ใดที่กระบวนการเปิดอยู่ในขณะนี้

# lsof -p $(pidof NetworkManager)
COMMAND   PID USER   FD      TYPE             DEVICE  SIZE/OFF     NODE NAME
NetworkMa 722 root  cwd       DIR              253,0       224       64 /
NetworkMa 722 root  rtd       DIR              253,0       224       64 /
NetworkMa 722 root  txt       REG              253,0   2618520   288243 /usr/sbin/NetworkManager
NetworkMa 722 root  mem       REG              253,0     27776    34560 /usr/lib64/libnss_dns-2.17.so
[...]
#

หากคุณมี SystemTap คุณสามารถตรวจสอบโฮสต์ทั้งหมดสำหรับไฟล์ที่กำลังเปิด

[root@localhost tmp]# cat mon
#!/usr/bin/env stap
probe syscall.open { printf ("pid %d program %s opened %s\n", pid(), execname(), filename) }
# ./mon
pid 14813 program touch opened "/etc/ld.so.cache"
pid 14813 program touch opened "/lib64/libc.so.6"
pid 14813 program touch opened 0x7f7a8c6ec8d0
pid 14813 program touch opened "foo2"
[...]
#

2
openไม่ใช่การเรียกระบบที่เกี่ยวข้องเท่านั้น ตัวอย่างเช่นเป็นไปได้ที่จะส่งไฟล์ descriptors ระหว่างกระบวนการผ่านซ็อกเก็ตยูนิกซ์และมีการopenatเรียกระบบซึ่งสามารถเปิดไฟล์ได้
kasperd

---- SIGUSR1 {si_signo = SIGUSR1, si_code = SI_TKILL, si_pid = 6026, si_uid = 1002} ---- นั่นคืออะไร
Boll19

kaspers ฉันต้องค้นหา 'openat' ที่คำสั่ง strace output หรือไม่
Boll19

ลองเปิดไฟล์ (แต่ไฟล์นั้นอาจไม่มีอยู่) ปรากฏขึ้นในเอาต์พุต 'strace' ด้วยหรือไม่
Boll19

Boll19, ไฟล์ที่ไม่สามารถเปิดได้เนื่องจากไฟล์ที่ไม่มีอยู่นั้นถูกรายงานอย่างมีความสุขstrace, ดูบรรทัด ENOENT ในตัวอย่าง
สตีฟ

5

คุณสามารถใช้opensnoopจาก BCC ซึ่งใช้ eBPF ภายใต้ประทุน:

# ./opensnoop -p 1576
PID    COMM      FD ERR PATH
1576   snmpd     11   0 /proc/sys/net/ipv6/conf/lo/forwarding
1576   snmpd     11   0 /proc/sys/net/ipv6/neigh/lo/base_reachable_time_ms
1576   snmpd      9   0 /proc/diskstats
1576   snmpd      9   0 /proc/stat
1576   snmpd      9   0 /proc/vmstat
[...]

มันค่อนข้างมีประสิทธิภาพเนื่องจากมันใช้ kprobes แทนที่จะต้องรีสตาร์ท syscalls เช่นstraceนั้น

นอกจากนี้คุณยังสามารถทำสิ่งนี้ได้ด้วยstrace(อาจ-fจะทำตามกระบวนการย่อยที่ติดตาม) แต่วิธีการทำงานของมันซึ่งเกี่ยวข้องกับการรีสตาร์ท syscalls เนื่องจากส่วนหนึ่งของptraceจะทำให้แอพพลิเคชันของคุณช้าลงบ้าง:

# strace -e open -p 15735
open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
open("/usr/lib/gconv/gconv-modules.cache", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/gconv/gconv-modules", O_RDONLY|O_CLOEXEC) = 3
open("/usr/lib/python2.7/site-packages", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 4
open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
open("/etc/localtime", O_RDONLY|O_CLOEXEC) = 8
[...]

นอกจากนี้คุณยังสามารถเริ่มต้นการใช้งานของคุณด้วยวิธีนี้หากต้องการใช้หรือstrace [executable]strace -f [executable]


5

sysdigเครื่องมือที่ชื่นชอบของฉันสำหรับการตรวจสอบไฟล์ที่เป็นโปรแกรมที่เปิดเป็นกรอบการตรวจสอบที่มีประสิทธิภาพ

สำหรับการตรวจสอบไฟล์ที่เปิดทั้งหมดที่เปิดโดยโปรแกรมชื่อexe_file:

sudo sysdig -p "proc.name=exe_file %12user.name %6proc.pid %12proc.name %3fd.num %fd.typechar %fd.name" evt.type=open

การตรวจสอบไฟล์ทั้งหมดที่เปิดในเซิร์ฟเวอร์:

sudo sysdig -p "%12user.name %6proc.pid %12proc.name %3fd.num %fd.typechar %fd.name" evt.type=open

การสร้างไฟล์ติดตามที่จะมีการเขียนเหตุการณ์ในโฮมไดเรกทอรีเท่านั้น (ซึ่งเราสามารถตรวจสอบได้ในภายหลังsysdig -r writetrace.scap.gz):

sudo sysdig -p "%user.name %proc.name %fd.name" "evt.type=write and fd.name contains /home/" -z -w writetrace.scap.gz

เห็นทุกอย่างในระดับ syscall กระบวนการที่มีชื่อexe_file:

sudo sysdig proc.name=exe_file

Sysdig มีสิ่วมากมายให้ดูสิ่งที่น่าสนใจมากขึ้นที่สามารถทำได้:

คุณยังมีdtraceสิ่งที่ไม่ได้ใช้ใน Linux แต่ก็ยังใช้งานได้กับระบบปฏิบัติการ * BSD:

# Files opened by process,
dtrace -n 'syscall::open*:entry { printf("%s %s",execname,copyinstr(arg0)); }'

นอกจากนี้sysdig, straceและdtraceคุณยังได้มีltraceซึ่งบันทึก / สัญญาณดัก / ห้องสมุดแบบไดนามิก / สายระบบซึ่งเรียกว่ารับ / โดยกระบวนการที่:

ltraceเป็นโปรแกรมที่เรียกใช้คำสั่งที่ระบุจนกว่าจะออก มันสกัดกั้นและบันทึกการเรียกไลบรารีแบบไดนามิกซึ่งถูกเรียกใช้โดยกระบวนการที่ดำเนินการและสัญญาณที่ได้รับจากกระบวนการนั้น นอกจากนี้ยังสามารถดักจับและพิมพ์การเรียกของระบบที่ดำเนินการโดยโปรแกรม

$ltrace exe_file
_libc_start_main(0x400624, 1, 0x7ffcb7b6d7c8, 0x400710 <unfinished ...>  
time(0)                                                                              = 1508018406  
srand(0x59e288e6, 0x7ffcb7b6d7c8, 0x7ffcb7b6d7d8, 0)                                 = 0  
sprintf("mkdir -p -- '/opt/sms/AU/mo'", "mkdir -p -- '%s'", "/opt/sms/AU/mo")        = 28  
system("mkdir -p -- '/opt/sms/AU/mo'" <no return ...>  
--- SIGCHLD (Child exited) ---  
<... system resumed> )                                                               = 0  
rand(2, 0x7ffcb7b6d480, 0, 0x7f9d6d4622b0)                                           = 0x2d8ddbe1  
sprintf("/opt/sms/AU/mo/tmp.XXXXXX", "%s/tmp.XXXXXX", "/opt/sms/AU/mo")      = 29  
mkstemp(0x7ffcb7b6d5c0, 0x40080b, 0x40081a, 0x7ffffff1)                              = 3  
sprintf("/opt/sms/AU/mo/tmp.XXXXXX", "%s/tmp.XXXXXX", "/opt/sms/AU/mo")      = 29  
mkstemp(0x7ffcb7b6d5c0, 0x40080b, 0x40081a, 0x7ffffff1)                              = 4  
+++ exited (status 0) +++  

หากโปรแกรมมีขนาดเล็กคุณอาจพิจารณาถอดแยกชิ้นส่วนด้วยobjdump -d exe_fileหรือถอดแยกชิ้นส่วน / แยกส่วนออกHopperเพื่อดูไฟล์ทั้งหมดที่เกี่ยวข้อง

สำหรับรายละเอียดเพิ่มเติมดูที่: การทำความเข้าใจกับสิ่งที่ไบนารี Linux กำลังทำอยู่

เป็นวิธีแรกฉันจะทำ:

strings exe_file

มันเป็นวิธีการที่มีต้นทุนต่ำและด้วยโชคบางชื่อไฟล์อาจจะปรากฏในโหมด ASCII ในไฟล์ไบนารีด้วยโชค

ดูคำตอบที่เกี่ยวข้องทำไมมีจริงและเท็จขนาดใหญ่?

หากไบนารี / ไฟล์ที่มาพร้อมกับการแจกจ่ายคุณสามารถดึงข้อมูลแหล่งที่มาจากแหล่งเก็บข้อมูลของการแจกจ่ายหรือที่เก็บอย่างเป็นทางการของยูทิลิตี้จริง

เป็นทรัพยากรสุดท้ายคุณสามารถใช้เครื่องมือเช่นgdbหรือrrเพื่อดีบักไบนารีในแบบเรียลไทม์


aaa43bb66: ~ # sudo proc.name = exe_file sysdig -p "% 12user.name% 6proc.pid% 12proc.name% 3fd.num% fd.typechar% fd.name" evt.type = เปิดไม่สามารถโหลดข้อผิดพลาดของไดรเวอร์ เปิดอุปกรณ์ / dev / sysdig0 ตรวจสอบให้แน่ใจว่าคุณมีข้อมูลประจำตัวของรูทและโมดูล sysdig-probe ถูกโหลด
Boll19

/ * <pre> aaa43bb66: ~ # sudo proc.name = exe_file sysdig -p "% 12user.name% 6proc.pid% 12proc.name% 3fd.num% fd.typechar% fd.name" evt.type = เปิดไม่สามารถใช้ได้ เพื่อโหลดข้อผิดพลาดของไดรเวอร์ที่เปิดอุปกรณ์ / dev / sysdig0 ตรวจสอบให้แน่ใจว่าคุณมีหนังสือรับรองรูทและโมดูล sysdig-probe ถูกโหลดแล้ว <code> * /
Boll19 19

@ Boll19 มีข้อผิดพลาดที่นั่นแก้ไขให้ถูกต้อง ข้อความนั้นดูเหมือนว่าจะเป็นsysdigบั๊ก (คุณใช้ ARM?) โปรดโพสต์คำถามใหม่
Rui F Ribeiro
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.