Monday, December 15, 2014

Windows System error 1219, multiple connections to a server or shared resource by the same user

Here's a funny one I ran into earlier.

So I try to mount a SAMBA share on a Windows system. I get this error:



Wait, are you telling me that I am restricted to having only one share subdirectory connected per PC? What happens if I need two? Now that's some crappy engineering right there Batman!

Oh, I know what this is. It's probably one of those Windows "features" and if I do the same thing from the command line, it'll just work, right? Right? Wrong.

F:\Documents and Settings\user>net use Q: \\192.168.0.254\DIR2 /USER:shareuser /PERSISTENT:NO
The password is invalid for \\192.168.0.254\DIR2.

Enter the password for 'shareuser' to connect to '192.168.0.254':
Multiple connections to a server or shared resource by the same user, using more than one user name, are not allowed. Disconnect all previous connections to the server or shared resource and try again..

Through some digging I managed to find out that this is by design. Windows will connect to a share once; if you try to connect again, it will block you. If you want to connect to a different subdirectory of your SAMBA server, you will need to disconnect from the one you are currently connected to.

Fret not though, for this is Windows; home of the crappiest, nastiest pieces of engineering ever came to existence.

Workaround? Just edit your %WINDIR%/system32/drivers/etc/hosts file and add some more entries that correspond to your share's IP address. For instance:

192.168.0.254 foo
192.168.0.254 bar
192.168.0.254 foobar
192.168.0.254 fubar

And now I can connect to my share using my new aliases:

F:\Documents and Settings\user>net use Q: \\fubar\DIR2 /USER:shareuser /PERSISTENT:NO
The password is invalid for \\fubar\DIR2.

Enter the password for 'shareuser' to connect to 'fubar':
The command completed successfully.

Oh Windows how I hate thee with all my passion.

Friday, December 5, 2014

Recover BMC administrator password on HP Proliant DL180 G6

This is from my notes. I don't have an HP Proliant DL180 G6 server in front of me, but I trust my notes and I think this description should be as accurate as it can. You'll need a PC with an internet connection, a USB drive and a jumper connector. You might also need a Linux Live CD (the instructions here assume that you have a RHEL-based Live CD).

a) Disconnect AC power from the system
b) Insert jumper on connector J27, D group pins 
c) Update BMC firmware using HP ROMPaq Firmware Upgrade for HP ProLiant G6 Lights-Out 100 Remote Management (For USB Key-Media).
    Detailed information is available at the following Web page: http://h20000.www2.hp.com/bizsupport/TechSupport/SoftwareDescription.jsp?lang=en&cc=us&prodTypeId=15351&prodSeriesId=3884343&swItem=MTX-bd27c5aa4f134285aa4825e143&prodNameId=3884344&swEnvOID=1005&swLang=13&taskId=135&mode=4&idx=1
d) Copy the impitool.exe binary from http://www.intel.com/design/servers/ipmi/ipmi_tool.htm onto the USB drive
e) Remove AC power and remove the jumper from J27, D group pins.
f) After BMC recovery is complete, boot from the USB key again and do:
ipmitool.exe 20 18 47 03 02 61 64 6d 69 6e 00 00 00 00 00 00 00 00 00 00 00
g) Remove USB drive and shutdown.
h) If the admininstrator user was "admin" you can now log in as admin/admin. If you still can't log in, proceed as follows (the following instructions are for a RHEL Live CD):
  1. Get a Linux Live CD
  2. yum update
  3. modprobe ipmi_msghandler
  4. modprobe ipmi_devintf
  5. modprobe ipmi_si
  6. yum search ipmi
  7. yum -y install ipmitool
  8. ipmitool user list
  9. note down the name of user id #3 and log in with that as a username and password admin.

Wednesday, December 3, 2014

PCI-DSS, nginx access logs, and credit card masking

PCI-DSS states that the card number must not be displayed in full—no more than the first six and the last four digits may be visible on a screen, a receipt, or on any other media used by the organization.

Sometimes your web server might leave access logs that contain this sort of information though. Here's an nginx access log snippet:

1.2.3.4 - - [02/Dec/2014:14:58:54 +0200] "GET /ccsite/?card_number=5100+1500+0000+0001&amount=10000&cvv=123&holder_name=N.Ame&expiration_month=1&expiration_year=2015&description=Something&_method=POST HTTP/1.1" 200 395 "https://partnersite.com/apps/ccapp?dothis.js" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:33.0) Gecko/20100101 Firefox/33.0"
1.2.3.4 - - [02/Dec/2014:16:07:46 +0200] "password=12345678&username=my_username" 200 416 "-" "Dalvik/1.6.0 (Linux; U; Android 4.3; C1905 Build/15.4.A.1.9)" 

Ouch, we shouldn't be writing stuff like this to our logs!

So what so we do?

Well, in this example I'm going to install the ngx_http_perl_module and use regular expressions to mask out the credit card and CVV.

First of all, let's see if we have Perl installed. Also, in order for Perl to recompile the modified modules during reconfiguration, it should be built with the -Dusemultiplicity=yes or -Dusethreads=yes parameters. Also, to make Perl leak less memory at run time, it should be built with the -Dusemymalloc=no parameter.

Let's check if we're good to go:

[root@webserver ~]# perl -V:usemultiplicity -V:usemymalloc
usemultiplicity='define';
usemymalloc='n';

Let's install some prerequisites to embed our Perl:

[root@webserver ~]# yum install perl-CPAN perl-ExtUtils-CBuilder perl-ExtUtils-MakeMaker perl-ExtUtils-Embed perl-devel 

Great. Now, let's back up our nginx configuration files and recompile it:

[root@webserver ~]# cp -rf /opt/nginx/conf/ /root/nginx_conf_bak

OK, now we should configure nginx as always, but with the addition of --with-http_perl_module. So in my case it is:

[root@webserver nginx-1.6.2]# ./configure --add-module=../naxsi/naxsi-master/naxsi_src/ --prefix=/opt/nginx --error-log-path=/var/log/nginx/nginx_error.log --http-log-path=/var/log/nginx/nginx_access.log --user=www-data --group=www-data --with-http_addition_module --with-http_geoip_module --with-http_gzip_static_module --with-http_stub_status_module --with-http_realip_module --without-mail_pop3_module --without-mail_smtp_module --without-mail_imap_module --without-http_memcached_module --without-http_ssi_module --without-http_uwsgi_module --without-http_scgi_module --with-http_perl_module

If you, like me, like to change the nginx headers and version to spoof their make to something else, say, IIS, then you should also make sure that the #define NGINX_VERSION in /src/core/nginx.h variable consists of numbers and dots only, for example not 3.4.1 (Unix), but 3.4.1, otherwise you'll encounter compilation problems.

Let's proceed to the installation of our new nginx binary that will now support the nginx perl module:

[root@webserver ~]# make
[root@webserver ~]# make install

Let's restore our old config:
[root@webserver ~]# cd /opt/nginx/conf/
[root@webserver ~]# rm -rf *
[root@webserver conf]# cp -rf /root/nginx_conf_bak/* .
[root@webserver conf]# chown -R www-data:www-data *

Time to do some substitutions using regular expressions on our logs. This needs to be in our http block:

[root@webserver ~]# vi nginx.conf
....
http {
perl_set $anonymize_data '
                sub {
                        my $r = shift;
                        my $req =  $r->request_body;
                        $req =~ s/\?card_number\=(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|6(?:011|5[0-9]{2})[0-9]{12}|(?:2131|1800|35\d{3})\d{11})/\?card_number\=XXXX-XXXX-XXXX-XXXX/g;
                        $req =~ s/\&card_number\=(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|6(?:011|5[0-9]{2})[0-9]{12}|(?:2131|1800|35\d{3})\d{11})/\&card_number\=XXXX-XXXX-XXXX-XXXX/g;
                        $req =~ s/\&cvv\=\d\d\d/\?cvv\=XXX/g;
                        $req =~ s/\&cvv\=\d\d\d/\&cvv\=XXX/g;
                        $req =~ s/password\=\w+/password\=XXXXXXXX/g;
                        return $req;
                } ';

Notice that I cover both scenarios; if the card_number arrives first (?card_number); or as a secondary/tertiary variable (&card_number). I do the same for the CVV. Replace "card_number" and "cvv" with whatever variable names your requests come as.

Finally, you will need to replace your "$request" with "$anonymize_data" in your log_format, like so:

log_format main $remote_addr - $remote_user [$time_local] "$anonymize_data" $status $body_bytes_sent "$http_referer" "$http_user_agent";

And now the card number, the CVV and the user's password get masked.

1.2.3.4 - - [02/Dec/2014:14:58:54 +0200] "GET /ccsite/?card_number=XXXX-XXXX-XXXX-XXXX&amount=10000&cvv=XXX&holder_name=N.Ame&expiration_month=1&expiration_year=2015&description=Something&_method=POST HTTP/1.1" 200 395 "https://partnersite.com/apps/ccapp?dothis.js" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:33.0) Gecko/20100101 Firefox/33.0"
1.2.3.4 - - [02/Dec/2014:16:07:46 +0200] "password=XXXXXXXX&username=my_username" 200 416 "-" "Dalvik/1.6.0 (Linux; U; Android 4.3; C1905 Build/15.4.A.1.9)"