Practicum Status Update Week 10

  • As mentioned in the last report, I skipped one week in favour of the GUADEC.
  • I had a funny C problem. Consider the following two functions:
     
    static int
    safe_read (void *data, size_t length, FILE* file)
    {
    	int status = fread(data, length, 1, file);
     
    	if (status == -1) error_report("%s: read packet (%lu) data on stream %p "
    								   "failed (%d): %s",
    								   __FUNCTION__, length, file,
    								   status, strerror(errno));
    	status = fflush(file);
    	return status;
    }
     
    static int
    safe_write (void *data, size_t length, FILE* file)
    {
    	int status = fwrite(data, length, 1, file);
     
    	if (status == -1) error_report("%s: writing packet (%lu) data on stream %p "
    								   "failed (%d): %s",
    								   __FUNCTION__, length, file,
    								   status, strerror(errno));
    	status = fflush(file);
    	return status;
    }

    Now you might want to deduplicate the code and make it one big and two small functions:

     
    static int
    safe_operation (size_t (func) (void *, size_t, size_t, FILE*), void *data, size_t length, FILE* file)
    {
    	int status = func(data, length, 1, file);
    	const char *funcstr = "undeclared";
     
    //	switch (*func) {
    //		case fread:
    //			funcstr = "read";
    //			break;
    //		case fwrite:
    //			funcstr = "write";
    //			break;
    //		default:
    //			funcstr = "?";
    //			break;
    //	}
     
    	if (status == -1) error_report("%s: %s (%p) packet (%lu) data on stream %p "
    								   "failed (%d): %s",
    								   __FUNCTION__, funcstr, *func, length, file,
    								   status, strerror(errno));
    	status = fflush(file);
    	return status;
    }

    but it wouldn’t compile because fread and fwrite have slightly different signatures.
    The solution is to:

     
    typedef size_t (*fwrite_fn)(const void * __restrict, size_t, size_t, FILE * __restrict);
     
    static int
    safe_operation (fwrite_fn func, void *data, size_t length, FILE* file)
    {
            int status = func(data, length, 1, file);
            const char *funcstr = "undeclared";
     
            if (status == -1) error_report("%s: %s (%p) packet (%lu) data on stream %p "
                                                                       "failed (%d): %s",
                                                                       __FUNCTION__, funcstr, *func, length, file,
                                                                       status, strerror(errno));
            status = fflush(file);
            return status;
    }
     
    int
    main(void)
    {
            int x;
     
            safe_operation((fwrite_fn)fread, &x, sizeof x, stderr);
            safe_operation(fwrite, &x, sizeof x, stderr);
            return 0;
    }

    Thanks to Roland for pointing that out.

  • On smth unrelated: Fought with OpenSSL and it’s API and documentation. But more on that in a different post.
  • Fortunately, only Gajim crashed once. Well rhythmbox locks up, too, as it always does
  • Annoyed by the fact, that it takes ages to “make” a freshly made kernel!
    muelli@bigbox ~/git/linux-2.6 $ time make 
      CHK     include/linux/version.h
      CHK     include/generated/utsrelease.h
      CALL    scripts/checksyscalls.sh
      CHK     include/generated/compile.h
      CHK     include/linux/version.h
    make[2]: `scripts/unifdef' is up to date.
      TEST    posttest
    Succeed: decoded and checked 1382728 instructions
    Kernel: arch/x86/boot/bzImage is ready  (#14)
      Building modules, stage 2.
      MODPOST 2107 modules
    WARNING: modpost: Found 4 section mismatch(es).
    To see full details build your kernel with:
    'make CONFIG_DEBUG_SECTION_MISMATCH=y'
    
    real	14m7.842s
    user	1m33.747s
    sys	0m25.388s
    muelli@bigbox ~/git/linux-2.6 $ 
    
  • Trying to automatically create a FAT image and fill populate it with the built modules is more cumbersome than expected. guestmount is way too much overhead: It requires qemu and channels the data out over the network (sic!). I just want a FUSE implementation that is capable of writing a FAT image! There seems to be UMFUSE but it’s packaged for Debian/Ubuntu and not for Fedora.Find the sources is quite a challenge (it’s here: https://view-os.svn.sourceforge.net/svnroot/view-os/trunk/fuse-modules/fat) but I can’t build it, because they haven’t really prepared their code for anybody else to build it. After being harassed to generate the ./configure file (autoconf,; aclocal; autoconf), it also wants shtool to be installed AND in a local directory (/.-). I gave up as it kept bugging me about a missing config.sub. But I still wanted to get that FUSE module so I dug up my Ubuntu chroot and apt-get sourced the files, ./configure && make && make install. Beautiful. Turns out, that the official FUSE wiki lists two ways to mount a FATfs: the one I’ve just described and a dead project (FatFuse).

    I then threw together this shellscript:

    ##!/bin/bash
     
    MOD_DIR=/tmp/linux-modules/
    FAT_IMAGE=/tmp/modules.$$.fat
    FAT_MOUNT=/tmp/share/
    FAT_TARGET_IMAGE=/tmp/modules.fat
     
    make modules_install INSTALL_MOD_PATH="$MOD_DIR" &&
     
    bytes=$(( $(du -s $MOD_DIR | awk '{print $1}') + $(( 20 * 1024)) ))
    #
    # create FAT image
    dd if=/dev/zero of=$FAT_IMAGE bs=1024 count=$bytes &&
    mkfs.vfat $FAT_IMAGE &&
    fusefat -o nonempty -o rw+ $FAT_IMAGE $FAT_MOUNT &&
    cp -dRx $MOD_DIR/* $FAT_MOUNT
    fusermount -u $FAT_MOUNT &&
    echo $FAT_IMAGE &&
    ln -sf $FAT_IMAGE $FAT_TARGET_IMAGE

    and I start qemu like that:

    /opt/muelli/qemu/bin/qemu-system-x86_64 -drive file=/tmp/ubuntu-snapshots.qcow2,if=virtio -kernel ~/git/linux-2.6/arch/x86_64/boot/bzImage -append 'selinux=0 root=/dev/vda init=/sbin/init' -m 1G -drive file=/tmp/modules.fat,if=virtio,readonly=on -monitor stdio -loadvm 1

    which allows me to access the module on the FAT drive on /dev/vdb. I can also snapshot the booted machine which saves me an awful lot of time for booting. But it took me quite a while to make QEmu do that, because the snapshot parameter for the disk does not save snapshots! Also, the FAT drive has to marked as readonly for QEmu to only save snapshots on the only remaining writable drive. But QEmu fails to make a drive readonly if the selected interface is IDE. Thus, you need virtio… Thanks to the helpful folks on IRC…

  • So yeah, all in all, I didn’t make any substantial progress :-/ I hope to finish a Webcam in software soonish though.

Practicum Status Update Week 8

  • Over the weekend, I’ve talked at the ChaosBBQ in Dortmund, Germany. A nice and small conferency gathering.
  • This week I had only a few bugs (that I reported):
  • The filter stuff is actually more complex than I initially thought: I do indeed have to handle async USB URBs which makes the code look more ugly and taste more like spaghetti. Anyway, the filter stuff should fully work now *yay*.

    I hope the video works. If it doesn’t, please download first. So we can replace packets on the fly, in and out. And of course, you could design a more complex scenario: Let the first read pass by unmodified but after that modify the packets.

  • Read a bit in “Essential Linux Device Drivers” which is an interesting to read book. I like the relaxed writing style. I haven’t gotten to the nitty gritty USB details yet though.
  • Wireshark can sniff USB communication, too. And it can save as a pcap file. And it dissects bits of the protocols. At least it shows the SCSI request for an USB Massstorage. I have to test whether it knows, say, webcams. First investigations show that it only supports USB Massstorage though. And it’d be interesting whether it can sniff the communication I’m filtering with QEmu.
  • Apparently, USB network magic for pcap is 0xdc:
    typedef struct pcap_hdr_s {
            guint32 magic_number;   /* magic number */
            guint16 version_major;  /* major version number */
            guint16 version_minor;  /* minor version number */
            gint32  thiszone;       /* GMT to local correction */
            guint32 sigfigs;        /* accuracy of timestamps */
            guint32 snaplen;        /* max length of captured packets, in octets */
            guint32 network;        /* data link type */
    } pcap_hdr_t;

    Wirehsark dumps the following:

    0000000: d4 c3 b2 a1 02 00 04 00 00 00 00 00 00 00 00 00  ................
    0000010: ff ff 00 00 dc 00 00 00 43 8e 44 4c d7 96 05 00  ........C.DL....

    So I might be able to implement saving to PCap at some stage.

  • Next week will be GUADEC! *yay* But that will also mean that I can’t work that much.
  • So my emulation seems to work now, too. I now need to speak the right protocol. So if you know a good resource that describes how a, say, USB Webcam behaves on the bus, drop me a line. Or anything that can dissect USB packets would be fine.

Practicum Status Update Week 7

  • Read about Radare. Apparently, they have “USB support” but I could only see a USB communication sniffer. So Radare doesn’t dissect USB pakets 🙁
  • Installed GDB from git, because the GDB in Fedora 13 crashes way too often. I didn’t file as many new bugs this week though 😉 I seem to have worked around all my crashers…
  • Fought a lot with git 🙁 It’s incredibly hostile. I tried to rebase stuff and it keeps bugging me with old commits still being visible although I’ve changed them 🙁 I probably haven’t understood what it does yet. Tried to fix as much as possible using git reflog. Of course, the man page references options (–verbose in my case) that are not existant. Brilliant. I don’t know why I actually expected git to help me.
    This is hilarious, too:

    muelli@bigbox ~/git/qemu $ git rebase setup_fds 
    First, rewinding head to replay your work on top of it...
    Applying: Temporary migration to usb_packet_filter_setup_fds
    Using index info to reconstruct a base tree...
    Falling back to patching base and 3-way merge...
    Auto-merging usb-linux.c
    CONFLICT (content): Merge conflict in usb-linux.c
    Failed to merge in the changes.
    Patch failed at 0001 Temporary migration to usb_packet_filter_setup_fds
    
    When you have resolved this problem run "git rebase --continue".
    If you would prefer to skip this patch, instead run "git rebase --skip".
    To restore the original branch and stop rebasing run "git rebase --abort".
    
    
    muelli@bigbox ~/git/qemu $ nano usb-linux.c # hack hack hack
    muelli@bigbox ~/git/qemu $ git add usb-linux.c
    muelli@bigbox ~/git/qemu $ git rebase --continue
    Applying: Temporary migration to usb_packet_filter_setup_fds
    No changes - did you forget to use 'git add'?
    
    When you have resolved this problem run "git rebase --continue".
    If you would prefer to skip this patch, instead run "git rebase --skip".
    To restore the original branch and stop rebasing run "git rebase --abort".
    
    muelli@bigbox ~/git/qemu $ 
    

    WTF?!

    That one is brilliant, too:

    muelli@bigbox ~/git/qemu $ git rebase -i setup_fds
    # Stupid me: I selected "f" for the very first entry in that edit window
    Cannot 'fixup' without a previous commit
    # Fair enough, let me restart then:
    muelli@bigbox ~/git/qemu $ git rebase setup_fds 
    Interactive rebase already started
    # O_o WTF? What else, besides aborting, could I possibly do anyway?!
    muelli@bigbox ~/git/qemu $ git rebase --abort
    muelli@bigbox ~/git/qemu $ git rebase setup_fds 
    # Now it works...
    
  • Reimplemented host side USB filters to obtain valid USB communication. I have various simple filters: PassThrough, Logging and Replacing. The first one does nothing but return the data w/o any modification. The second one writes the bytes it reads and writes to files. The third one replaces 512 “A”s with 512 “B”s. Still need separate packets from the device in question to the host from packets from the host to the device to obtain valid device behaviour without reading all of the documentation. That will give me a good starting point to actually do the fuzzing.

    That replace filter produced interesting results. I replaced every “A” transmitted by a “B”. On the host, I created a file on a mass storage with 4KB “A”s. When “cat”ting the file from the guest, I saw “A”s. But copying the file in the guest resulted in the new file having all “B”s. I expected the “cat” showing all “B”s, too. And as far as I can see, the “A”s are actually replaced for the “cat”.

    Of course, Istanbul crashed while trying to make that screencast.
    Note that the filter code actually changed by now, not only because I enhanced the protocol (in the version you’re seeing, only USB payload is exchanged. In the new version, also the PID, device address and device endpoint are filtered) but also because I refactored the communication bits into a USBPacket class.
    I missed to show the pen drive from the host point of view after having copied the file in the guest, but the “bbbb” file is full of “B”s.

  • I’m on my way to emulating a USB device, i.e. make the guest think it has a USB device attached but the device is a program running on the guest. I basically copied the USB serial driver and the HID driver and modified them to get packets from a pipe and send them to a pipe. I had serious problems with QEmu: QEmu didn’t register my new “device”. Now I called the right function to initialize the USB device and voila, it attaches it like it should.
    Now I need to obtain valid USB communication using the filter so that I can respond to incoming packets properly.
  • Dear lazyweb, I’m wondering whether I could make my OS load an application but then break on main() so that I can attach a debugger. I cannot run the application *with* GDB. Instead, I want to attach a GDB after the program is fully loaded. Maybe LD_PRELOADing on main() will work?

Practicum Status Update Week 5

  • Implemented adding and removal of a filter. It works via the monitor or command line. And it does indeed seem to work:


    Sorry for that video being so poorly embedded in this wordpress instance. You might want to try to download the video directly.

    So yeah, we can potentially filter USB packets by now, which allows us in-place fuzzing. But that’s cumbersome because we need to have a device attached to the host. So the goal must be to be able to do USB communication without a device being attached to the host but with a program that emulates the USB device in question.

  • Of course I had problems to build Istanbul, the software I created the screencast with. Other stuff, including my IDE 🙁 just crashes, too…
  • I used qemu to pass a usb device through to the guest. Hence the Linux on the host detached the device. I desperately tried make Linux reattach the device. I tried to use ioctl() with USBDEVFS_CLAIMINTERFACE but it didn’t really work. After spending many hours, I just unplugged and replugged the pendrive…
    My code is pretty much

        int interface = atoi(argv[1]);
        fd = open("/dev/bus/usb/002/006", O_RDWR);
        result = ioctl(fd, USBDEVFS_RELEASEINTERFACE, &interface);
        //result = ioctl(fd, USBDEVFS_CLAIMINTERFACE, &interface);
        printf("Result: %d, errno: %d %s\n", result, errno, strerror(errno));
    

    and fails with Invalid Argument for RELEASE or for CLAIM with -EINVAL (Invalid Argument) or -ENOENT (No such file or directory). I have no idea what I am doing wrong. So if you do, please tell me 😛
    Oh, and these ioctls are not exported to Python I think. At least I couldn’t find the correct ioctl number for USBDEVFS_CLAIMINTERFACE without progamming a tiny C program to print it out for me.

  • Trying to test anything with QEmu is a pain though: It takes ages to boot anything with QEmu without KVM 🙁 It takes literally a whole night to boot into an Ubuntu installation CD.
  • trying to work with a minimal operating system created by the following command on my Ubuntu box:
    sudo ubuntu-vm-builder kvm lucid --addpkg openssh-server --addpkg screen --addpkg acpid --addpkg htop --addpkg cheese --flavour generic
  • For the record: I build my QEmu with the following command ./configure --prefix=/opt/muelli/qemu/ --disable-strip --extra-cflags="-O0 -DDEBUG" --disable-docs --enable-io-thread --enable-attr --enable-kvm --disable-xen --target-list="i386-softmmu x86_64-softmmu" --enable-curses && make && make install

Practicum Status Update Week 4

Again, a small summary of my last week.

  • Filed a couple of bugs that annoyed me. My favourite: My main monitor dies randomly. Let’s hope it’s not a hardware issue. That’d seriously put me back. In fact, it’s quite cumbersome to reanimate my monitor in the middle of a working session… Oh. And qemu crashes 🙁 That’s really unfortunate for me atm.
  • Subscribed and quickly unsubscribed qemu-devel mailinglist. Way too noisy. Those low-level people don’t seem to like using bug tracker or smth like ReviewPad to submit patches. Very stressful.
  • Enjoyed a long weekend in Hamburg including watching some Worldcup games
  • Read through Qemu code and tried to grasp how things play together.
  • Started to implement simple USB packet filter. spent ages resolving a logical error: I checked for retval != -23 whereas I should have checked for retval == -23 🙁
    We can haz new commands

    So I have exported a new command to the QEmu monitor. And we can even attach some logic to that new command:

    Logic attached, nothing works yet though

    Everything returns -1 at this stage though. So the actual implementation still needs to be done.

  • It literally takes a whole night for me to boot anything with qemu though 🙁 That’s a real pain and I cannot work that way. My CPU is one of the few modern Intel CPUs that does not support hardware virtualisation 🙁 I need to think of a solution.
  • I still don’t really have a timeline 😐
  • Our deadline is on 2010-08-20 and we are supposed to hand in 3 hard copies and one soft copy. I wondering whether I have to go back to Dublin to hand my hard copies in.

Practicum Status Update Week 2 and 3

So I figured that we are supposed to write a blog during our practicum phase. Here I am.

  • I missed the first official week, which was right after the exams anyway. I doubt anybody was able to do anything after the Biometrics exam.
  • In the second week, I moved back to Germany. Slowly though: I attended LinuxTag and visited a friend…
  • The third week began with some administrative stuff (i.e. taxes and care about a grant). I also almost finished running GNOME Foundation Board of Directors elections: Preliminary Result.
  • More work related: I tried to updated from Fedora 12 to Fedora 13 (to get latest QEmu and tools). Didn’t work (as expected) out of the box. Encountered (and reported) a couple of annoying bugs. My favourite: The update tool tries to mount /boot and swap. But /boot is left unclean because the preupgrade tool apparently does a hard reboot (i.e. w/o unmounting the filesystems properly). And swap can’t be found by the upgrade tool (for whatever reason). In both cases the installer just stops working and reboots the machine (sic!), as opposed to just fsck /boot or continue w/o swap.
  • Began to set up working environment: LaTeX Template, cloned qemu repository, looked a bit at QEmu code.
  • Tried to install some Operating Systems to break. Microsoft didn’t let me.
  • Read some stuff
  • Filed two bugs against Zotero (my bibliography tool): One problem in fullscreen mode and one with proxied URLs.
  • Went to a regulars’ table (for the first time after 9 month) and found out that one of them runs a company and they do USB security assessment atm. They are trying to make QEmu emulate a mass storage that returns a good file on the first read and a bad file (i.e. virus) on the second read. Sounded interesting, we’ll keep in touch and exchange details.
  • Right now I’m missing kind of a plan for my work. I haven’t really structured my work or broken it up. So I’m trying to see how many weeks I actually have (I know that I’ll go at least to GUADEC, the annual GNOME conference, for one week. I might even be invited to GNOME.Asia in Taiwan…) and what I could possibly do in that time.
  • I do have a high level idea of what needs to be done, i.e.
    • Patch QEmu to pipe USB communication in and out,
    • write some backend that uses these pipes to communicate with the guest,
    • find a smart algorithm to create/modify fishy USB packets (i.e. try to understand how a webcam communicates and set funny values for resolution on purpose),
    • try to exploit an Operating System (probably best to start off with a self-broken USB driver or application)
  • I’ll try to have a roadmap by the beginning of the next week.

Practicum: Virtualised USB Fuzzing

Alright, I finally decided on my practicum subject. Together with my supervisor, we came up with the following exposé. I either wanted to do that or to do something in Mobile (Phone) OS security.

USB is omnipresent and so far, mostly Operating System behaviour has been exploited, i.e. automatically run an application off a CDROM. USB-Stack, USB-Driver or application security has not yet been in the focus of security research, probably because it is infeasible to create many USB test devices.

If various USB behaviour could be implemented easily and cheaply, a great diversity of maliciously acting USB devices could be tested with little effort.

The goal is to implement a USB fuzzing framework using a virtualisation software that allows to automatically test different USB behaviour to stress-test USB-Stacks, drivers and applications.

While hardware approaches would be possible, a virtual approach using virtualisation software will be taken. That allows any guest Operating System, including Windows and Linux, to be tested, as well as cheap and quick creation of tests and reliable reproduction of the obtained results.

Ideally, this results in exploits for each of the three identified vulnerable layers:

  • USB Stack in the Operating System
  • USB Driver for the attached device (i.e. Webcam)
  • Application using data from the USB device

Thus following questions will be addressed:

  • How secure are USB stacks when it comes to weird devices?
  • How resistant are drivers when specially crafted payload is sent?
  • How good are applications that act upon a new USB device and read its data?

MSN Shutdown in 2003

During CA640 I was made to write an ethical review which I was supposed to hand in using a dodgy webservice. Since it got 90% people mugged me to make it available 😉 Of course, I don’t have a problem with that, so people now have a reference or know what to expect when they enter the course.

You can find the PDF here and its abstract reads:

At the end 2003 Microsoft closed the public chat-rooms of its Internet service called MSN.
MSN was pushed by Children’s Charities because they feared an abuse of these chat-rooms.
In some countries, however, the service was still available but subject to a charge.
This review raises ethical questions about Microsoft’s and the Children’s Charities’ behaviour because making the people pay with the excuse of protecting children is considered ethically questionable.
Also the Children’s Charities pushed for closure of a heavily used service although there is absolutely no evidence that children would be safer after closing down a chat-room.

If you are not interested in the non-technical details you might be interested to know that I use a Mercurial Hook on the server side to automatically compile the LaTeX sources one I push changes to the server:

$ cat .hg/hgrc
[hooks]
changegroup.compile = export FILE=paper && hg up -C && pdflatex --interaction=batchmode $FILE && bibtex $FILE && pdflatex --interaction=batchmode $FILE && pdflatex --interaction=batchmode $FILE

And then I just symlink that resulting PDF file to my public_html directory.

Subverting (Soft) Quota

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*

Adding Linux Syscall

In a course (CA644) we were asked to add a new syscall to the Linux kernel.Linux Oxi Power!

As I believe that knowledge should be as free and as accessible as possible, I thought I have to at least publish our results. Another (though minor) reason is that the society -to some extend- pays for me doing science so I believe that the society deserves to at least see the results.

The need to actually publish that is not very big since a lot of information on how to do that exists already. However, that is mostly outdated. A good article is from macboy but it misses to mention a minor fact: The syscall() function is variadic so that it takes as many arguments as you give it.

So the abstract of the paper, that I’ve written together with Nosmo, reads:

This paper shows how to build a recent Linux kernel from scratch, how to add a new system call to it and how to implement new functionality easily.
The chosen functionality is to retrieve the stack protecting canary so that mitigation of buffer overflow attacks can be circumvented.

And you can download the PDF here.

If it’s not interesting for you content wise, it might be interesting from a technical point of view: The PDF has files attached, so that you don’t need to do the boring stuff yourself but rather save working files and modify them. That is achieved using the embedfile package.

\usepackage{embedfile}        % Provides \embedfile[filename=foo, desc={bar}]{file}
[...]
\embedfile[filespec=writetest.c, mimetype=text/x-c,desc={Program which uses the new systemcall}]{../code/userland/writetest.c}%

If your PDF client doesn’t allow you save the files (Evince does 🙂 ), you might want to use pdftk $PDF unpack_files in some empty directory.

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