ฉันสงสัยว่าปัญหาของคุณคือส่วน sudo
ของบรรทัดคำสั่ง nmap
หากคุณแทนที่ subprocess.call
ด้วย subprocess.check_call
ฉันคิดว่าคุณจะพบว่า คำสั่งนั้นทำให้เกิด CalledProcessError
สมมุติว่าบัญชีผู้ใช้ของคุณอยู่ในไฟล์ /etc/sudoers
แต่เว็บเซิร์ฟเวอร์ไม่เป็นเช่นนั้น
เนื่องจากสิ่งแรกที่ตัวดำเนินการเปลี่ยนเส้นทางเอาต์พุตของเชลล์ (>
) ทำคือตัดทอนไฟล์เอาต์พุต การพยายามรัน nmap
ที่ล้มเหลวจะส่งผลให้เกิด whohome.txt
เป็นศูนย์ไบต์ สคริปต์ Python ที่เหลือก็ทำเช่นเดียวกันกับ website.txt
และสุดท้ายคุณจะไม่มีอะไรแสดงบนเว็บไซต์ของคุณ
โซลูชั่น
ไม่จำเป็นต้องมี sudo
บนเดสก์ท็อป Linux ของฉัน ฉัน ไม่ จำเป็นต้องเรียกใช้ nmap
ในฐานะรูท เพื่อทำการสแกน Ping ในเครื่อง หากสิ่งนั้นเกิดขึ้นจริงในระบบของคุณ คุณก็ควรจะปล่อยส่วน sudo
ของคำสั่ง nmap
ของคุณได้เลย และดำเนินการให้เสร็จสิ้น
แม้ว่าจะมีความแตกต่างกันก็ตาม nmap
จะทำการทดสอบแต่ละเป้าหมายอย่างละเอียดมากขึ้น เมื่อ -pS
ping Sweep รันโดย root
จากหน้าคนเก่า nmap
(เน้นเพิ่ม):
-sP
(ข้ามการสแกนพอร์ต) .
[...]
ตัวเลือก -sP
ส่งคำขอ ICMP echo, TCP SYN ไปยังพอร์ต 443, TCP ACK ไปยังพอร์ต 80 และคำขอประทับเวลา ICMP ตามค่าเริ่มต้น เมื่อดำเนินการโดยผู้ใช้ที่ไม่มีสิทธิพิเศษ เฉพาะแพ็กเก็ต SYN เท่านั้นที่จะถูกส่ง (โดยใช้การโทรเชื่อมต่อ) ไปยังพอร์ต 80 และ 443 บนเป้าหมาย เมื่อผู้ใช้ที่มีสิทธิ์พยายามสแกนเป้าหมาย บนอีเธอร์เน็ตท้องถิ่น คำขอ ARP จะถูกนำมาใช้เว้นแต่จะระบุ --send-ip
[...]
เปิดใช้งาน sudo
สำหรับเว็บเซิร์ฟเวอร์ของคุณ
หากคุณต้องการข้อมูลเพิ่มเติมนี้ (และดูเหมือนว่าคุณต้องการ) คุณจะต้องเรียกใช้ nmap
(หรือสคริปต์ Python ที่เรียกข้อมูลนั้น) ด้วยสิทธิ์ผู้ใช้ระดับสูง ฉันไม่เคยพยายามบังคับให้เว็บเซิร์ฟเวอร์ทำเช่นนี้ แต่ฉันคิดว่าอย่างน้อยคุณจะต้องเพิ่มผู้ใช้ของเว็บเซิร์ฟเวอร์ของคุณไปที่ /etc/sudoers
สิ่งที่ต้องการ:
apache localhost=/usr/bin/nmap -sP
or:
httpd ALL=/usr/local/bin/nmap
...และอื่นๆ ขึ้นอยู่กับชื่อผู้ใช้ ตำแหน่งที่ nmap
ของคุณอยู่ คุณต้องการจำกัดอาร์กิวเมนต์ไว้ที่ nmap
อย่างเคร่งครัดเพียงใด เป็นต้น
สร้างไฟล์ปฏิบัติการ SUID เพื่อเรียกใช้ nmap
สำหรับคุณ
อีกทางหนึ่ง (และฉันเกลียดตัวเองที่แนะนำสิ่งนี้ --- ต้อง เป็นวิธีที่ดีกว่า) คือการเขียนโปรแกรม SUID (Set User ID) เล็ก ๆ ที่รัน เท่านั้น nmap
คำสั่งที่คุณต้องการ นี่คือโปรแกรม C ที่จะทำ:
#include <stdio.h>
#include <unistd.h>
int main(void);
int main(void) {
int retval = 0;
char* const error_string = "ERROR: Failed to execute \"/usr/bin/map\"";
char* const nmap_args[] = {
"/usr/bin/nmap",
"-sP",
"192.168.1.0/24",
NULL
};
retval = execv("/usr/bin/nmap", nmap_args);
/* execv returns _only_ if it fails, so if we've reached this
* point, print an error and exit.
*/
perror(error_string);
return retval;
}
บันทึกข้างต้นเป็นบางอย่างเช่น nmap_lan.c
และคอมไพล์ด้วย:
$ gcc -Wall -o nmap_lan nmap_lan.c
จากนั้น ย้ายไปที่ใดก็ตามที่คุณเก็บสคริปต์ของเว็บไซต์ของคุณ และ ในฐานะ root ให้เปลี่ยนความเป็นเจ้าของและการอนุญาต:
# chown root:root nmap_lan # Or whatever group name you use.
# chmod 4555 nmap_lan
4
นำหน้าตั้งค่าบิต SUID สี ls
ของไดเร็กทอรีอาจแสดงไฟล์นั้นที่ถูกไฮไลต์ การอนุญาตควรมีลักษณะเช่นนี้:
# ls -l nmap_lan
-r-sr-xr-x. 1 root root 6682 May 23 03:04 nmap_lan
ผู้ใช้ใดๆ ที่เรียกใช้ nmap_lan
จะได้รับการเลื่อนระดับให้เป็นเจ้าของไฟล์ nmap_lan
ชั่วคราว (ในกรณีนี้คือ root
) จนกว่าโปรแกรมจะออก นั่นเป็นเรื่องดีเป็นพิเศษ ซึ่งเป็นเหตุผลว่าทำไมฉันถึงฮาร์ดโค้ด ทุกอย่าง ในโปรแกรมนั้น... หากต้องการเปลี่ยนแปลงอะไรก็ตามที่มันทำได้ --- แม้แต่ช่วง IP ที่จะสแกน --- คุณจะต้องแก้ไข nmap_lan.c
ไฟล์ คอมไพล์ใหม่ และติดตั้งใหม่
ฉันได้ทดสอบ nmap_lan
บนบรรทัดคำสั่งของฉันแล้ว และมันสร้างเอาต์พุตผู้ใช้ที่มีสิทธิ์พิเศษ nmap
เมื่อเรียกใช้โดยผู้ใช้ที่ไม่มีสิทธิ์ซึ่งปกติจะได้รับเอาต์พุตที่จำกัดเท่านั้น
ความคิดเห็นเกี่ยวกับสคริปต์ Python
โดยทั่วไปแล้ว Python นั้นอย่างมากในการแยกวิเคราะห์อาร์กิวเมนต์ของเชลล์มากกว่าเชลล์ (ค่าเริ่มต้นสำหรับ shell
คือ False
ด้วยเหตุผลบางประการ) ดังนั้นให้สคริปต์ Python ของคุณทำงานให้มากที่สุดเท่าที่จะเป็นไปได้ รวมถึง การแยกวิเคราะห์คำสั่งเชลล์ การเปลี่ยนทิศทางอินพุต และเอาต์พุตการเปลี่ยนทิศทาง
ข้อได้เปรียบที่สำคัญของการทำงานใน Python ก็คือ การไม่เปิด อ่าน เขียน หรือปิดไฟล์ใดๆ ของคุณจะส่งผลให้เกิดการหยุดทำงานทันทีและการติดตามสแต็ก --- แทนที่จะเป็นความล้มเหลวแบบเงียบๆ ที่คุณกำลังเผชิญอยู่
ฉันจะเขียนคำสั่ง call
ใหม่เพื่อใช้รายการอาร์กิวเมนต์ที่แยกออกจากกันอย่างชัดเจน คุณสามารถจัดการการเปลี่ยนเส้นทางเอาต์พุตได้โดยส่งสตรีมไฟล์ที่เปิดไปยังพารามิเตอร์ stdout
คุณสามารถกำจัดการเปลี่ยนเส้นทางเชลล์บิตสุดท้ายของคุณได้โดยให้ Python เปิดไฟล์เอาท์พุตของคุณและเขียนลงไปอย่างชัดเจน
nmap_file='/home/pi/whohome.txt'
with open(nmap_file, 'wt', encoding='ascii') as fout:
subprocess.call(
['/usr/bin/nmap', '-sP', '192.168.1.0/24'], # Or just ['nmap_lan']
stdout=fout,
universal_newlines=True,
)
output_file='/var/www/html/website.txt'
with open(nmap_file, 'rt', encoding='ascii') as fin:
with open(output_file, 'wt', encoding='ascii') as fout:
for line in fin:
...
print('Output here', file=fout) # Add `file=...` to each print.
นอกจากนี้ เว้นแต่ว่าคุณต้องการไฟล์ whohome.txt
นั้นสำหรับอย่างอื่น คุณสามารถกำจัดมันทั้งหมดได้โดยใช้ check_output
เพื่อจัดเก็บเอาต์พุตจากคำสั่ง nmap
เป็นสตริง จากนั้นแยกออกเป็นบรรทัดแยกกัน (พารามิเตอร์ universal_newlines
ยังจัดการการแปลงวัตถุ bytes
เป็น str
อย่างน้อยใน Python 3)
lines = subprocess.check_output(
['/usr/bin/nmap', '-sP', '192.168.1.0/24'], # Or just ['nmap_lan']
universal_newlines=True
).split('\n')
output_file='/var/www/html/website.txt'
with open(output_file, 'wt', encoding='ascii') as fout:
for line in lines:
...
print('Output here', file=fout) # Add `file=...` to each print.
โปรดทราบว่าฉันใช้ with
บล็อกเพื่อปิดไฟล์ฟรี
(ท้ายที่สุด ชุดคำสั่ง if
นั้นกำลังร้องขอให้เขียนใหม่เป็น for machine in machines_dict:
ลูป โดยมีสตริงที่คุณกำลังค้นหาเป็นคีย์ในพจนานุกรมนั้น และเอาต์พุตที่คุณต้องการพิมพ์เป็นค่า)
person
Kevin J. Chase
schedule
23.05.2016
website.txt
กลายเป็นว่างเปล่าได้อย่างไร (หรือดูเหมือนว่างเปล่า) ตรวจสอบบริบทความปลอดภัยของไฟล์ด้วยls -Z *whatever*
- person Kevin J. Chase   schedule 23.05.2016website.txt
ถูกตัดทอนเหลือ 0 ไบต์จริง ๆ เมื่อคุณโหลดหน้าซ้ำหรือไม่ นั่นหมายถึงสคริปต์ python กำลังทำงานอยู่ แต่สร้างเอาต์พุต 0 ไบต์ มันมีอินพุตที่คุ้มค่าในไฟล์whohome.txt
หรือไม่ - person Kevin J. Chase   schedule 23.05.2016chmod
ed เป็น0777
และโดยทั่วไปเพื่อเปิดใช้งานการรักษาความปลอดภัยใดๆ ก็ตามที่คุณปิดใช้งานไว้อีกครั้งในขณะที่แก้ไขปัญหานี้ - person Kevin J. Chase   schedule 23.05.2016