CapTipper
Malicious HTTP traffic explorer
Install / Use
/learn @omriher/CapTipperREADME
CapTipper v0.3

CapTipper v0.3: http://www.omriher.com/2015/08/captipper-v03-is-out.html
CapTipper v0.2: http://www.omriher.com/2015/03/captipper-02-released.html
CapTipper v0.1: http://www.omriher.com/2015/01/captipper-malicious-http-traffic.html
CapTipper is a python tool to analyze, explore and revive HTTP malicious traffic.
CapTipper sets up a web server that acts exactly as the server in the PCAP file,
and contains internal tools, with a powerful interactive console, for analysis and inspection of the hosts, objects and conversations found.
The tool provides the security researcher with easy access to the files and the understanding of the network flow,
and is useful when trying to research exploits, pre-conditions, versions, obfuscations, plugins and shellcodes.
Feeding CapTipper with a drive-by traffic capture (e.g of an exploit kit) displays the user with the requests URI's that were sent and responses meta-data.
The user can at this point browse to http://127.0.0.1/[host]/[URI] and receive the response back to the browser.
In addition, an interactive shell is launched for deeper investigation using various commands such as: hosts, hexdump, info, ungzip, body, client, dump and more...
Documentation: http://captipper.readthedocs.org
Update from 02-Oct-2020:
CapTipper now supports Python3 and can be found in the following branch: https://github.com/omriher/CapTipper/tree/python3_support

Analysis Example
Usage: ./CapTipper.py <PCAP_file> [-p] [web_server_port=80]
Let's analyze the following Nuclear EK drive-by infection PCAP 2014-11-06-Nuclear-EK-traffic.pcap
C:\CapTipper> CapTipper.py "C:\NuclearFiles\2014-11-06-Nuclear-EK-traffic.pcap"
CapTipper v0.1 - Malicious HTTP traffic explorer tool
Copyright 2015 Omri Herscovici <omriher@gmail.com>
[A] Analyzing PCAP: C:\NuclearFiles\2014-11-06-Nuclear-EK-traffic.pcap
[+] Traffic Activity Time: Thu, 11/06/14 17:02:35
[+] Conversations Found:
0: / -> text/html (0.html) [5509 B]
1: /wp-includes/js/jquery/jquery.js?ver=1.7.2 -> application/javascript (jquery.js) [39562 B]
2: /seedadmin17.html -> text/html (seedadmin17.html) [354 B]
3: /15c0b14drr9f_1_08282d03fb0251bbd75ff6dc6e317bd9.html -> text/html (15c0b14drr9f_1_08282d03fb0251bbd75ff6dc6e317bd9.html) [113149 B]
4: /wp-content/uploads/2014/01/MetroWest_COVER_Issue2_Feb2014.jpg -> image/jpeg (MetroWest_COVER_Issue2_Feb2014.jpg) [350008 B]
5: /images/footer/3000melbourne.png -> image/png (3000melbourne.png) [2965 B]
6: /images/footer/3207portmelbourne.png -> image/png (3207portmelbourne.png) [3092 B]
7: /wp-content/uploads/2012/09/background1.jpg -> image/jpeg (background1.jpg) [33112 B]
8: /00015d76d9b2rr9f/1415286120 -> application/octet-stream (00015d76.swf) [31579 B]
9: /00015d766423rr9f/1415286120 -> application/pdf (XykpdWhZZ2.pdf) [9940 B]
10: /00015d76rr9f/1415286120/5/x00809070554515d565b010b03510053535c0505;1;6 -> application/octet-stream (5.exe) [139264 B]
11: /00015d76rr9f/1415286120/5/x00809070554515d565b010b03510053535c0505;1;6;1 -> application/octet-stream (5.exe) [139264 B]
12: /00015d76rr9f/1415286120/7 -> application/octet-stream (7.exe) [139264 B]
13: /00015d761709rr9f/1415286120 -> application/octet-stream (00015d76.swf) [8064 B]
14: /00015d76rr9f/1415286120/8 -> application/octet-stream (8.exe) [139264 B]
[+] Started Web Server on http://localhost:80
[+] Listening to requests...
CapTipper Interpreter
Type 'open <conversation id>' to open address in browser
type 'hosts' to view traffic flow
Type 'help' for more options
CT>
The Initialization outputs the conversations found between the client and the server in the following format:
[ID] : REQUEST URI -> SERVER RESPONSE TYPE (FILENAME) [SIZE IN BYTES]
ID: An assigned Id to the specific conversation
REQUEST URI: The URI that was sent to the server in the GET request
SERVER RESPONSE TYPE: The content-type returned in the server response header
FILENAME: The filename can be a few things:
- Filename attribute given in the response header
- Derived from the URI
- Assigned by CapTipper if couldn't find any of the above
SIZE IN BYTES: Response body size
After Initalization, 2 things occur:
- CapTipper creates a pseudo-web server that behaves like the web server in the pcap
- An Interpreter is launched
The interpreter contains internal tools for further investigation of the objects in the pcap.
Opening a URI in the browser is simply by typing 'open' along with the object id
CT> open 0
CT> log
[2015-01-09T18:01:28.878000] 127.0.0.1 : GET / HTTP/1.1
- None of the commands (Except 'open') actually requires the server to be running. You can turn off the server by typing 'server off' or by adding -s when calling CapTipper.
Let's see what can we find out without using the browser.
First, we'll take a bird's-eye view on the traffic by using the command 'hosts'
CT> hosts
Found Hosts:
www.magmedia.com.au
├-- / [0]
├-- /wp-includes/js/jquery/jquery.js?ver=1.7.2 [1]
├-- /wp-content/uploads/2014/01/MetroWest_COVER_Issue2_Feb2014.jpg [4]
├-- /images/footer/3000melbourne.png [5]
├-- /images/footer/3207portmelbourne.png [6]
└-- /wp-content/uploads/2012/09/background1.jpg [7]
pixeltouchstudios.tk
└-- /seedadmin17.html [2]
grannityrektonaver.co.vu
├-- /15c0b14drr9f_1_08282d03fb0251bbd75ff6dc6e317bd9.html [3]
├-- /00015d76d9b2rr9f/1415286120 [8]
├-- /00015d766423rr9f/1415286120 [9]
├-- /00015d76rr9f/1415286120/5/x00809070554515d565b010b03510053535c0505;1;6 [10]
├-- /00015d76rr9f/1415286120/5/x00809070554515d565b010b03510053535c0505;1;6;1 [11]
├-- /00015d76rr9f/1415286120/7 [12]
├-- /00015d761709rr9f/1415286120 [13]
└-- /00015d76rr9f/1415286120/8 [14]
It seems that www.magmedia.com.au is the compromised site.
By crossing this information and the file types we got in the conversations list, it looks like grannityrektonaver.co.vu is the infecting host.
Then what is pixeltouchstudios.tk ?
Well, knowing how exploit-kits usually work, this is probably the TDS (Traffic Distribution System) server.
Let's take a closer look.
We can print the header and the body of the page by typing 'head' and 'body':
CT> head 2
Displaying header of object 2 (seedadmin17.html):
HTTP/1.1 302 Found
Server: nginx
Date: Thu, 06 Nov 2014 15:02:38 GMT
Content-Type: text/html; charset=iso-8859-1
Content-Length: 354
Connection: keep-alive
Set-Cookie: ehihm=_YocADE3AAIAAgCvjVtU__.vjVtUQAABAAAAr41bVAA-; expires=Fri, 06-Nov-2015 15:03:11 GMT; path=/; domain=pixeltouchstudios.tk
Location: http://grannityrektonaver.co.vu/15c0b14drr9f_1_08282d03fb0251bbd75ff6dc6e317bd9.html
CT> body 2
Displaying body of object 2 (seedadmin17.html) [256 bytes]:
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>302 Found</title>
</head><body>
<h1>Found</h1>
<p>The document has moved <a href="http://grannityrektonaver.co.vu/15c0b14drr9f_1_08282d03fb0251bbd75ff6dc6e317bd9.html">here</a>.</p>
<hr
- By deafult, the body command returns the first 256 byte, you can change it by typing body 2 1000 - this will print the first 1000 bytes
We see that object 2, returns a 302 redirection to the infecting host.
So our hypothesis was probably true.
Let's get more information on object 2 by typing 'info':
CT> info 2
Info of conversation 2:
SERVER IP : 108.61.196.84:80
HOST : pixeltouchstudios.tk
URI : /seedadmin17.html
REFERER : http://www.magmedia.com.au/
RESULT NUM : 302 Found
RESULT TYPE : text/html
FILE NAME : seedadmin17.html
LENGTH : 354 B
The referrer to that page was of course magmedia.co.au, but what exactly redirected us?
By looking at the conversations it was probably either the index page or the javascript file.
Let's have a quick peek at the javascript file (object 1)
CT> body 1
Displaying body of object 1 (jquery.js) [256 bytes]:
▼ ♦♥─╜i{#╟ס╢√}~♣X╓t♥═"HJצg♀░→o½%Y▓╡ם║m┘CR║
@a!▒P ╪כ ╬o?≈‼╣TJ≥£≈\g╞jó╢\"#cן╚πg ÷ry≤~5↔O6םµ╦Vπ├ףף h|╛*ך╞½σh≤6_§ם╧ק╖כa╛ש.↨iπ╦┼á▌רl67¥ππ╤z╘^«╞╟ ÷∞°▀F╖כב▐hלכ═╦σ≥zZ4≤╓▌¢|╒Φg├σαv^,6φב=h╧≤═`╥\¶o
←▀↨π╧▐▌4ףf»≤π╢█h%חy{U▄╠≥A╤<n₧_┤?Φ=█▐▌_4/Z↨τ↨ק↨↨↨╟↨ח?^╢מ╟irq±┴i
Hmm... What's going on? Let's look at the header
CT> head 1
Displaying header of object 1 (jquery.js):
HTTP/1.1 200 OK
Content-Encoding: gzip
Vary: Accept-Encoding
Date: Thu, 06 Nov 2014 15:03:41 GMT
Server: LiteSpeed
Accept-Ranges: bytes
Connection: Keep-Alive
Keep-Alive: timeout=5, max=100
Last-Modified: Mon, 10 Feb 2014 12:34:10 GMT
Content-Type: application/javascript
Content-Length: 39562
Cache-Control: public, max-age=604800
Expires: Thu, 13 Nov 2014 15:03:41 GMT
The response is gzipped.
Let's ungzip it:
CT> ungzip 1
GZIP Decompression of object 1 (jquery.js) successful!
New object created: 15
Great. a new object was created (15).
Let's look at it.
CT> body 15
Displaying body of object 15 (ungzip-jquery.js) [256 bytes]:
/*
Copyright (C) 2007 Free Software Foundation, Inc. http://fsf.org/
*/
function getCookie(a){var b=document.cookie.match(new RegExp("(?:^|; )"+a.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g,"\\$1")+"=([^;]*)"));return b?decodeU
RIComponent(b[1]):undefined}(funct
So this is the ungzipped version of the JS file.
Remember, we want to find out what redirected us to the TDS,
Safe to assume it was an iframe, so
Related Skills
node-connect
344.1kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
96.8kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
344.1kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
344.1kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
