Saya menduga masalah Anda adalah bagian sudo
dari baris perintah nmap
. Jika Anda mengganti subprocess.call
dengan subprocess.check_call
, saya rasa Anda akan menemukannya perintah itu memunculkan CalledProcessError
.
Agaknya, akun pengguna Anda ada di file /etc/sudoers
, namun server Web tidak.
Karena hal pertama yang dilakukan oleh operator pengalihan keluaran shell (>
) adalah memotong file keluaran, upaya yang gagal untuk menjalankan nmap
menghasilkan whohome.txt
nol-byte. Skrip Python lainnya kemudian melakukan hal yang sama pada website.txt
, dan Anda tidak mendapatkan apa pun untuk ditampilkan di situs Web Anda.
Solusi
Tidak diperlukan sudo
.
Di desktop Linux saya, Saya tidak perlu menjalankan nmap
sebagai root untuk melakukan pemindaian ping lokal. Jika itu benar pada sistem Anda, maka Anda seharusnya bisa membuang bagian sudo
dari perintah nmap
Anda, dan selesai.
Namun ada perbedaannya. nmap
akan melakukan pengujian yang lebih menyeluruh terhadap setiap target ketika sapuan -pS
ping dijalankan oleh root
. Dari halaman manual nmap
lama (penekanan ditambahkan):
-sP
(Lewati pemindaian port) .
[...]
Opsi -sP
mengirimkan permintaan gema ICMP, TCP SYN ke port 443, TCP ACK ke port 80, dan permintaan stempel waktu ICMP secara default. Ketika dijalankan oleh pengguna yang tidak memiliki hak istimewa, hanya paket SYN yang dikirim (menggunakan panggilan connect) ke port 80 dan 443 pada target. Ketika pengguna yang memiliki hak istimewa mencoba memindai target di jaringan ethernet lokal, permintaan ARP akan digunakan kecuali --send-ip
ditentukan. [...]
Aktifkan sudo
untuk server Web Anda.
Jika Anda memerlukan informasi tambahan ini (dan sepertinya memang demikian), Anda harus menjalankan nmap
(atau skrip Python yang memanggilnya) dengan hak pengguna super. Saya tidak pernah mencoba memaksa server Web untuk melakukan ini, tapi saya berasumsi Anda setidaknya harus menambahkan pengguna server Web Anda ke /etc/sudoers
. Sesuatu seperti:
apache localhost=/usr/bin/nmap -sP
or:
httpd ALL=/usr/local/bin/nmap
...dan seterusnya, bergantung pada nama pengguna, di mana nmap
Anda berada, seberapa ketat Anda ingin membatasi argumen ke nmap
, dll.
Buat SUID yang dapat dieksekusi untuk menjalankan nmap
untuk Anda.
Alternatifnya (dan saya benci diri saya sendiri karena merekomendasikan hal ini --- pasti ada cara yang lebih baik) adalah dengan menulis program SUID (Set User ID) kecil yang hanya mengeksekusi nmap
perintah yang kamu inginkan. Berikut program C yang akan melakukannya:
#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;
}
Simpan di atas sebagai sesuatu seperti nmap_lan.c
, dan kompilasi dengan:
$ gcc -Wall -o nmap_lan nmap_lan.c
Lalu, pindahkan ke mana pun Anda menyimpan skrip situs Web Anda, dan sebagai root, ubah kepemilikan dan izinnya:
# chown root:root nmap_lan # Or whatever group name you use.
# chmod 4555 nmap_lan
4
di depan menyetel bit SUID. Warna ls
dari direktori mungkin akan menampilkan file yang disorot. Izinnya akan terlihat seperti ini:
# ls -l nmap_lan
-r-sr-xr-x. 1 root root 6682 May 23 03:04 nmap_lan
Setiap pengguna yang menjalankan nmap_lan
akan dipromosikan sementara menjadi pemilik file nmap_lan
(dalam hal ini, root
) hingga program keluar. Itu luar biasa murah hati, itulah sebabnya saya mengkodekan semuanya dalam program itu dengan keras... Untuk mengubah apa pun yang dilakukannya --- bahkan hanya rentang IP yang akan dipindai --- Anda harus mengedit nmap_lan.c
file, kompilasi ulang, dan instal ulang.
Saya telah menguji nmap_lan
pada baris perintah saya, dan menghasilkan keluaran nmap
pengguna yang memiliki hak istimewa ketika dijalankan oleh pengguna yang tidak memiliki hak istimewa yang biasanya hanya mendapat keluaran terbatas.
Komentar pada skrip Python
Secara umum, Python jauh lebih baik dalam mengurai argumen shell dibandingkan shell (nilai default untuk shell
adalah False
karena suatu alasan), jadi buatlah skrip Python Anda melakukan pekerjaan sebanyak mungkin, termasuk menguraikan perintah shell, mengarahkan input, dan mengarahkan output.
Keuntungan utama melakukan pekerjaan dengan Python adalah kegagalan membuka, membaca, menulis, atau menutup file Anda akan mengakibatkan crash langsung dan jejak tumpukan --- alih-alih kegagalan diam-diam yang selama ini Anda alami.
Saya akan menulis ulang perintah call
untuk menggunakan daftar argumen yang dipisahkan secara eksplisit. Anda dapat menangani pengalihan keluaran dengan meneruskan aliran file yang dibuka ke parameter stdout
. Anda dapat menghilangkan sedikit pengalihan shell terakhir dengan meminta Python membuka file output Anda dan menulisnya secara eksplisit.
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.
Selain itu, kecuali Anda memerlukan file whohome.txt
tersebut untuk hal lain, Anda dapat menghilangkannya seluruhnya dengan menggunakan check_output
untuk menyimpan output dari perintah nmap
sebagai string, dan kemudian membaginya menjadi baris terpisah. (Parameter universal_newlines
juga menangani konversi objek bytes
menjadi str
, setidaknya dengan 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.
Perhatikan bahwa saya menggunakan with
blok untuk menutup file secara gratis.
(Akhirnya, rangkaian perintah if
tersebut meminta untuk ditulis ulang sebagai perulangan for machine in machines_dict:
, dengan string yang Anda cari sebagai kunci dalam kamus tersebut, dan keluaran yang ingin Anda cetak sebagai nilainya.)
person
Kevin J. Chase
schedule
23.05.2016
website.txt
menjadi kosong (atau tampak kosong). Periksa konteks keamanan file denganls -Z *whatever*
. - person Kevin J. Chase   schedule 23.05.2016website.txt
benar-benar terpotong menjadi 0 byte saat Anda memuat ulang halaman? Itu berarti skrip python sedang berjalan, tetapi menghasilkan output 0 byte. Apakah ada masukan berharga dalam filewhohome.txt
? - person Kevin J. Chase   schedule 23.05.2016chmod
edit ke0777
, dan secara umum untuk mengaktifkan kembali keamanan apa pun yang telah Anda nonaktifkan saat memecahkan masalah ini. - person Kevin J. Chase   schedule 23.05.2016