Commit 8b17dc34 authored by jeromemarchand's avatar jeromemarchand Committed by yonghong-song

sslsniff: add NSS support (#1908)

* sslsniff: add NSS support

* sslsniff: update documentation
parent e6a166bc
.TH sslsniff 8 "2016-08-16" "USER COMMANDS" .TH sslsniff 8 "2016-08-16" "USER COMMANDS"
.SH NAME .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 .SH SYNOPSIS
.B sslsniff .B sslsniff [-h] [-p PID] [-c COMM] [-o] [-g] [-n] [-d]
.SH DESCRIPTION .SH DESCRIPTION
sslsniff prints data sent to SSL_write and SSL_read OpenSSL functions, allowing sslsniff prints data sent to write/send and read/recv functions of
us to read plain text content before encryption (when writing) and after OpenSSL, GnuTLS and NSS, allowing us to read plain text content before
decryption (when reading). encryption (when writing) and after decryption (when reading).
This works reading the second parameter of both functions (*buf). This works reading the second parameter of both functions (*buf).
...@@ -15,13 +15,13 @@ Since this uses BPF, only the root user can use this tool. ...@@ -15,13 +15,13 @@ Since this uses BPF, only the root user can use this tool.
CONFIG_BPF and bcc. CONFIG_BPF and bcc.
.SH EXAMPLES .SH EXAMPLES
.TP .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 .B sslsniff
.SH FIELDS .SH FIELDS
.TP .TP
FUNC FUNC
Which function is being called (SSL_write or SSL_read) Which function is being called (write/send or read/recv)
.TP .TP
TIME TIME
Time of the command, in seconds. Time of the command, in seconds.
...@@ -30,10 +30,10 @@ COMM ...@@ -30,10 +30,10 @@ COMM
Entered command. Entered command.
.TP .TP
PID PID
Process ID calling OpenSSL. Process ID calling SSL.
.TP .TP
LEN LEN
Bytes written or read by OpenSSL functions. Bytes written or read by SSL functions.
.SH SOURCE .SH SOURCE
This is from bcc. This is from bcc.
.IP .IP
......
#!/usr/bin/python #!/usr/bin/python
# #
# sslsniff Captures data on read/recv or write/send functions of OpenSSL and # sslsniff Captures data on read/recv or write/send functions of OpenSSL,
# GnuTLS # GnuTLS and NSS
# For Linux, uses BCC, eBPF. # For Linux, uses BCC, eBPF.
# #
# USAGE: sslsniff.py [-h] [-p PID] [-c COMM] [-o] [-g] [-d] # USAGE: sslsniff.py [-h] [-p PID] [-c COMM] [-o] [-g] [-d]
...@@ -25,6 +25,7 @@ examples = """examples: ...@@ -25,6 +25,7 @@ examples = """examples:
./sslsniff -c curl # sniff curl command only ./sslsniff -c curl # sniff curl command only
./sslsniff --no-openssl # don't show OpenSSL calls ./sslsniff --no-openssl # don't show OpenSSL calls
./sslsniff --no-gnutls # don't show GnuTLS calls ./sslsniff --no-gnutls # don't show GnuTLS calls
./sslsniff --no-nss # don't show NSS calls
""" """
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
description="Sniff SSL data", description="Sniff SSL data",
...@@ -37,6 +38,8 @@ parser.add_argument("-o", "--no-openssl", action="store_false", dest="openssl", ...@@ -37,6 +38,8 @@ parser.add_argument("-o", "--no-openssl", action="store_false", dest="openssl",
help="do not show OpenSSL calls.") help="do not show OpenSSL calls.")
parser.add_argument("-g", "--no-gnutls", action="store_false", dest="gnutls", parser.add_argument("-g", "--no-gnutls", action="store_false", dest="gnutls",
help="do not show GnuTLS calls.") 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, parser.add_argument('-d', '--debug', dest='debug', action='count', default=0,
help='debug mode.') help='debug mode.')
parser.add_argument("--ebpf", action="store_true", parser.add_argument("--ebpf", action="store_true",
...@@ -149,6 +152,20 @@ if args.gnutls: ...@@ -149,6 +152,20 @@ if args.gnutls:
b.attach_uretprobe(name="gnutls", sym="gnutls_record_recv", b.attach_uretprobe(name="gnutls", sym="gnutls_record_recv",
fn_name="probe_SSL_read_exit", pid=args.pid or -1) 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 # define output data structure in Python
TASK_COMM_LEN = 16 # linux/sched.h TASK_COMM_LEN = 16 # linux/sched.h
MAX_BUF_SIZE = 464 # Limited by the BPF stack MAX_BUF_SIZE = 464 # Limited by the BPF stack
......
Demonstrations of sslsniff.py Demonstrations of sslsniff.py
This tool traces the OpenSSL functions SSL_READ and SSL_WRITE. This tool traces the write/send and read/recv functions of OpenSSL,
Data passed to this functions is printed as plain text. GnuTLS and NSS. Data passed to this functions is printed as plain
Useful, for example, to sniff HTTP before encrypted with SSL. text. Useful, for example, to sniff HTTP before encrypted with SSL.
Output of tool executing in other shell "curl https://example.com" Output of tool executing in other shell "curl https://example.com"
% sudo python sslsniff.py % sudo python sslsniff.py
FUNC TIME(s) COMM PID LEN FUNC TIME(s) COMM PID LEN
SSL_WRITE 0.000000000 curl 12915 75 WRITE/SEND 0.000000000 curl 12915 75
----- DATA ----- ----- DATA -----
GET / HTTP/1.1 GET / HTTP/1.1
Host: example.com Host: example.com
...@@ -20,7 +20,7 @@ Accept: */* ...@@ -20,7 +20,7 @@ Accept: */*
----- END DATA ----- ----- END DATA -----
SSL_READ 0.127144585 curl 12915 333 READ/RECV 0.127144585 curl 12915 333
----- DATA ----- ----- DATA -----
HTTP/1.1 200 OK HTTP/1.1 200 OK
Cache-Control: max-age=604800 Cache-Control: max-age=604800
...@@ -38,7 +38,7 @@ Content-Length: 1270 ...@@ -38,7 +38,7 @@ Content-Length: 1270
----- END DATA ----- ----- END DATA -----
SSL_READ 0.129967972 curl 12915 1270 READ/RECV 0.129967972 curl 12915 1270
----- DATA ----- ----- DATA -----
<!doctype html> <!doctype html>
<html> <html>
...@@ -65,7 +65,7 @@ SSL_READ 0.129967972 curl 12915 1270 ...@@ -65,7 +65,7 @@ SSL_READ 0.129967972 curl 12915 1270
USAGE message: 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 Sniff SSL data
...@@ -75,6 +75,7 @@ optional arguments: ...@@ -75,6 +75,7 @@ optional arguments:
-c COMM, --comm COMM sniff only commands matching string. -c COMM, --comm COMM sniff only commands matching string.
-o, --no-openssl do not show OpenSSL calls. -o, --no-openssl do not show OpenSSL calls.
-g, --no-gnutls do not show GnuTLS calls. -g, --no-gnutls do not show GnuTLS calls.
-n, --no-nss do not show NSS calls.
-d, --debug debug mode. -d, --debug debug mode.
examples: examples:
...@@ -83,3 +84,4 @@ examples: ...@@ -83,3 +84,4 @@ examples:
./sslsniff -c curl # sniff curl command only ./sslsniff -c curl # sniff curl command only
./sslsniff --no-openssl # don't show OpenSSL calls ./sslsniff --no-openssl # don't show OpenSSL calls
./sslsniff --no-gnutls # don't show GnuTLS calls ./sslsniff --no-gnutls # don't show GnuTLS calls
./sslsniff --no-nss # don't show NSS calls
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment