Running Nmap from Chat with Legobot
Chatops for hackers!
For those of you who saw my shenanigans in IRC earlier, this is the promised post on what I was doing. For those who missed it or don’t hang out in IRC, shame! This is an announcement of a new package I released today, description of how to use it, and solicitation for feedback. We’re going to talk about running Nmap from chat mediums such as Slack and IRC.
Required Skills
Understanding of nmap and python will be helpful for this, but not essential.
Disclaimer
If you leave this bot in an IRC or Slack with other people, whoever sends it a scan command will launch a scan from your IP. You don’t want that.
Introduction
Nmap is a favorite tool among securitry professionals and system administrators alike, providing a powerful and comparatively simple* tool for testing network connections, listening services, and more.
Chatops, as defined quite well by Atlassian:
ChatOps is a collaboration model that connects people, tools, process, and automation into a transparent workflow
For the hacker unacquainted wth ChatOps and what that might mean, one of the major principles of ChatOps involves consolidating flow of information to a single location. You may have many sources of information (we’ll call them signal), and going out to the various sources of the signals to gather information for analysis can result in a lot of work.
*Try writing your own port scanner that does what Nmap does.
Now imagine yourself in a team context, where you need to generate the information, collect it, share it, and then process it with everyone, you can see the need for what we call a “shared context” for information. Imagine Alice and Bob are on a red team. Alice runs an nmap scan and Bob runs some work in SQLmap. Those results should automatically come back to chat so that both Alice and Bob can see all the information generated.
But why?
Applying ChatOps to red team and blue team operations means invoking security tools from chat, consolidating information, reducing turnaround time for iterating to the next step in attack or analysis, improving analysis by improving access to information, and ultimately looking really freaking cool by pwning a box from a couple commands on irc
The Framework
Now that I’ve hopefully sold you on that one area of ChatOps (there are many more good reasons to adopt it), let’s look at the framework we’ll use for this.
A couple of years ago, I started Legobot with a friend. Over time, it has grown into my own favorite tool for integrating any task I want into chat and a generally useful ChatOps framework. I’ve used for tracking pull requests from FOSS communities, keeping people up to date on version numbers, publishing Gists on Github, querying Kubernetes for deployment status of applications at work, keeping track of karma points in a community, and managing queue rotations for on-call engineers. I love it. I won’t dig too deep into how Legobot works here, though. This post is about an nmap plugin I wrote for it.
The plugin (Lego)
What better name for a plugin to Legobot than a Lego? Our lego here is a wrapper for python-nmap. Python-nmap is crazy easy to use, Python 3 compatible, and results are easily parsable. In other words, a perfect candidate.
In order to make it easy to add or modify scan behavior for the intrepid hacker, I have used what I call a “dispatcher” pattern that allows the programmer to drop in a new argv[1]
parameter to be executed without much trouble.
def _dispatcher(self, message):
command = message['text'].split()[1]
commands = {'simple': self._basic_scan, 'os': self._os_detect}
if command in commands:
commands[command](message)
return True
else:
self.reply(message, 'Command not supported. RTFM.',
self._handle_opts(message))
return False
After extracting the command from the message, we compare that with the commands in the commands
dict. The value for each of those keys is the corresponding method that handles whatever command we’re asking for. Therefore, adding a new command is a matter of adding a new key and value to the dictionary in self._dispatcher()
and adding the corresponding method to handle it.
Usage
Now to see it in action.
OS detection (bot must be running as root):
“22:34” fraq ╡ !nmap os 127.0.0.1
“22:34” mmp-test ╡ Host: 127.0.0.1 | tcp [22, 25, 445, 587, 6969, 8081, 8443] |OS best guess (100% confidence): Apple macOS 10.12 (Sierra) (Darwin 16.0.0) |
Simple scans:
“21:25” fraq ╡ !nmap 127.0.0.1 22-1024
“21:26” mmp-test ╡ Host: localhost | tcp [22, 25, 445, 587] |
All host arguments can accept ranges in the same way the nmap CLI can.
Over the next little bit I will continue to improve this. I have successfully tested running built-in nmap scripts as well. I also plan to allow for raw nmap queries
Conclusion
While on the surface, this paper is about using nmap from Legobot, which is cool but simple, it’s really about introducing security type people to the sort of possibilities offered by chat as a medium for getting crap done and not just talking.
I’ve long championed the sharing of techniques and principles between Ops and Infosec. In this instance, I feel that for group engagements or blue-team work, ChatOps can be a powerful method for working faster and more accurately.
Launching commands and receiving input in chat lets everyone collaborate and participate in real-time. Additionally, wrapping commands with shorthand like this provides less opportunity for error by simplfying the invocation. Finally, by abstracting the data you’re after from the tool you’re using (not a technique we did here), you can change magic in the middle without users having to change workflows. Example: 'who is google.com` could use nmap, dig, or nslookup on the backend. As long as information is presented back to the user with a consistent format, it doesn’t matter.
I hope you enjoyed this and that it gets you thinking about all the cool things you can do with bots (and hopefully use Legobot to do them!)