Wednesday, May 27, 2015

Update all GIT and SVN repositories in all subfolders

If you happen to have a large collection of tools, some of which come from GitHub or other Git repositories, some others come from Google code or other subversion repos, this is for you.

The script below will recursively scan a base directory and find all Git and SVN repos, and update them.

Add a crontab entry to call this script every day if you like.

#!/bin/bash

BASEDIR=${HOME}/pentest

# Updating git repos
for d in `find ${BASEDIR} -type d -exec test -d '{}/.git' \; -prune -print`; do
   cd "$d"
   echo Updating `pwd` ...
   git pull
done

# Updating SVN repos
for d in `find ${BASEDIR} -type d -exec test -d '{}/.svn' \; -prune -print`; do
   cd "$d"
   echo Updating `pwd` ...
   svn up
done

That's all.

Tuesday, March 10, 2015

[How-To] Provide a password to su from the command line

How to provide a password to SU from the command line or from a script

For security reasons, /bin/su does not accept a password from the command line:

user@host$ echo pass | su -c id
su: must be run from a terminal

When you can execute commands on a system but you don't have an interactive shell (these things happen), then you can't use su this way.

But using socat, you can simulate a tty for any program and provide the input from STDIN, a socket, a file, whatever...

Here is how you would run it:

user@host$ (sleep 1; echo SuperSecr3t) | socat - EXEC:'su -c id',pty,ctty,setsid
Password: ### No input here, just wait 1sec
uid=0(root) gid=0(root) groups=0(root)

Taking this further, now imagine that you have a non-interactive shell access as a standard user (user1). On this system, there is another user (user2) who can run commands as root using sudo, but user1 can't. You happen to know the password to the user2 account. What you want to do is switch to user2 via su, then run a command as root using sudo from the user2 account.

Here is how to proceed:

user1@host$ echo -e '#!/bin/sh\necho User2SuperPasswd | sudo -S id' > runasroot.sh
user1@host$ chmod +x runasroot.sh
user1@host$ (sleep 1; echo User2SuperPasswd) | socat - EXEC:'su user2 -c ./runasroot.sh',pty,ctty,setsid
Password: ### No input here, just wait 1 sec
[sudo] password for user2: uid=0(root) gid=0(root) groups=0(root)

Thursday, March 5, 2015

How-To: Rdesktop over (HTTP) Proxy

How to connect to a remote desktop host via an HTTP Proxy

In this example we will use, once again, socat. Here is how to connect to a Terminal Server which can be reach only behind an HTTP Proxy.

First, make sure that your $http_proxy environment variable is set properly.

Add the following function to your ~/.bashrc:

function rdesktop_proxy () {
 
 if [ $# -lt 1 ]; then
  echo "usage: $0 <hostname/ip>"
  return
 fi

 HOST=$1
 PROXY_HOST=$(echo $http_proxy | sed 's,http:,,;s,/,,g' | cut -d: -f1)
 PROXY_PORT=$(echo $http_proxy | sed 's,http:,,;s,/,,g' | cut -d: -f2)

 socat TCP4-LISTEN:51515,bind=127.0.0.1,reuseaddr PROXY:$PROXY_HOST:$HOST:3389,proxyport=$PROXY_PORT &

 /usr/local/bin/xfreerdp +clipboard +home-drive "/t:$1" /v:127.0.0.1:51515 "${@:2}"
}

Then re-source your shell:

source ~/.bashrc

And you can just type:

rdesktop_proxy my.rdpdomain.com /u:John

The example above use the xfreerdp client, but you can adjust it to use your favourite RDP client, you get the idea.

Thursday, February 5, 2015

Compile a headless FreeRDP for credential checking

Lately, I needed to have a command-line tool that was able to check for the validity of RDP credentials from a host with no X Server installed. The goal was to have a webapp that allows to check for the validity of credentials. For SMB-only, I could have used winexe, but even if Windows creds are valid, an RDP session may fail because the user isn't in the correct group, or lacks permissions, etc.

Compiling xfreerdp for this usage is a bit tricky because we want to have a version that loads the least possible libraries in order to have a binary that is as much portable as we can. Also, we don't need to include any rendering / audio libraries at all. We just want to check for credentials.

This tutorials explains how to compile it to be run on a server with no X Server installed, and to avoid the need to install / copy over additional dependencies.

It should be able to run on a 32 or 64 bit ubuntu server without additional configuration. However some system libraries such as LibSSL, must have the same version than the one that was used to compile it.

The version compiled at the time of writing is this commit. The version of cmake used is 2.8 (version >= 3 can cause some issues).

It is highly recommended to perform the following on a development VM and then copy the binary over, rather than on a production server.

The VM used for this writing is Ubuntu Server 14.04 LTS (Trusty) x64.

Compiling


1. Install and update the OS if needed.

2. Install the required dependencies

sudo apt-get install unzip pkg-config build-essential git-core cmake libssl-dev libx11-dev libxext-dev libxinerama-dev libxcursor-dev libxdamage-dev libxv-dev libxkbfile-dev libasound2-dev libcups2-dev libxml2 libxml2-dev libxrandr-dev libgstreamer0.10-dev libgstreamer-plugins-base0.10-dev libavutil-dev libavcodec-dev

3. Download the sources:

cd ~
wget https://github.com/FreeRDP/FreeRDP/archive/master.zip

4. Extract and compile. Here using CMAKE we generate the Makefiles according to the options we specify. In our case, we don't need any rendering or audio libraries etc, so we disable everything we can.
For an explanation of each parameter, run "cmake -L" inside the directory containing the sources.

unzip master.zip
cd FreeRDP-master
cmake -DMONOLITHIC_BUILD=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release \
-DWITH_SSE2=OFF -DWITH_ALSA=OFF -DWITH_FFMPEG=OFF -DWITH_MANPAGES=OFF \
-DWITH_SERVER_INTERFACE=OFF -DWITH-PULSE=OFF -DWITH_GSTREAMER_1_0=OFF \
-DWITH_XKBFILE=OFF -DWITH_XINERAMA=OFF -DWITH_XEXT=OFF -DWITH_XCURSOR=OFF \
-DWITH_XV=OFF -DWITH_XI=OFF -DWITH_XRENDER=OFF -DWITH_XFIXES=OFF .
make
make install

5. Link the libraries and update the cache:

echo /usr/local/lib/freerdp > /etc/ld.so.conf.d/freerdp.conf
ldconfig

6. The binary should have been created in ~/FreeRDP-master/client/X11. You can see how many libraries it loads with the following command (With the defaut cmake options, it would need more than 60):

$ ldd `which xfreerdp` | wc -l
13

Modify relevant parts of the code


We want to use the "+auth-only" parameter to instruct xfreerdp to not connect to the X Server and just check for the credentials. But for some reason, it still wants to connect to it and so it fails when there is none.

We must modify the source code of the following file:

~/FreeRDP-master/client/X11/xf_client.c

What we want to do is to "Return true" without even checking for a X Server. Look for the function called:

BOOL xf_pre_connect(freerdp* instance)

We must comment out or remove some blocks inside this function. For simplicty replace the whole function with the following code:

OL xf_pre_connect(freerdp* instance)
{
        rdpChannels* channels;
        rdpSettings* settings;
        xfContext* xfc = (xfContext*) instance->context;

        xfc->codecs = instance->context->codecs;
        xfc->settings = instance->settings;
        xfc->instance = instance;

        settings = instance->settings;
        channels = instance->context->channels;

        settings->OsMajorType = OSMAJORTYPE_UNIX;
        settings->OsMinorType = OSMINORTYPE_NATIVE_XSERVER;

        ZeroMemory(settings->OrderSupport, 32);
        settings->OrderSupport[NEG_DSTBLT_INDEX] = TRUE;
        settings->OrderSupport[NEG_PATBLT_INDEX] = TRUE;
        settings->OrderSupport[NEG_SCRBLT_INDEX] = TRUE;
        settings->OrderSupport[NEG_OPAQUE_RECT_INDEX] = TRUE;
        settings->OrderSupport[NEG_DRAWNINEGRID_INDEX] = FALSE;
        settings->OrderSupport[NEG_MULTIDSTBLT_INDEX] = FALSE;
        settings->OrderSupport[NEG_MULTIPATBLT_INDEX] = FALSE;
        settings->OrderSupport[NEG_MULTISCRBLT_INDEX] = FALSE;
        settings->OrderSupport[NEG_MULTIOPAQUERECT_INDEX] = TRUE;
        settings->OrderSupport[NEG_MULTI_DRAWNINEGRID_INDEX] = FALSE;
        settings->OrderSupport[NEG_LINETO_INDEX] = TRUE;
        settings->OrderSupport[NEG_POLYLINE_INDEX] = TRUE;
        settings->OrderSupport[NEG_MEMBLT_INDEX] = settings->BitmapCacheEnabled;
        settings->OrderSupport[NEG_MEM3BLT_INDEX] = (settings->SoftwareGdi) ? TRUE : FALSE;
        settings->OrderSupport[NEG_MEMBLT_V2_INDEX] = settings->BitmapCacheEnabled;
        settings->OrderSupport[NEG_MEM3BLT_V2_INDEX] = FALSE;
        settings->OrderSupport[NEG_SAVEBITMAP_INDEX] = FALSE;
        settings->OrderSupport[NEG_GLYPH_INDEX_INDEX] = TRUE;
        settings->OrderSupport[NEG_FAST_INDEX_INDEX] = TRUE;
        settings->OrderSupport[NEG_FAST_GLYPH_INDEX] = TRUE;
        settings->OrderSupport[NEG_POLYGON_SC_INDEX] = (settings->SoftwareGdi) ? FALSE : TRUE;
        settings->OrderSupport[NEG_POLYGON_CB_INDEX] = (settings->SoftwareGdi) ? FALSE : TRUE;
        settings->OrderSupport[NEG_ELLIPSE_SC_INDEX] = FALSE;
        settings->OrderSupport[NEG_ELLIPSE_CB_INDEX] = FALSE;
        
        if (!settings->Username)
        {
                char *login_name = getlogin();
                if (login_name)
                {
                        settings->Username = _strdup(login_name);
                        WLog_INFO(TAG, "No user name set. - Using login name: %s", settings->Username);
                }
        }

        if (settings->AuthenticationOnly)
        {
                /* Check +auth-only has a username and password. */
                if (!settings->Password)
                {
                        WLog_INFO(TAG, "auth-only, but no password set. Please provide one.");
                        return FALSE;
                }

                WLog_INFO(TAG, "Authentication only. Don't connect to X.");
        }
        
        return TRUE;
}

Optionally, we can also remove the code that creates the certificates in the user's home directory as we don't want this. Open the following file:

~/FreeRDP-master/libfreerdp/crypto/certificate.c

The first function at the top of the file should be:

int certificate_store_init(rdpCertificateStore* certificate_store)

Simply remove or comment all the code inside this function except the final "return 1;".
Now we can recompile xfreerdp.
cd ~/FreeRDP-master
make
./client/X11/xfreerdp --help

At this point we have a usable, almost-portable, headless version of xfreerdp that we can copy over to another server.

Check for credentials


I have been able to see three different outputs (there might be more):

1. When authentication succeeds

root@ubuntu-server:~/FreeRDP-master# ./client/X11/xfreerdp /cert-ignore +auth-only /v:10.0.2.2:4242 /u:testuser /d:Spoon /p:pass
[11:14:05:745] [1385:-1230230672] [INFO][com.freerdp.client.x11] - Authentication only. Don't connect to X.
[11:14:06:834] [1385:-1230230672] [ERROR][com.freerdp.core] - Authentication only, exit status 0

2. When the password is incorrect, account is locked out, disabled, or expired:

root@ubuntu-server:~/FreeRDP-master# ./client/X11/xfreerdp /cert-ignore +auth-only /v:10.0.2.2:4242 /u:testuser /d:Spoon /p:WRONG_PASS
[11:14:13:130] [1387:-1229997200] [INFO][com.freerdp.client.x11] - Authentication only. Don't connect to X.
[11:14:13:141] [1387:-1229997200] [ERROR][com.freerdp.core] - credssp_recv() error: -1
[11:14:13:141] [1387:-1229997200] [ERROR][com.freerdp.core] - freerdp_set_last_error 0x20009
[11:14:13:141] [1387:-1229997200] [ERROR][com.freerdp.core.transport] - Authentication failure, check credentials.If credentials are valid, the NTLMSSP implementation may be to blame.
[11:14:13:141] [1387:-1229997200] [ERROR][com.freerdp.core.connection] - Error: protocol security negotiation or connection failure
[11:14:13:141] [1387:-1229997200] [ERROR][com.freerdp.core] - Authentication only, exit status 1

3. When credentials are correct but the user is not in the correct group, i.e. "Remote Desktop Users":

root@ubuntu-server:~/FreeRDP-master# ./client/X11/xfreerdp /cert-ignore +auth-only /v:10.0.2.2:4242 /u:testuser /d:Spoon /p:pass
[11:11:28:747] [1377:-1230374032] [INFO][com.freerdp.client.x11] - Authentication only. Don't connect to X.
[11:11:29:811] [1377:-1230374032] [ERROR][com.freerdp.core] - ERRINFO_SERVER_INSUFFICIENT_PRIVILEGES (0x00000009):The user cannot connect to the server due to insufficient access privileges.
[11:11:29:813] [1377:-1230374032] [ERROR][com.freerdp.core.rdp] - DisconnectProviderUltimatum: reason: 1
[11:11:29:813] [1377:-1230374032] [ERROR][com.freerdp.core] - Authentication only, exit status 1

Thursday, January 22, 2015

Intercept all HTTP + SSL Android traffic and bypass SSL Pinning

How to intercept all Android HTTP / HTTPS network traffic on Windows and bypass SSL Pinning


  1.  Install ADB / Android SDK or use the AppUse VM
  2. Root the android device
  3. Install Android Cydia Substrate
  4. adb install com.saurik.substrate.apk
  5. Install Android SSL Trust Killer
  6. adb install Android-SSL-TrustKiller.apk
  7. Export Burp Root CA Certificate
  8. Push Burp Cert to the sdcard
  9. adb push PortSwiggerCA.cer /sdcard
  10. Install Burp Cert in the Android Trust Store
  11. Settings > Security > Install from device storage
  12. On Windows, create a Wireless hotspot sharing your Internet / external connection
    1. Create the hotspot:
    2. ​netsh wlan set hostednetwork mode=allow ssid=MyHotspot key=MyPassword keyUsage=persistent
    3. To start the hotspot
    4. netsh wlan start hostednetwork
    5. Or to stop the hotspot:
    6. netsh wlan stop hostednetwork
  13. Enabled Internet Connection Sharing with your external connection:
  14. Right click your connection's NIC, "Sharing" tab, check the box, select "MyHotspot". The external NIC icon should say "shared".
  15. Connect the Android to the wifi Hotspot using the key configured previously.
  16. Optional: If you prefer to use a static network configuration as opposed to DHCP, go to the Wifi connection advanced settings and look for the IP address attributed. Switch to a static IP and set this IP manually. The gateway should be the IP address of the Windows "MyHotspot" interface. The DNS Server should be your ISP's / corporate network one. Reconnect the Wifi with the new network configuration.
  17. Try to ping the Android device's IP address from the Windows.
  18. Run Burp and make it listen on the Hotspot's interface IP address.
  19. You can configure this proxy in the Wireless connection advanced settings, but that would take effect only for proxy-aware apps such as the web browser. Preferably, and since your device is rooted, use an app such as ProxyDroid to make all the apps go through the proxy transparently. You should have Play Store working as well.
  20. Configure your Burp's upstream proxies rules if needed.
  21. You should be able to intercept all HTTP/HTTPS traffic. If not, well, go back to step 1.

Thursday, January 8, 2015

Setup a Bittorrent download/seed box on Android

I used to run XMBC (now named Kodi) on a Raspberry Pi, which worked great, but it lacked a bit a power. Also, the Linux versions of Kodi are not usually updated as much as the Windows or Android versions.

Definitely being an Android person, I decided to get myself a nice Android TV box for christmas. After having rooted it, installed all the media-center stuff and connected a nice big external USB hard drive for media storage, came the part of looking for a way to install a Bittorrent client.

As it turns out there are quite a lot of choices from the Google Play Store. But nothing matched what I needed:
  • A bittorrent client that runs as a daemon all the time ;
  • Must support scheduling to download only at night ;
  • Must have a directory watching feature ;
  • Must be manageable remotely via Web UI.

I tried different ones with no luck. After some research I came across an acceptable solution: Installing a bootstrapped version of Ubuntu Precise on the top of the Android OS. There is an elegant solution with video tutorials for that here.

The installation is pretty straightforward, you should be done in less than 15 minutes. Just watch the video tutorials first.

I chose a 2GB disk image with a Precise installation. When it finishes installing the base packages, type the following commands from your Android prompt (You can use ConnectBot or Terminal Emulator for this).

- Jump into the Ubuntu chrooted environment:
deb

- Update the packages list and upgrade them to the latest version
apt-get update -y && apt-get upgrade -y

- Install Andromize (A package designed to furthermore adapt your installation to the Android environment)
apt-get install andromize

- Clean the APT cache
apt-get clean

- Create a new user
adduser jeremy

- Create a password
passwd jeremy

- Add the user to the sudo group
adduser jeremy sudo

- Install SSH Server
apt-get install openssh-server

You may optionally want to change the SSH listen port in /etc/ssh/sshd_config.

At this point your base system is set up. You can logout your Ubuntu shell to be dropped back on the Android shell and see the options to the "deb" command with "deb h":

root@NEO-X8H-PLUS:/sdcard # deb h
Script to integrate Debian binaries on an Android phone

Without options: start a root bash shell
bootdeb ?: help, display this help text
bootdeb u: umount, remove symlinks and unmount Debian disk
bootdeb k: kill, kill (-KILL) programs, then unmount Debian disk
bootdeb r: reboot, mount Debian readonly and reboot (last resort)
bootdeb c: clean, clean symlinks to Android root from Debian disk
bootdeb s: sshd, start the openssh server
bootdeb S: sshd-stop, stop the openssh server
bootdeb x: xrdp, start the xrdp server
bootdeb X: xrdp-stop, stop the xrdp server

To umount the Ubuntu image, use "deb u". For now, you can just run the SSH server using "deb s" and then connect to it, either locally with ConnectBot or remotely with any SSH client.

Now for the Bittorrent installation part. I chose the Deluge client as it as activiely maintained and developed, and it matches all the criteria I needed.

- Install the following package to get "add-apt-repository" on your Ubuntu installation
sudo apt-get install python-software-properties

Note: In some situations, you may need to install the package "software-properties-common" instead.

- Add the Deluge PPA to your installation, and install the Deluge daemon and WebUI Server (refer to this page for more details):
sudo add-apt-repository ppa:deluge-team/ppa
sudo apt-get update
sudo apt-get install deluged deluge-web

Run the daemon and the WebUI Server:
deluged
deluge-web &

All done! you should now be able to point your browser to http://android.ip.address:8112/. The default password to the WebUI is "deluge". Then take some time to adjust the configuration such as the download paths, bandwidth limits and schedules.

For a more seamless experience, you can make Kodi periodically scan your download folder to have movies added to the library automatically!

Note: When you run certain commands from within your Linux installation, you may see errors such as "passwd: u:r:init:s0 is not authorized to change the password of [...]". In this case, you need to temporarily disable SELinux back on the Android shell by using the command below:
setenforce 0

Friday, August 1, 2014

XOR a string or file with a key in Python

Here is an elegant example about how to XOR a string using a key with Python's itertools cycle:

>>> from itertools import cycle
>>> 
>>> def do_xor(key, str):
...     str = str.replace(' ', '').decode('hex')
...     key = ''.join(key.split()[::-1]).decode('hex')
...     
...     return ''.join([chr(ord(a) ^ ord(b)) for a,b in zip(str, cycle(key))])
... 
>>> message = "8E D8 51 66 8B D9 03 67 8D FE 0A 3E E1 97 15 13"
>>> key = "13 37 ba be"
>>> 
>>> print do_xor(key, message)
0bfu5c4t3D=-_-"
>>>

If your string isn't in a hexadecimal representation, just remove the "decode('hex')" bits.

Following up on the example above, here is a script that allows quick and easy file encryption. Just chose a key that you will remember and this script will help easily protecting sensitive information on disk:

import os, sys
from itertools import cycle

if len(sys.argv) != 3:
 print "usage: %s <filename> <key>" % sys.argv[0]
 sys.exit()

if os.path.exists(sys.argv[1]):
 data = open(sys.argv[1]).read()
 xored = [chr(ord(a) ^ ord(b)) for a,b in zip(data, cycle(sys.argv[2]))]
 
 open(sys.argv[1], 'w').write(''.join(xored))

 print "file xored"
 
else:
 print "%s: file not found" % sys.argv[1]

Example usage:

user@host:~$ cat /tmp/a
this is a simple text file.
user@host:~$ python xorfile.py /tmp/a Sup3rS3cr3t
file xored
user@host:~$ cat /tmp/a
<... some unprintable characters ...>
user@host:~$ python xorfile.py /tmp/a Sup3rS3cr3t
file xored
user@host:~$ cat /tmp/a
this is a simple text file.
user@host:~$