Performing a masscan on an input file containing domain names - linux

I cannot find any options in order to perform a masscan on an input file containing domain names in the following format:
domain-name1.com
domain-name2.org
domain-name3.net
Is there a way I could use masscan with an input file containing those domain names? If the masscan software cannot perform that, would you see any Linux programs that could it that would be fast like masscan?

You can use GNU's parallel in combination with dig or host to do performative mass DNS resolution. A combination of dig and parallel would be the following:
parallel -j100 --retries 3 dig #$nameserver +short :::: hosts.txt | grep -E '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' > ip_list.txt
The number after -j switch is the amount of parallel DNS queries you want to execute;
+short tells dig to output only the DNS resolved addresses;
grep filters out only IP addresses, so we don't get MX entries, or any other unresolved addresses;
hosts.txt is the input file, containing hostnames;
ip_list.txt is the output file, which will be used to feed masscan.
Then you can feed masscan with your generated ip_list.txt as demonstrated:
masscan -iL ip_list.txt -p 80
edit
I found another command that can achieve the same parallel effect, but it's a bit more exciting as it's easier, which is xarg,an example syntax on how to use it is the following:
cat hosts.txt | xargs -n1 -P100 dig +short +retry=3 | grep -E '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' > ip_list.txt
-P100 specifies 100 parallel processes;
-n1 gets only the first argument of a line from hosts.txt (changing it to higher shouldn't have any effect, as long as the input file has only hostnames separated by newlines);
The downside of this approach is that xargs doesn't retry if dig fails, but I used +retry for that;

masscan does not provide any option to run scan on domain name you have to provide it list of ip address. So if you have a list of domain names in a file you can use following script to get ip address of all the domains.
$ cat hosts
github.com
google.com
pentestmonkey.com
script:
import sys
import socket
read_file = open('hosts','r')
for host in read_file:
print socket.gethostbyname(host.rstrip("\n")) #rstrip for removing new line characters
read_file.close()

From the Comparison with Nmap section of the masscan README.md:
You can think of masscan as having the following settings permanently
enabled:
...
-n: no DNS resolution happens
So that tool will not facilitate conversion of the host names to IP addresses. You'll need to do that using a tool like host or dig and then feed the results into masscan.
massscan can read scan ranges (i.e. IP addresses and CIDR blocks) from a file, using the -iL <filename> flag.
Also worth mentioning, here's another excerpt from README.md:
Scanning the entire Internet is bad. For one thing, parts of the
Internet react badly to being scanned. For another thing, some sites
track scans and add you to a ban list, which will get you firewalled
from useful parts of the Internet.
If the "millions of domain names" aren't under your control, the warning above is applicable.

Use a high-speed (parallel or async) mass DNS resolver (massdns, fernmelder, etc.) to get the IP addresses for each DNS name efficiently. Use the IP addresses as input for masscan. If you'd like, you can plug the DNS names back in to the masscan JSON output with a dozen lines of Python.
Unless you're working on a very small scale, do NOT use Python or nmap to do your DNS resolution. You need native code to do this well, hence the recommendation for massdns or fernmelder

Related

Bash script or existing program to monitor "etc/hosts" file domain blacklist access?

This is sort of a complex question, I hope I can explain it clearly:
I have a long blacklist of domains added to my /etc/hosts file and it works perfectly. Now I want to be able to "monitor" with a "simple" Bash script every time a domain/entry is blocked, e.g.:
Let's say I'm running this hypothetical script on my Terminal and I try to access Facebook in my browser (which is blocked in my hosts file), I'd like to see in my Terminal something like:
0.0.0.0 facebook.com
Then, I try to access LinkedIn (also blocked), and now I want to see in my Terminal:
0.0.0.0 facebook.com
0.0.0.0 linkedin.com
Then, I try to access Instagram (blacklisted as well) and I see:
0.0.0.0 facebook.com
0.0.0.0 linkedin.com
0.0.0.0 instagram.com
And so on...
Is that possible? I've spent days looking for an existing program that does this but no luck..
It's possible; whether you find it simple is a different question.
Caveat: if you edit the hosts file you'll need to restart the process.
Save
BEGIN {
while (getline < "/etc/hosts") # read the hosts file line by line
{
split($0,fields," *") # break up each line on "any number of spaces" and assign to the array "fields"
hosts[fields[2]"."]++ # create an array "hosts" that holds e.g. www.google.com as it's key
}
close("/etc/hosts") # close the hosts file, be tidy
}
{
for(a=7;a<=NF;a++){ # for each line of input (these are now coming from tcpdump) iterate over the 7th to last (NF) fields
if($a in hosts){ # if the field is present in the hosts array (matches an index)
print $a # print it
}
}
}
as e.g. hosts.awk ...
You can then run
sudo tcpdump -l port 53 | awk -f hosts.awk

How to highlight words from one file in another file? (Linux)

host hostname {
hardware ethernet 00:10:E0:dF:e2:Ee;
fixed-address 192.168.*.*;
ddns-hostname name;
}
I have list of ip addresses in one file. How can I highlight those addresses in dhcpd.hosts file and still to see the whole block or the whole text?
emphasized text
I've tried to use while read variable; do grep $variable dhcpd.hosts; done < iplistfile
but it's printing only one line
You probably want
grep --color=always -f iplistfile dhcpd.hosts
and you might want to add the -F and -w options too.

How does one create a wrapper around a program?

I want to learn to create a wrapper around a program in linux. How does one do this? A tutorial reference web-page/link or example will do. To clarify what I want to learn, I will explain with an example.
I use vim for editing text files. And use rcs as my simple revision control system. rcs allows you to check-in and checkout-files. I would like to create a warpper program named vir which when I type in the shell as:
$ vir temp.txt
will load the file temp.txt into rcs with ci -u temp.txt and then allows me to edit the file using vim.
When I get out and go back in, It will need to check out the file first, using ci -u temp.txt and allow me to edit the file as one normally does with vim, and then when I save and exit, it should check-in the file using co -u temp.txt and as part of that I should be able to add a version control comment.
Basically, all I want to be doing on the command line is:
$ vir temp.txt
as one would with vim. And the wrapper should take care of the version control for me.
Take a look at rcsvers.vim, a vim plugin for automatically saving versions in RCS; you could modify that. There are also other RCS plugins for vim at vim.org
I have a wrapper to enhance the ping command (using zsh) it could, maybe help you:
# ping command wrapper - Last Change: out 27 2019 18:47
# source: https://www.cyberciti.biz/tips/unix-linux-bash-shell-script-wrapper-examples.html
ping(){
# Name: ping() wrapper
# Arg: (url|domain|ip)
# Purpose: Send ping request to domain by removing urls, protocol, username:pass using system /usr/bin/ping
local array=( $# ) # get all args in an array
local host=${array[-1]} # get the last arg
local args=${array[1,-2]} # get all args before last arg in $#
#local _ping="/usr/bin/ping"
local _ping="/bin/ping"
local c=$(_getdomainnameonly "$host")
[ "$host" != "$c" ] && echo "Sending ICMP ECHO_REQUEST to \"$c\"..."
# pass args and host
# $_ping $args $c
# default args for ping
$_ping -n -c 2 -i 1 -W1 $c
}
_getdomainnameonly(){
# Name: _getdomainnameonly
# Arg: Url/domain/ip
# Returns: Only domain name
# Purpose: Get domain name and remove protocol part, username:password and other parts from url
# get url
local h="$1"
# upper to lowercase
local f="${h:l}"
# remove protocol part of hostname
f="${f#http://}"
f="${f#https://}"
f="${f#ftp://}"
f="${f#scp://}"
f="${f#scp://}"
f="${f#sftp://}"
# Remove username and/or username:password part of hostname
f="${f#*:*#}"
f="${f#*#}"
# remove all /foo/xyz.html*
f=${f%%/*}
# show domain name only
echo "$f"
}
What it hides the local ping using a function called "ping", so if your script has precedence on your path it will find at first the function ping. Then inside the script I define an internal variable called ping that points out to the real ping command:
local _ping="/bin/ping"
You can also notice that the args are stored in one array.

extract data from text file with linux

I have file and I need to extract some data. the problem I'm facing is some line not almost the same with other lines. here is the example:
action=accept trandisp=noop srcip=1.1.1.1 dstip=2.2.2.2 service=PING proto=1 duration=61
action=accept trandisp=noop srcip=1.1.1.1 dstip=3.3.3.3 dstport=80 service=http proto=1 duration=61
I want to get the destination IP with service in the first row, and the
destination IP with dstport and service in the second line.
I'm new in linux and I tried it with grep and cut but it didn't work for me.
please help me with the explanation of your answer.
What about this one?
grep -o -P "dstip=[0-9.]+ (dstport=[0-9]+)? service=\w+ (dstport=[0-9]+)?" your-file
Explanation:
-o, --only-matching show only the part of a line matching PATTERN
-P, --perl-regexp PATTERN is a Perl regular expression
Of course, key-value order matters.

Why sometimes I am getting a bad hostname?

This is something really bizarre. We have a Shell script, that is to do server configuration on every Linux box. and it contains this line of command:
#!/bin/bash
...
hostname=`hostname -f 2>/dev/null`
Most of time, this line of script returns back the correct host name value, as:
+ hostname=xyz.companyname.com
But I have seen couple of times, the whole configure fails, because it gives back such output:
+ hostname=xyz.companyname.COM
I don't know why the last piece of domain name becomes UP-Case value.
I don't see anything suspicious in the /etc/hosts file. Any idea what could make such happen ?
Thanks,
Jack
Check /etc/hosts.
My understanding is that hostname -f can retrieve the hostname from DHCP (?) or /etc/hosts—based on what condition(s), I don't know.
But you may have a
123.45.67.89 xyz.companyname.com xyz.companyname.COM
or something similar in there.

Resources