Didier Stevens

Tuesday 30 July 2019

Quickpost: tcp-honeypot.py & Browser Tests

Filed under: My Software,Networking,Quickpost — Didier Stevens @ 0:00

tcp-honeypot.py is a Python program that allows you to define listeners using dictionaries: they listen on a given TCP port and process connections according to their configuration.

It started as a simple TCP honeypot, but now I use it too if I need a small network server.

For my quickpost “Quickpost: Browsers & Content-Disposition“, I needed a simple web server that would serve a page that I could fully control (headers & body).

I did this with tcp-honeypot. Dictionary dListeners (used by tcp-honeypot) defines the listeners: the keys are the TCP port numbers to listen on, and the values are dictionaries with configuration entries.

As I wanted to serve 3 different pages, I resorted to listen on 3 different ports (8080, 8081, 8082), each would serve a different page. Each dictionary for these listeners contains one entry with key THP_REPLY. Because each listener is very simple it listens for a connection and reads incoming data, discards it, and then sends its reply (regardless of input).

Here is the code to do this (file content-disposition-test.py):

#!/usr/bin/env python

__description__ = 'TCP honeypot configuration for Content-Disposition tests'
__author__ = 'Didier Stevens'
__version__ = '0.0.1'
__date__ = '2019/04/03'

"""
Source code put in public domain by Didier Stevens, no Copyright
https://DidierStevens.com
Use at your own risk

History:
  2019/04/03: start

Todo:
"""

dListeners = {
    8080:    {THP_REPLY: TW_CRLF(['HTTP/1.1 200 OK', 'Content-Disposition: inline', '', 'Line 1', 'Line 2', 'Line 3'])},
    8081:    {THP_REPLY: TW_CRLF(['HTTP/1.1 200 OK', 'Content-Disposition: attachment', '', 'Line 1', 'Line 2', 'Line 3'])},
    8082:    {THP_REPLY: TW_CRLF(['HTTP/1.1 200 OK', 'Content-Disposition: attachment; filename="test.js"', '', 'Line 1', 'Line 2', 'Line 3'])},
}

THP_REPLY configures a listener to read incoming data when a TCP connection is established, then send a reply (the value of dictionary entry THP_ENTRY) and then close the connection. This value is a string: the HTTP message (start-line, headers and body) to be send to the browser. In stead of defining one long string with start-line, headers and body, separated with carriage return & newline (CR NL), I use convenience function TW_CRNL. When you call convenience function TW_CRNL (Terminate With CR NL) with a list of strings, it terminates each string with CR NL (\r\n) and concatenates all strings into one string, that is returned by the function.

To start the server with this configuration, I just have to run tcp-honeypot.py with content-disposition-test.py as argument.

There are other methods to do this, for example using a single port. I’ll describe these methods in an upcoming blog post.


Quickpost info


2 Comments »

  1. This is great!!!!!!!!!! Cannot wait to try it! 🙂

    Comment by DK — Tuesday 30 July 2019 @ 8:30

  2. good python script.

    Comment by Cătălin George Feștilă — Friday 2 August 2019 @ 13:40


RSS feed for comments on this post. TrackBack URI

Leave a Reply (comments are moderated)

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Blog at WordPress.com.