Skip to content

Commit

Permalink
sslsniff: add NSS support (iovisor#1908)
Browse files Browse the repository at this point in the history
* sslsniff: add NSS support

* sslsniff: update documentation
  • Loading branch information
jeromemarchand authored and yonghong-song committed Aug 4, 2018
1 parent e6a166b commit 8b17dc3
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 18 deletions.
18 changes: 9 additions & 9 deletions man/man8/sslsniff.8
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
.TH sslsniff 8 "2016-08-16" "USER COMMANDS"
.SH NAME
sslsniff \- Print data passed to OpenSSL. Uses Linux eBPF/bcc.
sslsniff \- Print data passed to OpenSSL, GnuTLS or NSS. Uses Linux eBPF/bcc.
.SH SYNOPSIS
.B sslsniff
.B sslsniff [-h] [-p PID] [-c COMM] [-o] [-g] [-n] [-d]
.SH DESCRIPTION
sslsniff prints data sent to SSL_write and SSL_read OpenSSL functions, allowing
us to read plain text content before encryption (when writing) and after
decryption (when reading).
sslsniff prints data sent to write/send and read/recv functions of
OpenSSL, GnuTLS and NSS, allowing us to read plain text content before
encryption (when writing) and after decryption (when reading).

This works reading the second parameter of both functions (*buf).

Expand All @@ -15,13 +15,13 @@ Since this uses BPF, only the root user can use this tool.
CONFIG_BPF and bcc.
.SH EXAMPLES
.TP
Print all calls to SSL_write and SSL_read system-wide:
Print all calls to SSL write/send and read/recv system-wide:
#
.B sslsniff
.SH FIELDS
.TP
FUNC
Which function is being called (SSL_write or SSL_read)
Which function is being called (write/send or read/recv)
.TP
TIME
Time of the command, in seconds.
Expand All @@ -30,10 +30,10 @@ COMM
Entered command.
.TP
PID
Process ID calling OpenSSL.
Process ID calling SSL.
.TP
LEN
Bytes written or read by OpenSSL functions.
Bytes written or read by SSL functions.
.SH SOURCE
This is from bcc.
.IP
Expand Down
21 changes: 19 additions & 2 deletions tools/sslsniff.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/python
#
# sslsniff Captures data on read/recv or write/send functions of OpenSSL and
# GnuTLS
# sslsniff Captures data on read/recv or write/send functions of OpenSSL,
# GnuTLS and NSS
# For Linux, uses BCC, eBPF.
#
# USAGE: sslsniff.py [-h] [-p PID] [-c COMM] [-o] [-g] [-d]
Expand All @@ -25,6 +25,7 @@
./sslsniff -c curl # sniff curl command only
./sslsniff --no-openssl # don't show OpenSSL calls
./sslsniff --no-gnutls # don't show GnuTLS calls
./sslsniff --no-nss # don't show NSS calls
"""
parser = argparse.ArgumentParser(
description="Sniff SSL data",
Expand All @@ -37,6 +38,8 @@
help="do not show OpenSSL calls.")
parser.add_argument("-g", "--no-gnutls", action="store_false", dest="gnutls",
help="do not show GnuTLS calls.")
parser.add_argument("-n", "--no-nss", action="store_false", dest="nss",
help="do not show NSS calls.")
parser.add_argument('-d', '--debug', dest='debug', action='count', default=0,
help='debug mode.')
parser.add_argument("--ebpf", action="store_true",
Expand Down Expand Up @@ -149,6 +152,20 @@
b.attach_uretprobe(name="gnutls", sym="gnutls_record_recv",
fn_name="probe_SSL_read_exit", pid=args.pid or -1)

if args.nss:
b.attach_uprobe(name="nspr4", sym="PR_Write", fn_name="probe_SSL_write",
pid=args.pid or -1)
b.attach_uprobe(name="nspr4", sym="PR_Send", fn_name="probe_SSL_write",
pid=args.pid or -1)
b.attach_uprobe(name="nspr4", sym="PR_Read", fn_name="probe_SSL_read_enter",
pid=args.pid or -1)
b.attach_uretprobe(name="nspr4", sym="PR_Read",
fn_name="probe_SSL_read_exit", pid=args.pid or -1)
b.attach_uprobe(name="nspr4", sym="PR_Recv", fn_name="probe_SSL_read_enter",
pid=args.pid or -1)
b.attach_uretprobe(name="nspr4", sym="PR_Recv",
fn_name="probe_SSL_read_exit", pid=args.pid or -1)

# define output data structure in Python
TASK_COMM_LEN = 16 # linux/sched.h
MAX_BUF_SIZE = 464 # Limited by the BPF stack
Expand Down
16 changes: 9 additions & 7 deletions tools/sslsniff_example.txt
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
Demonstrations of sslsniff.py


This tool traces the OpenSSL functions SSL_READ and SSL_WRITE.
Data passed to this functions is printed as plain text.
Useful, for example, to sniff HTTP before encrypted with SSL.
This tool traces the write/send and read/recv functions of OpenSSL,
GnuTLS and NSS. Data passed to this functions is printed as plain
text. Useful, for example, to sniff HTTP before encrypted with SSL.


Output of tool executing in other shell "curl https://example.com"

% sudo python sslsniff.py
FUNC TIME(s) COMM PID LEN
SSL_WRITE 0.000000000 curl 12915 75
WRITE/SEND 0.000000000 curl 12915 75
----- DATA -----
GET / HTTP/1.1
Host: example.com
Expand All @@ -20,7 +20,7 @@ Accept: */*

----- END DATA -----

SSL_READ 0.127144585 curl 12915 333
READ/RECV 0.127144585 curl 12915 333
----- DATA -----
HTTP/1.1 200 OK
Cache-Control: max-age=604800
Expand All @@ -38,7 +38,7 @@ Content-Length: 1270

----- END DATA -----

SSL_READ 0.129967972 curl 12915 1270
READ/RECV 0.129967972 curl 12915 1270
----- DATA -----
<!doctype html>
<html>
Expand All @@ -65,7 +65,7 @@ SSL_READ 0.129967972 curl 12915 1270

USAGE message:

usage: sslsniff.py [-h] [-p PID] [-c COMM] [-o] [-g] [-d]
usage: sslsniff.py [-h] [-p PID] [-c COMM] [-o] [-g] [-n] [-d]

Sniff SSL data

Expand All @@ -75,6 +75,7 @@ optional arguments:
-c COMM, --comm COMM sniff only commands matching string.
-o, --no-openssl do not show OpenSSL calls.
-g, --no-gnutls do not show GnuTLS calls.
-n, --no-nss do not show NSS calls.
-d, --debug debug mode.

examples:
Expand All @@ -83,3 +84,4 @@ examples:
./sslsniff -c curl # sniff curl command only
./sslsniff --no-openssl # don't show OpenSSL calls
./sslsniff --no-gnutls # don't show GnuTLS calls
./sslsniff --no-nss # don't show NSS calls

0 comments on commit 8b17dc3

Please sign in to comment.