@@ -777,6 +777,7 @@ def cmd_vulns_help
777
777
print_line "Usage: vulns [addr range]"
778
778
print_line
779
779
print_line " -h,--help Show this help information"
780
+ print_line " -o <file> Send output to a file in csv format"
780
781
print_line " -p,--port <portspec> List vulns matching this port spec"
781
782
print_line " -s <svc names> List vulns matching these service names"
782
783
print_line " -R,--rhosts Set RHOSTS from the results of the search"
@@ -801,6 +802,7 @@ def cmd_vulns(*args)
801
802
search_term = nil
802
803
show_info = false
803
804
set_rhosts = false
805
+ output_file = nil
804
806
805
807
# Short-circuit help
806
808
if args . delete "-h"
@@ -817,6 +819,14 @@ def cmd_vulns(*args)
817
819
when "-h" , "--help"
818
820
cmd_vulns_help
819
821
return
822
+ when "-o" , "--output"
823
+ output_file = args . shift
824
+ if output_file
825
+ output_file = File . expand_path ( output_file )
826
+ else
827
+ print_error ( "Invalid output filename" )
828
+ return
829
+ end
820
830
when "-p" , "--port"
821
831
unless ( arg_port_range ( args . shift , port_ranges , true ) )
822
832
return
@@ -846,6 +856,10 @@ def cmd_vulns(*args)
846
856
host_ranges . push ( nil ) if host_ranges . empty?
847
857
ports = port_ranges . flatten . uniq
848
858
svcs . flatten!
859
+ tbl = Rex ::Text ::Table . new (
860
+ 'Header' => 'Vulnerabilities' ,
861
+ 'Columns' => [ 'Timestamp' , 'Host' , 'Name' , 'References' , 'Information' ]
862
+ )
849
863
850
864
each_host_range_chunk ( host_ranges ) do |host_search |
851
865
framework . db . hosts ( framework . db . workspace , false , host_search ) . each do |host |
@@ -857,19 +871,34 @@ def cmd_vulns(*args)
857
871
)
858
872
end
859
873
reflist = vuln . refs . map { |r | r . name }
874
+
860
875
if ( vuln . service )
861
876
# Skip this one if the user specified a port and it
862
877
# doesn't match.
863
878
next unless ports . empty? or ports . include? vuln . service . port
864
879
# Same for service names
865
880
next unless svcs . empty? or svcs . include? ( vuln . service . name )
866
- print_status ( "Time: #{ vuln . created_at } Vuln: host=#{ host . address } name=#{ vuln . name } refs=#{ reflist . join ( ',' ) } #{ ( show_info && vuln . info ) ? "info=#{ vuln . info } " : "" } " )
867
-
868
881
else
869
882
# This vuln has no service, so it can't match
870
883
next unless ports . empty? and svcs . empty?
871
- print_status ( "Time: #{ vuln . created_at } Vuln: host=#{ host . address } name=#{ vuln . name } refs=#{ reflist . join ( ',' ) } #{ ( show_info && vuln . info ) ? "info=#{ vuln . info } " : "" } " )
872
884
end
885
+
886
+ print_status ( "Time: #{ vuln . created_at } Vuln: host=#{ host . address } name=#{ vuln . name } refs=#{ reflist . join ( ',' ) } #{ ( show_info && vuln . info ) ? "info=#{ vuln . info } " : "" } " )
887
+
888
+ if output_file
889
+ row = [ ]
890
+ row << vuln . created_at
891
+ row << host . address
892
+ row << vuln . name
893
+ row << reflist * ","
894
+ if show_info && vuln . info
895
+ row << "info=#{ vuln . info } "
896
+ else
897
+ row << ''
898
+ end
899
+ tbl << row
900
+ end
901
+
873
902
if set_rhosts
874
903
addr = ( host . scope ? host . address + '%' + host . scope : host . address )
875
904
rhosts << addr
@@ -878,6 +907,11 @@ def cmd_vulns(*args)
878
907
end
879
908
end
880
909
910
+ if output_file
911
+ File . write ( output_file , tbl . to_csv )
912
+ print_status ( "Wrote vulnerability information to #{ output_file } " )
913
+ end
914
+
881
915
# Finally, handle the case where the user wants the resulting list
882
916
# of hosts to go into RHOSTS.
883
917
set_rhosts_from_addrs ( rhosts . uniq ) if set_rhosts
0 commit comments