Provide JSON output option#277
Conversation
We could introduce a flag called Having the format first would allow us to pipe the output to another process or redirect to a file as you mentioned. <3
That's my least favourite part of the code, but I couldn't find a better solution at the time to merge the options from the config file and the options passed on the command line directly. The flow to add a new thing to the config is:
|
Just to reiterate, that last part is a problem on our side -- we do not have documentation on adding a new thing to the config so sorry for any confusion :) I'll add it in now ✨ Update, added them here: |
|
Alright, this is what I came up with: There is the I also moved the text output that was in the Nmap loop out of there. While doing so, I found Lastly, I updated the output of |
This sounds rather confusing, I would hope that if the format is text and it's not outputting to a file, it outputs to the terminal? Else, we make them mutually exclusive in the code itself, so if format == text and not file_output stop program. Although, from my perspective, if the default is text we shouldn't panic if our input is the same as the default What do you think? :) |
|
@bee-san Yeah, it's rather unintuitive. Things like To make sure we're on the same page here: Is the "text" / greppable / summary / list format (for example Here is my next proposal: The Anyway, I would implement fn main() {
// ...
if opts.greppable || opts.format.is_some() || opts.output_file.is_some() || ... {
match opts.format.unwrap_or_default() {
// ...
}
}
}Note: The more I think about it, I wonder if |
|
My two cents on this topic: I would like to simplify our public APIs otherwise we start running into confusing scenarios. The challenge here seems to to be having an useful output in our generated file, which is the scanner result in this case versus having all the output of RustScan in the file. In my opinion we shouldn't really output to a file the results of our scripts, we can let scripts themselves do that or the user can pipe stdout to a file. @bee-san @niklasmohrin What do you think of:
|
|
@bee-san @bernardoamc I think we are all thinking of a similar solution. To clarify: Should the summary output and the nmap scan be mutually exclusive, that is, should the I agree that this whole Then however, there should be something like a On the other hand, if I hope I did not confuse too much stuff, but I personally think that this distinction between say "normal mode" and "summary mode" would be a clean solution. P.S. Maybe there should be a flag to have a JSON file as an input and take that as the result of the port scan. This could be nice if you wanted to try different nmap arguments against the same target. This can be discussed later or in a different thread though. |
|
@bee-san @bernardoamc You should be able to compare both approaches from my last comment by using |
|
Since there is also an issue about having only the output from nmap and nothing else (see #296), this "mode" semantic could be further expanded:
I am not sure what the best approach to encoding these modes in CLI parameters would be (subcommands or mutually exclusive flags?). I think that this would make for a great experience with rustscan, since you can access all possible use cases of the program easily through the choice of a mode. Let me know what you think @bee-san @bernardoamc @iiiusky |
I think the third mode can meet most of the needs, because the format that comes with nmap can be used. It is already a standard format. Many developers are already compatible with the parsing of nmap xml format. Of course, there is another situation. Only rustscan is used, and nmap scanning is not performed.In this case, if you need to output, you can consider customizing an output structure. |
|
The problem is that we call nmap multiple times, once for every host, because there are different ports to scan on every host. Thus we have multiple XML files with different entries in the # Let's say we found 10.10.10.21 to have ports 80, 81
# and 10.10.10.22 to have 80, 82 open
# Afaik the only way to have all of the open ports scanned
# in one nmap run is to scan all three ports on both machines
nmap -p 80,81,82 10.10.10.21 10.10.10.22
# which would be slightly slower for this and probably
# way slower for bigger examples
# We need to merge the outputs of
nmap -p 80,81 10.10.10.21
nmap -p 80,02 10.10.10.22
# to look as if we run the command
# from the above explanationI think it would be reasonable to modify the XML content as if the nmap scan ran against all ports that we give to nmap at all (so it's the set of all ports found to be open by the port scan), because we know that the port is closed and nmap would have determined the same. I totally agree that we should not introduce a totally new format for nmap results, that would be very inconvenient. @iiiusky What do you think would be the best way to accomplish that? Maybe it's just some serde magic around the nmap xml? |
I think that using a method like |
|
@iiiusky I don't think this is a sane default because it would be against what rustscan tries to accomplish: unnecessary slow nmap port scans. Let' say you want to scan Maybe this should be an option like Just output all XML files without merging them (maybe capture output and have rustscan create a file with a helpful name?) or merge them similar to for example https://github.com/CBHue/nMap_Merger (haven't tested, just saw that this is out here). |
I don't agree with this method of not merging nmap results and then outputting all the results. This will make the process of parsing the resulting xml very cumbersome. If you want to merge xml, this method is definitely feasible, but there may be unknown problems. |
|
Yes, just outputting all XML files separately would probably be a bit messy at times, but it might be the best option in some situations, which is why I wouldn't want to turn the option down so quickly. There is probably a use-case for all three approaches:
|
You can take a look at the introduction of the --resume parameter in the help file of the official website. Also, if the results of nmap are merged, do we need to traverse all nodes and merge? Or is it merged in truncated mode? If it is to traverse all nodes and merge, you need to follow the official nmap.dtd https://github.com/nmap/nmap/commits/master/docs/nmap.dtd definition to keep the latest state. |
|
Sorry it took so long to answer @niklasmohrin , life happened. I will take a look at your approach. 🙏 |
I have a new idea. We can scan different ports for each different host according to what you said above, and then return it, but after the final return, we can spit out a json type array format, and then nmap The scanned results are base64 encoded. If you need to parse the nmap results, you must first parse our json list. The json list contains all the results scanned by nmap, such as this What do you think of this? I think this is not very friendly to programs that directly parse the results of nmap, because he must add a new intermediate parsing tool, but programs that use rustscan for secondary development have no such troubles. |
|
I implemented the functions I wanted above, but did not implement xml merge,@niklasmohrin |
|
@iiiusky I don't think I understand why base 64 encoded XML in a JSON array is better than just listing all XML outputs with some separator or even output XML that is just a list of all of the nmap XML outputs. Isn't this even more complicated for other programs to parse? I feel like this is all getting very very complicated and I would rather discuss the scope of all of these changes before working on implementation (again). What should the user API for all of these options look like? There could be the mode approach that I described in this comment or the output options for just the port scan could also be scripts for the scripting engine, removing the need of modes. Please give me some input / opinions @bee-san @bernardoamc |
|
I consider using base64 to encode xml in json, because there may be some character encoding problems in the process of outputting xml. After encoding it once with base64, the original data can be completely output (I may be worrying too much My process of using rustscan is as follows:
In the process of using rustscan, I need to get the original nmap output, but according to the existing situation, if I pass the -oX parameter to nmap, the output information of a single host is good, if there are multiple hosts output then all of them They are displayed together, and the tool cannot distinguish them directly, and must rely on line breaks or keywords. When I have an appeal problem, can the script solve the situation? |
Hey! This should close #213.
The solution was pretty straightforward. I was wondering whether it would be nicer to have a flag that outputs the results as JSON to the console so they could be piped into another process or get redirected to a file. I also left a TODO at the
merge_requiredpart, because I was not sure whether I had to add something there.Let me know what you think!