OCRing a scanned book

I had the pleasure to use a “Bookeye” book scanner. It’s a huge device which helps scanning things like books or folders. It’s very quick and very easy to use. I got a huge PDF out of my good 100 pages that I’ve scanned.

Unfortunately the light was very bright and so the scanner scanned “through” the open pages revealing the back sides of the pages. That’s not very cool and I couldn’t really dim the light or put a sheet between the Pages.
Also, it doesn’t do OCR but my main point of digitalising this book was to actually have it searchable and copy&pastable.

There seem to be multiple options to do OCR on images:

tesseract

covered already

ocropus

Apparently this is supposed to be tesseract on steroids as it can recognise text on paper and different layouts and everything.
Since it’s a bit painful to compile, I’d love to share my experiences hoping that it will become useful to somebody.

During compilation of ocropus, you might run into issues like this or that, so be prepared to patch the code.


cd /tmp/
svn checkout http://iulib.googlecode.com/svn/trunk/ iulib
cd iulib/
./configure --prefix=/tmp/libiu-install
make && make install


cd /tmp/
wget http://www.leptonica.com/source/leptonlib-1.67.tar.gz -O- | tar xvzf -
cd leptonlib*/
./configure --prefix=/tmp/leptonica
make && make install


cd /tmp/
svn checkout http://ocropus.googlecode.com/svn/trunk/ ocropus
# This is due to this bug: http://code.google.com/p/ocropus/issues/detail?id=283
cat > ~/bin/leptheaders <
#!/bin/sh
echo /tmp/leptonica/include/leptonica/
EOF
chmod a+x ~/bin/leptheaders
./configure --prefix=/tmp/ocropus-install --with-iulib=/tmp/libiu-install/
make && make install

muelli@bigbox /tmp $ LD_LIBRARY_PATH=/tmp/ocropus-install/lib/:/tmp/leptonica/lib/ ./ocropus-install/bin/ocroscript --help
usage: ./ocropus-install/bin/ocroscript [options] [script [args]].
Available options are:
  -e stat  execute string 'stat'
  -l name  require library 'name'
  -i       enter interactive mode after executing 'script'
  -v       show version information
  --       stop handling options
  -        execute stdin and stop handling options
muelli@bigbox /tmp $

However, I can’t do anything because I can’t make LUA load the scripts from the share/ directory of the prefix. Too sad. It looked very promising.

Cuneiform

This is an interesting thing. It’s a BSD licensed russian OCR software that was once one the leading tools to do OCR.
Interestingly, it’s the most straight forward thing to install, compared to the other things listed here.

bzr branch lp:cuneiform-linux
cd cuneiform-linux/
mkdir build
cd build/
cmake .. -DCMAKE_INSTALL_PREFIX=/tmp/cuneiform
make
make install

This is supposed to produce some sort of HTML which we can glue to a PDF with the following tool.

hocr2pdf

Apparently takes “HTML annotated OCR data” and bundles that, together with the image, to a PDF.


cd /tmp/
svn co http://svn.exactcode.de/exact-image/trunk ei
cd ei/
./configure --prefix=/tmp/exactimage
make && make install

That, however, failed for me like this:

  LINK EXEC objdir/frontends/optimize2bw
/usr/bin/ld: objdir/codecs/lib.a: undefined reference to symbol 'QuantizeBuffer'
/usr/bin/ld: note: 'QuantizeBuffer' is defined in DSO /usr/lib64/libgif.so.4 so try adding it to the linker command line
/usr/lib64/libgif.so.4: could not read symbols: Invalid operation
collect2: ld returned 1 exit status
make: *** [objdir/frontends/optimize2bw] Error 1

Adding “LDFLAGS += -lgif” to the Makefile fixes that. I couldn’t find a bug tracker, hence I reported this issue via email but haven’t heard back yet.

Although the hOCR format seems to be the only option to actually know where in the file the text appears, no OCR program, except cuneiform and tesseract with a patch, seems to support it 🙁

gscan2pdf

as a full suite it can import pictures or PDFs and use a OCR program mentioned above (tesseract or gocr). The whole thing can then be saved as a PDF again.
Results with gocr are not so good. I can’t really copy and paste stuff. Searching does kinda work though.

Using Tesseract, however, doesn’t work quite well:

 Tesseract Open Source OCR Engine
tesseract: unicharset.cpp:76: const UNICHAR_ID UNICHARSET::unichar_to_id(const char*, int) const: Assertion `ids.contains(unichar_repr, length)' failed.
sh: line 1:  6187 Aborted                 (core dumped) tesseract /tmp/4jZN0oNbB1/dLNBLkcjph.tif /tmp/4jZN0oNbB1/_4BdZMfGXJ -l fra
*** unhandled exception in callback:
***   Error: cannot open /tmp/4jZN0oNbB1/_4BdZMfGXJ.txt
***  ignoring at /usr/bin/gscan2pdf line 12513.
Tesseract Open Source OCR Engine
tesseract: unicharset.cpp:76: const UNICHAR_ID UNICHARSET::unichar_to_id(const char*, int) const: Assertion `ids.contains(unichar_repr, length)' failed.
sh: line 1:  6193 Aborted                 (core dumped) tesseract /tmp/4jZN0oNbB1/ELMbnDkaEI.tif /tmp/4jZN0oNbB1/C47fuqxX3S -l fra
*** unhandled exception in callback:
***   Error: cannot open /tmp/4jZN0oNbB1/C47fuqxX3S.txt
***  ignoring at /usr/bin/gscan2pdf line 12513.

It doesn’t seems to be able to work with cuneiform 🙁

Archivista Box

This is actually an appliance and you can download an ISO image.
Running it is straight forward:

cd /tmp/
wget 'http://downloads.sourceforge.net/project/archivista/archivista/ArchivistaBox_2010_IV/archivista_20101218.iso?r=http%3A%2F%2Fsourceforge.net%2Fprojects%2Farchivista%2F&ts=1295436241&use_mirror=ovh'
qemu -cdrom /tmp/archivista_20101218.iso -m 786M -usb

Funnily enough, the image won’t boot with more than 786MB of RAM. Quite weird, but qemu just reports the CPU to be halted after a while. If it does work, it boots up a firefox with a nice WebUI which seems to be quite functional. However, I can’t upload my >100MB PDF probably because it’s a web based thing and either the server rejects big uploads or the CGI just times out or a mixture of both.

Trying to root this thing is more complex than usual. Apparently you can’t give “init=/bin/sh” as a boot parameter as it wouldn’t make a difference. So I tried to have a look at the ISO image. There is fuseiso to mount ISO images in userspace. Unfortunately, CDEmu doesn’t seem to be packaged for Fedora. Not surprisingly, there was a SquashFS on that ISO9660 filesystem. Unfortunately, I didn’t find any SquashFS FUSE implementation 🙁 But even with elevated privileges, I can’t mount that thing *sigh*:

$ file ~/empty/live.squash
/home/muelli/empty/live.squash: Squashfs filesystem, little endian, version 3.0, 685979128 bytes, 98267 inodes, blocksize: 65536 bytes, created: Sat Dec 18 06:54:54 2010
$ sudo mount ~/empty/live.squash /tmp/empty/
mount: wrong fs type, bad option, bad superblock on /dev/loop1,
       missing codepage or helper program, or other error
       In some cases useful info is found in syslog - try
       dmesg | tail  or so
$ dmesg | tail -n 2
[342853.796364] squashfs: version 4.0 (2009/01/31) Phillip Lougher
[342853.796726] SQUASHFS error: Major/Minor mismatch, older Squashfs 3.0 filesystems are unsupported

But unsquashfs helped to extract the whole thing onto my disk. They used “T2” to bundle everything to a CD and packaged software mentioned above. Unfortunately, very old versions were used, i.e. cuneiform is in version 0.4.0 as opposed to 1.0.0. Hence, I don’t really consider it to be very useful to poke around that thing.

It’s a huge thing worth exploring though. It all seems to come from this SVN repository: svn://svn.archivista.ch/home/data/archivista/svn.

WatchOCR

For some reason, they built an ISO image as well. Probably to run an appliance.

cd /tmp/
wget http://www.watchocr.com/files/watchocr-V0.6-2010-12-10-en.iso
qemu -cdrom /tmp/watchocr-V0.6-2010-12-10-en.iso -m 1G

The image booted up a webbrowser which showed a webinterface to the WebOCR functionality.
I extraced the necessary scripts which wraps tools like cuniform, ghostscript and friends. Compared to the archivista box, the scripts here are rather simple. Please find webocr and img2pdf. They also use an old cuneiform 0.8.0 which is older than the version from Launchpad.

However, in my QEMU instance, the watchocr box took a very long time to process my good 100 pages PDF.

Some custom script

That tries to do the job did in fact quite well, although it’s quite slow as well. It lacks proper support for spawning multiple commands in parallel.

After you have installed the dependencies like mentioned above, you can run it:

wget http://www.konradvoelkel.de/download/pdfocr.sh
PATH="/tmp/exactimage/bin/:/tmp/cuneiform/bin/:$PATH" LD_LIBRARY_PATH=/tmp/cuneiform/lib64/ sh -x pdfocr.sh buch-test-1.pdf 0 0 0 0 2500 2000 fra SomeAuthor SomeTitle

The script, however, doesn’t really work for me, probably because of some quoting issues:

+ pdfjoin --fitpaper --tidy --outfile ../buch-test-1.pdf.ocr1.pdf 'pg_*.png.pdf'
          ----
  pdfjam: This is pdfjam version 2.08.
  pdfjam: Reading any site-wide or user-specific defaults...
          (none found)
  pdfjam ERROR: pg_*.png.pdf not found

Having overcome that problem, the following pdfjoin doesn’t work for an unknown reason. After having replaced pdfjoin manually, I realised, that the script sampled the pages down, made them monochrome and rotated them! Hence, no OCR was possible and the final PDF was totally unusable *sigh*.

It’s a mess.

To conclude…

I still don’t have a properly OCRd version of my scanned book, because of not very well integrated tools. I believe that programs like pdftk, imagemagick, unpaper, cuneiform, hocr2pdf, pdfjam do their job very well. But it appears that they are not very well knit together to form a useful tools to OCR a given PDF. Requirements would be, for example, that there is no loss of quality of the scanned images, that the number of programs to be called is reduced to a minimum and that everything needs to be able to do batch processing. So far, I couldn’t find anything that fulfills that requirements. If you know anything or have a few moments to bundle the necessary tools together, please tell me :o) The necessary pieces are all there, as far as I can see. It just needs someone to integrate everything nicely.

FOSS.in last edition 2010

I had the pleasure to be invited to FOSS.in 2010. As I was there to represent parts of GNOME I feel obliged to report what actually happened.

The first day was really interesting. It was very nice to see that many people having a real interest in Free Software. It was mostly students that I have talked to and they said that Free Software was by far not an issue at colleges in India.

Many people queued up to register for the conference. That’s very good to see. Apparently, around 500 people showed up to share the Free Software love. the usual delays in the conference setup were there as expected 😉 So the opening ceremony started quite late and started, as usual, with lighting the lamp.

Danese from the Wikimedia Foundation started the conference with her keynote on the technical aspects of Wikipedia.

She showed that there is a lot of potential for Wikipedia in India, because so far, there was a technical language barrier in Wikipedia’s software. Also, companies like Microsoft have spent loads of time and money on wiping out a free (software) culture, hence not so many Indians got the idea of free software or free content and were simply not aware of the free availability of Wikipedia.

According to Danese, Wikipedia is the Top 5 website after companies like Google or Facebook. And compared to the other top websites, the Wikimedia Foundation has by far the least employees. It’s around 50, compared to the multiple tens of thousands of employees that the other companies employ. She also described the openness of Wikipedia in almost every aspect. Even the NOC is quite open to the outside world, you can supposedly see the network status. Also, all the documentation is on the web about all the internal process so that you could learn a lot about the Foundation a lot if you wanted to.

She presented us several methods and technologies which help them to scale the way the Wikipedia does, as well as some very nerdy details like the Squid proxy setup or customisations they made to MySQL. They are also working on offline delivery methods because many people on the world do not have continuous internet access which makes browsing the web pretty hard.

After lunch break, Bablir Singh told us about caching in virtualised environments. He introduced into a range of problems that come with virtualisation. For example the lack of memory and that all the assumption of caches that Linux makes were broken when virtualising.
Basically the problem was that if a Linux guest runs on a Linux host, both of them would cache, say, the hard disk. This is, of course, not necessary and he proposed two strategies to mitigate that problem. One of them was to use a memory balloon driver and give the kernel a hint that the for the caching allocated pages should be wiped earlier.

Lenny then talked about systemd and claimed that it was Socket Based Activation that made it so damn fast. It was inspired by Apples launchd and performs quite well.

Afterwards, I have been to the Meego room where they gave away t-shirts and Rubix-cubes. I was told a technique on how to solve the Rubix-cube and I tried to do it. I wasn’t too successful though but it’s still very interesting. I can’t recite the methods and ways to solve the cube but there are tutorials on the internet.

Rahul talked about failures he seen in Fedora. He claimed that Fedora was the first project to adopt a six month release cycle. He questioned whether six month is actually a good time frame. Also the governance modalities were questioned. The veto right in the Fedora Board was prone to misuse. Early websites were ugly and not very inviting. By now, the website is more appealing and should invite the audience to contribute. MoinMoin was accused of not being as good MediaWiki, simply because Wikipedia uses MediaWiki. Not a very good reasoning in my opinion.

I was invited to do a talk about Security and Mobile Devices (again). I had a very interested audience which pulled off an interesting Q&A Session. People still come with questions and ideas. I just love that. You can find the slides here.

As we are on mobile security, I wrote a tiny program for my N900 to sidejack Twitter accounts. It’s a bit like firesheep, but does Twitter only (for now) and it actually posts a nice message. But I’ve also been pnwed… 😉

But more on that in a separate post.


Unfortunately, the FOSS.in team announced, that this will be the last FOSS.in they organise. That’s very sad because it was a lot of fun with a very interesting set of people. They claim that they are burnt out and that if one person is missing, nothing will work, because everyone knew exactly what role to take and what to do. I don’t really like this reasoning, because it reveals that the Busfactor is extremely low. This, however, should be one of the main concerns when doing community work. Hence, the team is to blame for having taken care of increasing the Busfactor and thus leading FOSS.in to a dead end. Very sad. But thanks anyway for the last FOSS.in. I am very proud of having attended it.

jOEpardy released as Free Software

As mentioned in an earlier post, I was investigating the possibility to set jOEpardy free. It’s a Java program that let’s you hold a Jeopardy session based on a XML file. It has been used quite a few times and is pretty stable. A boatload of credits go to Triphoenix, who coded an awful lot without very much time, probably lacking sleep or coffee or even both. Thanks.

So to make the announcement: jOEpardy is GPLv3+ software (*yay*) and you can download the code via Mercurial here: https://hg.cryptobitch.de/joepardy. I don’t intend to make tarball or binary releases as I (at your option) either don’t have the time or simply don’t see a need.

But to actually use it, you want to have some buzzers. You could play it with a regular keyboard though. At the end of the day, you need to generate a keycodes for a “1”, a “2”, a “3” or a “4”. If you’re nerdy enough, you can get yourself an emergency button in the next hardware store and solder some tiny serial logic to it. Then you could read that serial signal and convert to X events via xtest.

You’ll figure smth out 😉

The beauty of a free (Maemo) handset

During GUADEC, I of course wanted to use my N900. But since the PR1.2 update, the Jabber client wouldn’t connect to the server anymore, because OpenSSL doesn’t honor imported CAs. So the only option to make it connect is to ignore SSL errors. But as I’m naturally paranoid, I didn’t dare to connect… It’s a nerdy conference with a lot of hackers after all.

Fortunately, I had all those nice Collaborans next to me and I could ask loads of (stupid?) questions. Turns out, that the Jabber client (telepathy-gabble) on the N900 is a bit old and uses loudmouth and not wocky.

So I brought my SDK back to life (jeez, it’s very inconvenient to do stuff with that scratchbox setup 🙁 ) and I was surprised that apt-get source libloudmouth1-0 was sufficient to get the code. And apt-get build-dep libloudmouth1-0 && dpkg-buildpackage -rfakeroot built the package. Almost easy (I had to fix loads of dependency issue but it then worked out).

As neither I nor the Collaborans knew how to integrate with the Certificate Manager, I just wanted to make OpenSSL aware of the root CA which I intended to drop somewhere in ~/.certs or so.

After a couple of busy conference days I found out that code which implements the desired functionality already exists but was commented out. So I adapted that and now loudmouth imports certificates from /home/user/.config/telepathy/trusted-cas.pem or /home/user/.config/telepathy/certs /home/user/.maemosec-certs/ssl-ca before it connects. The former is just a file with all root CAs being PEM encoded. The latter is a directory where you have to put PEM or DER encoded certs into and then run c_rehash . in it the certificate manager puts the certificates in after you’ve imported it. Because just loading any .pem or .der file would have been to easy to work with. It was hard for me to understand OpenSSL’s API. This article helped me a bit though, so you might find it useful, too.

So if you want your jabber client on the N900 to connect to a SSL/TLS secured server that uses a root CA that is not in the built in certificate store, grab the .deb here. You can, of course, get the source as well.

Turns out, that there is a workaround mentioned in bug 9355 hence you might consider it to be easier to modify system files yourself instead of letting the package manager do it.

Bottom line being that it’s wonderful to be allowed to study the code. It’s wonderful to be allowed fix stuff. And it’s wonderful to be allowed to redistribute the software. Even with my own modifications. And that it will be that way for the lifetime of that piece of software. I do love Free Software.

Got a N900 *yay*

A while back, during FOSS.in, I participated at a Maemo “hacking” contents. The goal was to produce something valuable for Maemo and get a N900 in return. I basically ported Gajim to the N900 and, drumroll, I won! *yay*

Unfortunately, it took them a while to ship that thing so that I received it half a year later or so. But then it was amazingly fast. I received a parcel from Helsinki (2031km far away) which was sent 20hrs earlier. The parcel thus was traveling at ~100km/h. Great service, DHL! Thanks a million Nokia, Thanks Maemo Bangalore!

I really like the N900 because it’s a Linux based device. Well, there is Android, right? But Nokia actually does send it’s patches upstream and they invite you to get root on the device you own. Plus everything is pretty much standard. There is D-Bus, there GTK+, there is Python, there is Linux, … Hence, building and running stuff is pretty easy. I am looking forward to run my DNS Tunnel and DOOM and play around with the USB.

I am now busy playing with my new N900.

Klingon Language Support

From Documentation/unicode.txt:

Klingon language support
————————

In 1996, Linux was the first operating system in the world to add support for the artificial language Klingon, created by Marc Okrand for the “Star Trek” television series.  This encoding was later adopted by the ConScript Unicode Registry and proposed (but ultimately rejected) for inclusion in Unicode Plane 1.  Thus, it remains as a Linux/CSUR private assignment in the Linux Zone.

This encoding has been endorsed by the Klingon Language Institute. For more information, contact them at:

http://www.kli.org/

Maybe Linux isn’t ready to take over the world yet, but at least it’s ready to take over the universe…

Skipfish versus WebGoat

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

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 written for Windows and they hardcode the path of 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

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

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 😉

Creative Commons Attribution-ShareAlike 3.0 Unported
This work by Muelli is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported.