huuck / ADBHoney

Low interaction honeypot designed for Android Debug Bridge over TCP/IP
GNU General Public License v3.0
158 stars 33 forks source link

Json logging #2

Closed fe7ch closed 5 years ago

fe7ch commented 5 years ago

It would be awesome to have json logging of interesting events (connects, commands, payloads).

bontchev commented 5 years ago

Indeed, I was thinking about this very same thing. It's on my to-do list for this honeypot; I was just waiting for the line indentation to be fixed, so that I would be sure to understand the structure of the program correctly and not to mess things up when modifying it.

Regarding the JSON logging, I've been looking at what Cowrie logs and trying to design something similar. Here is a proposal; feel free to change or improve.

First of all, the honeypot should log events, one JSON line per event. Events are things like establishing a connection, sending a shell line to the honeypot, uploading a file, closing (or breaking) a connection, etc. Here are examples of events and how they should be logged:

1) When a connection is established:

{
    "eventid": "adbhoney.session.connect",
    "timestamp": "2017-01-23T07:26:29.081081Z",
    "session": "f35bd10b32e2",
    "message": "New connection: 46.166.142.56:58692 (192.168.0.102:5555) [session: f35bd10b32e2]",
    "system": "ADBHoneyTransport,0,46.166.142.56",
    "isError": 0,
    "src_ip": "46.166.142.56",
    "src_port": 58692,
    "dst_port": 5555,
    "dst_ip": "192.168.0.102",
    "sensor": "vesselin-pc"
}

eventid is the name of the event.

timestamp is the time at which the event occurred (in UTC time zone, human-readable format - not as it currently is, as Unix epoch time).

session is the session number (a random number in hex) assigned to the session. A session is created when a connection is established and it ends when the connection is closed (or broken). The session number serves to link together the different events that occur during the same session.

message is a human-readable message describing the event.

system is something that Cowrie has but I'm not sufficiently confident that we need here. Since this is only an ADB honeypot (Cowrie is both SSH and Telnet), we don't really need to distinguish between different kinds of communication protocols. But if we decide to keep it, the number after the first comma is the thread number, and after that is the IP of the attacker.

isError is indication whether an error occurred while establishing the connection. This, too, might be unnecessary, since if there is an error, the connection simply isn't established and we have nothing to log.

src_ip is the IP address of the attacker.

src_port is the internal port it connects to. These should be reported separately (host, port), not as a single string as it is currently done.

dst_port is the port of the honeypot the connection connects to, 5555 by default, but it would be possible to move it elsewhere if, for some reason, we prefer the honeypot to listen to a different port.

dst_ip is the local IP of the machine running the honeypot.

sensor is the hostname of the machine running the honeypot. This is necessary, because we might have the honeypot running on multiple machines and aggregating their JSON (or other) logs in a common database. We want to be able to distinguish which data came from which particular honeypot.

In the next events I'll add explanation only of the fields that are new (i.e., not described above).

2) When the attacker issues a shell command:

{
    "eventid": "adbhoney.command.input",
    "timestamp": "2017-01-22T07:25:36.762093Z",
    "session": "f35bd10b32e2",
    "message": "shell:pm path com.ufo.miner",
    "system": "ADBHoneyTransport,0,46.166.142.56",
    "isError": 0,
    "src_ip": "118.179.176.136",
    "input": "pm path com.ufo.miner",
    "sensor": "vesselin-pc"
}

input is the exact command as issued by the attacker (i.e., what follows "shell:" currently in the log), even if it consists of multiple (i.e., separated by semicolons) shell commands.

3) Each shell command input should be split by the semicolon (if any) and for each part one of the following two events should be generated. Currently there is no shell emulation and all commands succeed (i.e., only events of the first kind will be present in the log) but I'm trying to account here for future development when we might add some kind of shell command emulation.

{
    "eventid": "adbhoney.command.success",
    "timestamp": "2017-01-22T07:25:36.763907Z",
    "session": "f35bd10b32e2",
    "message": "Command found: pm path com.ufo.miner",
    "system": "ADBHoneyTransport,0,46.166.142.56",
    "isError": 0,
    "src_ip": "118.179.176.136",
    "input": "pm path com.ufo.miner",
    "sensor": "vesselin-pc"
}

{
    "eventid": "adbhoney.command.failed",
    "timestamp": "2017-01-22T07:25:37.252756Z",
    "session": "f35bd10b32e2",
    "message": "Command not found: pm path com.ufo.miner",
    "system": "ADBHoneyTransport,0,46.166.142.56",
    "isError": 0,
    "src_ip": "118.179.176.136",
    "input": "pm path com.ufo.miner",
    "sensor": "vesselin-pc"
}

4) When the attacker is initiating a file upload directly (i.e., not via a shell command that calls wget or something), the following event should be logged:

{
    "eventid": "adbhoney.session.file_upload",
    "timestamp": "2017-01-23T12:30:58.682695Z",
    "session": "f35bd10b32e2",
    "message": "Downloaded file with SHA-256 d7188b8c575367e10ea8b36ec7cca067ef6ce6d26ffa8c74b3faa0b14ebb8ff0 to dl/data-d7188b8c575367e10ea8b36ec7cca067ef6ce6d26ffa8c74b3faa0b14ebb8ff0.raw"
    "system": "ADBHoneyTransport,0,46.166.142.56",
    "isError": 0,
    "src_ip": "109.236.92.150",
    "shasum": "d7188b8c575367e10ea8b36ec7cca067ef6ce6d26ffa8c74b3faa0b14ebb8ff0",
    "outfile": "dl/data-d7188b8c575367e10ea8b36ec7cca067ef6ce6d26ffa8c74b3faa0b14ebb8ff0.raw",
    "sensor": "vesselin-pc",
}

outfile should reflect the path on the local file system of the honeypot, where the file is saved. This should be configurable (I'll open an issue about this later) and not be in the same directory where the honeypot is.

5) Finally, when the session is closed (normally or because the attacker has reset the connection), the following event should be logged:

{
    "eventid": "adbhoney.session.closed",
    "timestamp": "2017-01-23T07:27:06.639586Z",
    "session": "f35bd10b32e2",
    "message": "Connection reset by peer after 37 seconds",
    "system": "ADBHoneyTransport,0,46.166.142.56",
    "isError": 0,
    "src_ip": "46.166.142.56",
    "duration": 37.55857801437378,
    "sensor": "vesselin-pc"
}

duration is self-explanatory.

message should contain information whether the connection was closed normally or due to an error (connection reset).

This is all I could think of on this subject right now.

bontchev commented 5 years ago

Implemented JSON logging (pull request #22). Quick and dirty for now; just to get something that works. Eventually parts of it will be rewritten when/if we implement support of output plug-ins like in Cowrie.

huuck commented 5 years ago

Gonna close this one, JSON logging seems to be in order for now.