jeudi 2 avril 2015

Let's go fishing with fake sstic challenge

Yesterday, as I was idling on the interwebs, I noticed a challenge on twitter:

The URL is http://static.sstic.org/challenge2015/chlg-2015 .

Yesterday was the 1st april, fool's day. I didn't expected much of that, but clicked on the link anyway:

OOOOOOkay.

We noticed immediately the Salted__ which is an openssl header, we know that it is followed by the 8 bytes of salt, and after this header, the encrypted message. Documentation says that nothing can be known of the underlying cipher or mode used from this header.

So, if we want to break by bruteforce this encryption, we have to guess the encryption scheme and the password. And we are the 1st of april, so it could just be pure random in order to laugh at us wasting CPU cycles.

But, if you watch closely the picture, you can clearly see a pattern repeating.

That's unusual. Good crypto should be undistinguishable from random. So, either this is a fake, either this is bad crypto. And we know one bad crypto mode: ECB, where identical cleartext gives identical crypt.

Let's continue with this idea. File containing a lot of identical data are uncompressed images, as of BMP. BMP is made of an header, then groups of three bytes representing a pixel (Red Green Blue value in hex).

We have a file of  3000144 bytes. 16 bytes are from openssl header, some bytes from BMP header, and the pixels. If we imagine a 1000x1000 image , we need 300000 bytes of pixel data. Let's skip those 144 bytes and watch at that.

In two lines of shell:

Tada!

We can see something :-)

If we reverse the image with convert -flip, we can better read the email and we're done.

Please, SSTIC commitee, can you reserve a place for me? (I'll pay it, it's just to be sure to have one ;) )


EDIT: it was just too easy. No need to bruteforce, first try, win:


0xMitsurugi

mardi 20 janvier 2015

Let's have (not) fun with afl

And that's a part two for an extreme exploitation of my previous bug found with afl. It was a crash in cabextract.

And it's a double fail.

1/ First fail
This crash is just a null pointer dereference. There is a lot of documentation in internet for it, and in that case, that's just not interesting at all. In order to be exploitable, you have to map an executable page at offset 0 and trigger the crash.

Here is a nice doc talking about null deref. Here is another blogspot explaining how to exploit null deref in linux kernel (now it's protected).

Short story short: "In the realm of userland applications, exploiting them usually requires being able to somehow control the target's allocations until you get page zero mapped, and this can be very hard."

2/ Second fail
This bug is known and corrected! You can see a nice explanation in debian bugtracker.

So,  nothing to do here, and moving for next target!

Mitsurugi

mercredi 14 janvier 2015

Let's have some fun with afl

1/ Let's play

Let's play with the fuzzer afl. I'll write some blogposts about my research with afl. This can be seen as a diary of a fuzzer :-)

2/ At first, choose your target

I think that afl has been pretty much used on usual unix binaries (compressor, file format, and so on), so I did a
$ ls /usr/bin

and choose one of them in order to fuzz. afl is great at fuzzing programs which take a file as argument and don't produce too much output. There is a lot of them which can be fuzzed.

That's easy, just grab the sources of the binary you want to fuzz, recompile it using afl-gcc (or afl-g++), and roll!
Sometimes, it's better to desactivate checksum computations: fuzzing goes faster, fuzzing goes farther (doesn't stop for a bad checksum) and in case of a crash, you can easily recalculate the checksum and see if crash is still here.

After fuzzing a lot of software, I managed to reach two crashes:

That's enough for a good start. Those two crashes will be investigated.

I don't look at hangs: my computer do a lot of things (loadavg > 1 most of the time), and afl has an aggressive value of 50ms for saying that program has stopped. So, there is a lot of false positive. And I'm mostly interested in crashes anyway.

3/ Keep focused

Afl comes with an handy helper call Peruvian were rabbit. Just feed afl-fuzz with some known files causing a crash and it will make some variation around it in order to see if some new crashes appears.

$ cd ..
$ mkdir crashes crashes/findings crashes/testcases
$ cp fuzzy/findings/crashes/id\:000001* crashes/testcases/case1
$ cp fuzzy/findings/crashes/id\:000002* crashes/testcases/case2
$ cd crashes
$ afl-gcc -C -i testcases/ -o findings/ unnamed -t @@

And unsurprisingly, number of crashes grow very fast:

I have now 255 files causing crashes.

What's really interesting in my case is that the unmodified program (the one doing checksum) segfaults too :-) It writes a message "bad checksum", but segfault like a boss:

mitsurugi@mitsu:~/fuzz$ ./unnamed-no-cksum -t case1
Segmentation fault
mitsurugi@mitsu:~/fuzz$ ./unnamed-ori -t case1
    failed (checksum error)
Segmentation fault
mitsurugi@mitsu:~/fuzz$


mitsurugi@mitsu:~/fuzz$ ./unnamed-no-cksum -t case1
Segmentation fault

mitsurugi@mitsu:~/fuzz$ dmesg | tail -1
[784784.901989] unnamed-no-cksum[29344]: segfault at 0 ip   (null) sp bf89d38c error 14 in unnamed-no-cksum[8048000+57000]
And it seems promising, because it crash on a bad EIP value (and not a losy read or write in forbidden location). My senseï said:

"If you manage to control EIP, you'll soon manage to control the world"

4/ Let's investigate

I have a good lead, the next step is to force EIP to a choosen value (0x41414141 for example) instead of 0x00000000.

The crash appears here:
=> 0x804daf0:    call   DWORD PTR [eax+0x40]
   0x804daf3:    cmp    eax,0x3
   0x804daf6:    je     0x804db54


And the memory layout around eax is:
gdb$ x/12dwx $eax + 0x30
0x80618b0:   0x0804a580    0x0804a560    0x00000000    0x0000eaea
0x80618c0:   0x00000000    0x00000000    0x080601e8    0x08060080
0x80618d0:   0x00000000    0x080618dc    0x080618dc    0x00000000
gdb$


unfortunately, I don't have 0xeaea followed by some 0x00 in source file. So I think I'll have to dig really further.

I also have 255 files, I choose 10 of them, all of them crash with EIP=0x00000000. It's time to industrialize the checkings.

That's all for today :-)
Mitsurugi

mardi 6 janvier 2015

Is fuzzing obsolete? No, afl rocks!

1/ Intro

Is fuzzing obsolete? I've read an interesting presentation given at NosuchCon about analyzing execution of binaries.

One slide was saying that fuzzing is over:

So, let's try it with afl, or american fuzzy lop. As everybody knows, american fuzzy lop is a rabbit, but few knows that it's a really powerful fuzzer made by lcamtuf.

Afl can instrumentate the code in order to follow some path, instead of relying on chance only.

2/ Dumb mode, before afl

If I rely with chance only, with an initial buffer "good", and with 1000 try/seconds, I will have to wait (2^32/1000/3600/24) = 49 days to trigger a crash. That's not really efficient.

3/ AFL powerful execution mode

In order to use afl, you have to recompile your binaries with afl-gcc (wrapper around gcc). It's easy: download afl, compile it, then add in your path the build directories like:

export PATH=$PATH:/home/mitsurugi/fuzz/afl-0.88b/
export AFL_PATH=/home/mitsurugi/fuzz/afl-0.88b/

(protip: your PATH should be set before afl, i.e. PATH=afl-dir/:$PATH won't work)

and rocks:

Now the code is instrumented, we just have to launch afl-fuzz:

And in less than an hour (!!!) afl trigger the crash:

That's incredible. Dumb fuzz was expecting 49 days.

4/ conclusion

So, I think that we can say that fuzzing is not over yet :-) Let's start afl everywhere in every progs!

I've currently trigger a crash in a common unix utility, but it's not exploitable (working on it, but it's hard, I can write some 0 in a not really arbitrary location :-( ).

What I miss so much is the same fuzzer for networking utility. Kind of :
printf 'GET / HTTP/1.1\r\nHost: localhost\r\n\r\n' > tescases/request
afl-fuzz -i testcases/ -o findings httpd @@

lundi 3 novembre 2014

NoSuchCon cracking crackmips

Yesterday was an hard day: big hangover after saturday night beer session, big headache and no internet.
So I choose to drink a lot of water and play with NoSuchCon crackmips to change my mind.

There is two major parts in this blogpost. After the initial recognition, I began to follow a lead, really instructive, but destined to fail. Then, I restate my assumption, and with the experience of the first try, I manage to crack the binary.

1) Recon target

  • You won't make it through this fight!

1-1) Installation

the binary is a MIPS binary. I used qemu-system-mipsel to work, here is a little shell script:

$ cat startme.sh
#! /bin/bash
qemu-system-mipsel -M malta -kernel vmlinux-3.2.0-4-4kc-malta -hda debian_wheezy_mipsel_standard.qcow2 -append "root=/dev/sda1 console=tty0" -m 512 -net nic -net user,hostfwd=tcp::22222-:22

$

With it, I can launch qemu, and then ssh into it on localhost port 22222.

1-2) First glance

nm crackmips reveals some intersting information:
  • use of SHA256 and AES
  • presence of ptrace
  • forking
  • a function called decrypt_url
Time to try with a :
user@debian-mipsel:~$ ./crackmips
usage: ./crackmips password

user@debian-mipsel:~$ ./crackmips toto
WRONG PASSWORD
user@debian-mipsel:~$


I don't know if reversing is a kind of science or an art. How much intuition can help when you reverse something against a scientific analysisis af full code. Let's begin with intuition.

2) First try:

  • I'll show you what fighting with swords is all about.

 2-1)  Intuition

My first intuition was to think crackmips as that:
  • a (somehow useless) antidebug ptrace call: In a lot of challenge, there is an antidebug ptrace call.
  • forking of a process
  • a validation of password with an algorithm in this child
  • a SHA-256 of password which will be used as a key to decrypt a specific url

2-2) Go, go, go.

Let's get rid of ptrace with LD_PRELOAD trick, then play with binary. We quickly find that a wrong password will print "WRONG PASSWORD" (srsly?), but some passwords print "ERR". That's a good lead. If we follow crackmips with strace, we see that 'clone'  is called when password is 48 char long. to sum up:
  • The password must be 48 char long
  • The password must be in range [0-9A-F]
  • The program forks if both previous rules are right

2-3) Time to objdump

objdump -d crackmips reveals something quite interesting: A lot of break (101!) as you can see:
(snip...)
  402300:      00821021        addu    v0,a0,v0
  402304:      ac430008        sw      v1,8(v0)
  402308:      0000000d        break
  40230c:      8fc30038        lw      v1,56(s8)
  402310:      00031080        sll     v0,v1,0x2
  402314:      27c40018        addiu   a0,s8,24
  402318:      00821021        addu    v0,a0,v0
  40231c:      8c440008        lw      a0,8(v0)
  402320:      8fc20038        lw      v0,56(s8)
  402324:      00822023        subu    a0,a0,v0
  402328:      00031080        sll     v0,v1,0x2
  40232c:      27c30018        addiu   v1,s8,24
  402330:      00621021        addu    v0,v1,v0
  402334:      ac440008        sw      a0,8(v0)
  402338:      0000000d        break
  40233c:      8fc30038        lw      v1,56(s8)
  402340:      00031080        sll     v0,v1,0x2
  402344:      27c40018        addiu   a0,s8,24
  402348:      00821021        addu    v0,a0,v0
(snip...)


2-3) Let's gdb

gdb is launched with LD_PRELOAD in order to get rid of ptrace and follow-fork-mode child.If launched with a 48-char pass, it stops as expected on the first break instruction (0x40228c).

2-4) Digging into the break

The break are all based on the same scheme:
  • initialization of values
  • loading of 8 chars of password in $a0 (we notice that char are inversed, 12345678 becomes 87654321 in register)
  • simple operation (plus, xor, add, minus, leftshift of bit, rightshift, and so on)
  • saving the new password
 At the end of the 100 breaks, we have:
   0x4039e0 <main+6588>:    addiu   v0,v0,1
   0x4039e4 <main+6592>:    sw  v0,56(s8)
   0x4039e8 <main+6596>:    lw  v0,56(s8)
   0x4039ec <main+6600>:    sltiu   v0,v0,6
   0x4039f0 <main+6604>:    bnez    v0,0x40228c <main+616>

so we understand that its counter get incremented from 0 to 5 (6x8=48).

then a memcmp follow:

   0x4039f8 <main+6612>:    addiu   v0,s8,32
   0x4039fc <main+6616>:    move    a0,v0
   0x403a00 <main+6620>:    lui v0,0x40
   0x403a04 <main+6624>:    addiu   a1,v0,15524
   0x403a08 <main+6628>:    jal 0x400840 <memcmp@plt>


we find an intersting string at that point:
a0 : scrambled password string
a1 : "[ Synacktiv + NSC = <3 ]"

a2 : 24 char to analyser
Ok, so the password, once scrambled, should equals to "[ Synacktiv + NSC = <3 ]" (yeah, guys, I love you too, especially on bad afternoon like this one, with Evian and headache)

If we patch the result of the memcmp function to be true, we see some junk printed to screen. 

So some of my guesses must be right: password is scrambled with those 100 functions, then compared to a fixed string, then decrypt_url is called. 

2-5) Boring time.

The work can begin. In a window, objdump. In another, vi. 
I begin to write a veeeery boring python script. I took all parts between breaks, revert them and create a function for each of them (100 times. Boring. As. Hell. Yuck!).

I found that there is 5 different function (plus, minus, xor, leftslide, rightslide) called with different args. Some functions depends of the position of the part of the password (0->5).

So, the progs looks like a long list of:
 (...)
def func_4034f0(v0):
    moins(v0)

def func_4034a4(v0):
    rightslide(0xf)

def func_403444(v0):
    rightslide(v0+1)

 (...)
and at the end
( ... )
func_4034a4(pos)
func_403444(pos)
(... etc..)

2-6) Crack it (and fail like a boss!)

I  launch my python prog 6 times:
$ ./rev.py 7953205b 0
$ ./rev.py 6b63616e 1
etc:
so the password should be: D3CC52F8EC139ED6BA23B382F2B63ADFA9545C5C8B8BF5C2

I patched the binary and replace all breaks with nops, and within a single heartbeat (my sensei says: always give the final blow quick, strong and clean), I typed:

user@debian-mipsel:~$ ./patched_crackmips_nobreaks D3CC52F8EC139ED6BA23B382F2B63ADFA9545C5C8B8BF5C2
MP!����jU� ����� |,vB���f�� ���
                                 �؀��� / ��Q'��)g'��˞qC ��| n����/    �Lu�]��]
user@debian-mipsel:~$


Obviously, there is something wrong! That's confirmed with the unpatched binary:
user@debian-mipsel:~$ ./crackmips D3CC52F8EC139ED6BA23B382F2B63ADFA9545C5C8B8BF5C2
WRONG PASSWORD
user@debian-mipsel:~$

3) Second try:

  • I don't matter how many times you try! I'll win!
After an aspirine, I went back to crackmips. I knew that something was obviously wrong because of the breaks. How in the world can the binary continue after a break without help? And why the linear following of all those breaks doesn't points to victory?

3-1) Solving the break mystery

By digging in the code, I noticed that ptrace was called several times. I decided to launch the binary without my anti_ptrace hooking lib.
 user@debian-mipsel:~$ strace -i ./crackmips
D3CC52F8EC139ED6BA23B382F2B63ADFA9545C5C8B8BF5C2
 (... snip...)
[77e92e70] clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x77fee068) = 2111
[77e93000] --- SIGCHLD (Child exited) @ 0 (0) ---
[77e9257c] waitpid(2111, [{WIFSTOPPED(s) && WSTOPSIG(s) == SIGTRAP}], __WALL) = 2111
[77ecd52c] ptrace(PTRACE_GETREGS, 2111, 0, 0x7fff6484) = 0
[77ecd52c] ptrace(PTRACE_SETREGS, 2111, 0, 0x7fff6484) = 0
[77ecd52c] ptrace(PTRACE_CONT, 2111, 0, SIG_0) = 0
[77ecd52c] --- SIGCHLD (Child exited) @ 0 (0) ---
[77e9257c] waitpid(2111, [{WIFSTOPPED(s) && WSTOPSIG(s) == SIGTRAP}], __WALL) = 2111
[77ecd52c] ptrace(PTRACE_GETREGS, 2111, 0, 0x7fff6484) = 0
[77ecd52c] ptrace(PTRACE_SETREGS, 2111, 0, 0x7fff6484) = 0
[77ecd52c] ptrace(PTRACE_CONT, 2111, 0, SIG_0) = 0
[77ecd52c] --- SIGCHLD (Child exited) @ 0 (0) ---
[77e9257c] waitpid(2111, [{WIFSTOPPED(s) && WSTOPSIG(s) == SIGTRAP}], __WALL) = 2111
[77ecd52c] ptrace(PTRACE_GETREGS, 2111, 0, 0x7fff6484) = 0
[77ecd52c] ptrace(PTRACE_SETREGS, 2111, 0, 0x7fff6484) = 0
[77ecd52c] ptrace(PTRACE_CONT, 2111, 0, SIG_0) = 0
[77ecd52c] --- SIGCHLD (Child exited) @ 0 (0) ---
 (... snip...)


We can see a pattern here, GETREGS, SETREGS, CONT called multiples times.

So, my assumption about ptrace used as antidebug is false! ptrace is used in order to drive the child process. The father waitpid for the child, then get its regs, modify them and send a PTRACE_CONT.

3-2) Let's debug father

With gdb, I choose to break at debug function (once again, driven by intuition).

After some sanity checks (did ptrace success, did the child is in waitpid etc..) we see (again) a looooong list af scrambling data beginning at:
  400b8c:       8fc2014c        lw      v0,332(s8)
  400b90:       afc2001c        sw      v0,28(s8)
  400b94:       3c020040        lui     v0,0x40
  400b98:       24420a78        addiu   v0,v0,2680
  400b9c:       8fc3001c        lw      v1,28(s8)
  400ba0:       00621023        subu    v0,v1,v0
  400ba4:       afc2001c        sw      v0,28(s8)
  400ba8:       8fc20018        lw      v0,24(s8)
  400bac:       3c03446f        lui     v1,0x446f
  400bb0:       34638657        ori     v1,v1,0x8657

 (...snip)



But in the middle of this long scrambling, there is a check:
  401440:       08100529        j       4014a4 <debug+0xa44>
  401444:       afc00020        sw      zero,32(s8)
  401448:       8fc20020        lw      v0,32(s8)
  40144c:       00021840        sll     v1,v0,0x1
  401450:       3c020041        lui     v0,0x41
  401454:       00031880        sll     v1,v1,0x2
  401458:       24424130        addiu   v0,v0,16688
  40145c:       00621021        addu    v0,v1,v0
  401460:       8c430000        lw      v1,0(v0)
  401464:       8fc2001c        lw      v0,28(s8)
  401468:       1462000b        bne     v1,v0,401498 <debug+0xa38>
  40146c:       00200825        move    at,at
  401470:       8fc20020        lw      v0,32(s8)
  401474:       00021040        sll     v0,v0,0x1
  401478:       24430001        addiu   v1,v0,1
  40147c:       3c020041        lui     v0,0x41
  401480:       00031880        sll     v1,v1,0x2
  401484:       24424130        addiu   v0,v0,16688
  401488:       00621021        addu    v0,v1,v0
  40148c:       8c420000        lw      v0,0(v0)
  401490:       0810052d        j       4014b4 <debug+0xa54>
  401494:       afc2001c        sw      v0,28(s8)
  401498:       8fc20020        lw      v0,32(s8)
  40149c:       24420001        addiu   v0,v0,1
  4014a0:       afc20020        sw      v0,32(s8)
  4014a4:       8fc20020        lw      v0,32(s8)
  4014a8:       2c42025e        sltiu   v0,v0,606
  4014ac:       1440ffe6        bnez    v0,401448 <debug+0x9e8>
  4014b0:       00200825        move    at,at
  4014b4:       8fc30020        lw      v1,32(s8)
  4014b8:       2402025e        li      v0,606
  4014bc:       1462000c        bne     v1,v0,4014f0 <debug+0xa90>
  4014c0:       00200825        move    at,at
  4014c4:       3c020040        lui     v0,0x40
  4014c8:       24433c00        addiu   v1,v0,15360
  4014cc:       3c020041        lui     v0,0x41
  4014d0:       8c4254a0        lw      v0,21664(v0)
  4014d4:       00602021        move    a0,v1
  4014d8:       24050001        li      a1,1
  4014dc:       24060004        li      a2,4
  4014e0:       0c100230        jal     4008c0 <fwrite@plt>
  4014e4:       00403821        move    a3,v0
  4014e8:       0c100248        jal     400920 <exit@plt>
  4014ec:       24040001        li      a0,1

Basically, it just checks that the word loaded at $s8+332 after scrambling is in a list.
There is 606 tries (noticed that 101x6=606?). The question is: what represents $s8+332? It doesn't take long to understand that $s8+332 is $pc of the child. Also, the list of reference values is called "pcs", which is another good hint.

Ok, let's play with it, without trying to following it step by step.
If at $s8+332 I give a random value, then this check fails, and "ERR\n" is printed to screen: logic.
If I give one of any break address, then the check doesn't fail.
And, at the end of this loooong scrambling, I have another address which equals to another break address+4 (but not the initial break+4)


3-3)Final understanding

The best place to read the modified $pc of the child is right after the PTRACE_CONT, so I wrote some lines of gdb to log all of them in a log file.
user@debian-mipsel:~$ gdb -q crackmips
Reading symbols from /home/user/crackmips...(no debugging symbols found)...done.
(gdb) b * 0x00401e00
Breakpoint 1 at 0x401e00
(gdb) commands
Type commands for breakpoint(s) 1, one per line.
End with a line saying just "end".
>x/x $s8+332
>c
>end
(gdb) set log file breaks

(gdb) set log on
(gdb) r AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
 ( ...snip)


I have now a long list of pcs:
$ grep '0x7fff6564:' breaks
0x7fff6564:     0x0040228c
0x7fff6564:     0x004022bc
0x7fff6564:     0x00402d0c
0x7fff6564:     0x00402dd4
0x7fff6564:     0x0040357c
0x7fff6564:     0x00402f34
0x7fff6564:     0x004037a8
0x7fff6564:     0x00403728
0x7fff6564:     0x0040244c
 (... snip)


and we see that we jump from one break to another one in the binary.

3-4) Break it like a boss:

My list of breaks is 606 lines long. I can see that all breaks are called 6 times.

Here we have the explanation of why the previous password fails: all the parts between breaks are not lineary called.
I can also see that for each part of the password, the series of $pc is not the same.

In order to break, I can reused my previous script, with a little help of formatting (remember how I called all of the parts with the adress :-) )
$ head -101 ptrace7 | cut -d "x" -f3 | sed s/$/\(v0\)/ | sed s/^00/func_/ | tac > zero
$ head -202 ptrace7 | tail 101 | cut -d "x" -f3 | sed s/$/\(v0\)/ | sed s/^00/func_/ | tac > one
etc..
 
I reused all the function written in the rev.py script :
cat rev2.py zero > hundred_func.py
python ./hundred_func.py 7953205b 0
0xfe446223

cat rev2.py one > hundred_func.py
(etc..)
Once each series of char inversed (remember that I found that the password is inversed), we can crack it.

I wait until the sun set to gave the final blow without hate, without anger, just with peace in my minds and a sharpened sword:

user@debian-mipsel:~$ ./crackmips 322644EF941077AB1115AB575363AE87F58E6D9AFE5C62CC
good job!
Next level is there: http://nsc2014.synacktiv.com:65480/oob4giekee4zaeW9/
user@debian-mipsel:~$

(unfortunately, no internet yesterday to continue.)

4) Conclusion

  • Name's Mitsurugi... REMEMBER IT!
This challenge was an opportunity for me to learn some MIPS assembly.

It was very interesting, and it teach me to not blindly follow my intuitions. Always verify!
There is a lot of code I didn't read, I didn't check how the scheme of the password is made, and maybe there is some black magic inside the debug function (I didn't try hard to reverse it).

It was fun, except the 100 function to write (meh!) The challenge would be exactly the same with only 10 functions. Maybe there is a quicker way (with Sublime Text 3? ;) ) , but it doesn't matter: as my sensei says:
"No matter the road, only the purpose counts"

Thanks to Synacktiv and NoSuchcon!

dimanche 1 juin 2014

Le gourmet Solitaire

Un samouraï, un rônin, un guerrier taciturne marche, solitaire. Le ciel est bas, un vent froid fait voler la poussière dans le crépuscule.
Le samouraï entre en coup de vent dans une taverne. Sans retenir sa force, il fait coulisser la porte à grand bruit. Puis, sans la moindre hésitation, il avance d'un pas ferme à l'intérieur. Il se laisse tomber sur un coussin. Il pose à côté de lui le sabre qu'il vient de dégager de sa ceinture de kimono. La taverne est vide. Aucun client. Le patron lui-même, sans doute dans l'arrière boutique est invisible. Le samouraï tend légèrement le cou et tourne son regard vers la porte qui donne sur l'arrière, quand le patron, ayant entendu du bruit, jette un coup d’œil dans la salle.
-"A manger, Tavernier!" gueule le samouraï.
-"Voilà, voilà! Tout de suite." répond le tenancier, apeuré par le ton énergique, tout en enfilant ses soques de bois. Puis, se retournant vers le service:
-"Holà, O-mitchan"
C'est sa jeune servante qui se nomme ainsi. Sa femme est morte il y a déjà longtemps. O-mitchan se dépêche de préparer le thé de bienvenue, pose le pot sur un plateau et vient le servir.
-"Irasshaïmashi, bienvenue seigneur!" dit O-mitchan les yeux modestement baissés. Mais quand elle va pour servir le samouraï, celui-ci l'arrête d'une voix virile:
-"Pas besoin de thé! Du saké! Apporte du saké!"
-"Ah, ou.. oui." répond elle , la main en l'air, le pot de thé au bout du bras. Elle marque un temps d'hésitation: doit elle poser malgré tout le pot devant le client avant de se retirer, ou doit elle le ramener au service?
Comme s'il lisait dans son coeur, le samouraï lance une main hâlée aux doigts velus et prend d'autorité le pot de thé de la main blanche d'O-mitchan, pour le reposer sur le plateau. Avec une ombre de sourire, ses gros yeux fixés sur le visage de la douce enfant, il ajoute un ton plus bas:
-"Musumé (fillette), t'aurais pas entendu parler ces derniers temps dans le patelin de samouraïs inconnus qui rôderaient dans les parages un grand sabre à leurs ceintures?"
-"Je ne connais que http://communaute.sstic.org/ChallengeSSTIC2014 seigneur, ils se promènent tous les trois dans les bois et ils me font peur"
-"J'ai tué le premier dans l'USB, le long des lignes de 4096 octets. Il m'a donné le nom du second brigand: badbios.bin, un guerrier aux techniques ARMv8 qui camouflait son vrai visage derrière une VM. J'ai combattu une journée entière. Souviens toi de ça Musumé: 0BADBIOS IS DEAD!!"
-"Et pour fw.hex, Seigneur?"
Le samouraï laisse montrer son épaule dénudée ou se distingue une blessure qu'on devine très ancienne. Un tic nerveux le parcourt alors qu'il se frotte cette cicatrice.
-"..... fw.hex m'a échappé. Ainsi vont les choses." Grogne le samouraï.

vendredi 18 avril 2014

Run Aarch64 (ARMv8) binaries under x86 box

A small post to explain how to run ARM binaries on an x86 linux box.
mitsurugi@mitsu:~$ uname -a
Linux mitsu 3.10.17 #2 SMP Wed Oct 23 16:34:38 CDT 2013 x86_64 Intel(R) Core(TM)2 CPU         U7600  @ 1.20GHz GenuineIntel GNU/Linux

Ok. Just download the debian tgz (88MB) and static qemu binary (~7MB) from the page:
http://rwmj.wordpress.com/2013/12/22/how-to-run-aarch64-binaries-on-an-x86-64-host-using-qemu-userspace-emulation/

Untar the tgz under /chroot_armv8, copy the qemu-arm-static binary under /chroot_armv8.

Then tell your kernel to use qemu for ARM binary. Read https://www.kernel.org/doc/Documentation/binfmt_misc.txt for more information about binfmt_misc.

mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc 
cd /proc/sys/fs/binfmt_misc 
echo ":qemu-arm64:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/qemu-arm64-static:OC" > register 
cd /chroot_armv8
chroot .
root@mitsu:/# uname -a
Linux mitsu 3.8.0 #2 SMP Wed Oct 23 16:34:38 CDT 2013 aarch64 GNU/Linux

And now, you're in a debian ARMv8 :-) You can eventually bind mount some directories like /proc, /sys, etc. but at first:

echo "8.8.8.8 nameserver" > /etc/resolv.conf
apt-get update


and it's OK to start with your brand new ARMv8 board!

[update1] : rename qemu-arm-static in binfmt
[update2] : No, you can'use gdb with this setup. Qemu-arm-static doesn't seems to send ptrace syscalls. You have to use qemu with integrated gdb server and use a gdb multiarch