Thursday, January 25, 2018

Beginning Windows Exploit Development - Understanding SEH with Visual Studion 2017

This series of posts are based on me looking at expanding my knowledge on Windows Exploit Development. This is based on understanding SEH and exploiting same.

Before we get started, I must state clearly that this information is based on the guidance provided from corelan.be website as shown in the references section.

For some folks reading my material may be easier, for others reading the material from Corelan will be easier. Whichever you choose, please note that this is all based on the guidance provided by those folks and thus nothing here is my original work.

Now that the attribution stuff is out of the way, let's get going.


To help to drive home the understanding of SEH, the code below will help me out.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/*
  This code is part of my learnings of SEH handling
  Author: Nik Alleyne
  Blog: securitynik.blogspot.com
  Date: 2018-01-12
*/

#include <stdio.h>
#include <string.h>

#pragma warning(disable : 4996)

int ExceptionHandler(void);

void main(int argc, char *argv[])
 {
 // Declare a buffer of size 512 bytes
 char myBuffer[512];
  printf("Hey %s I'm running ... \n", argv[1]);
  

 // Setup the exception Handler
  __try
   {
    strcpy(myBuffer, argv[1]);
   }
  __except ( ExceptionHandler() )
   {
   }
  return 0;
 }

int ExceptionHandler(void)
 {
  printf("Just a head's up this exception is being handled ... \n");
  return 0;
 }


When compiled with Visual Studio 2017 and executed with a command line argument we get:

E:\Coding\SEH-Demo\Debug>SEH-Demo.exe SecurityNik
Hey SecurityNik I'm running ...

However, when ran without any command line arguments we get ...






















Next step is to "Launch executable" in "WindDbg Preview", by opening the "SEH-Demo.exe". Once we launch the executable we see in WinDbg Preview:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
Executable search path is: 
ModLoad: 00d20000 00e2e000   SEH-Demo.exe
ModLoad: 77df0000 77f7d000   ntdll.dll
ModLoad: 74b80000 74c50000   C:\Windows\SysWOW64\KERNEL32.DLL
ModLoad: 755f0000 757c7000   C:\Windows\SysWOW64\KERNELBASE.dll
(cb4.1130): Break instruction exception - code 80000003 (first chance)
eax=00000000 ebx=00000010 ecx=f6200000 edx=00000000 esi=007c3000 edi=77df6964
eip=77e9dadf esp=0096f91c ebp=0096f948 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
ntdll!LdrpDoDebuggerBreak+0x2b:
77e9dadf cc              int     3

Looking at the Windows Thread Information Block (TIB) at FS:[0] which contains the current Structured Exception Handler (SEH) frame to gain further insight into the SEH structure

1
2
3
4
5
6
7
8
9
0:000> d fs:[0]
0053:00000000  38 f9 96 00 00 00 97 00-00 e0 96 00 00 00 00 00 8...............
0053:00000010  00 1e 00 00 00 00 00 00-00 60 7c 00 00 00 00 00 .........`|.....
0053:00000020  b4 0c 00 00 30 11 00 00-00 00 00 00 2c 60 7c 00 ....0.......,`|.
0053:00000030  00 30 7c 00 32 00 00 00-00 00 00 00 00 00 00 00 .0|.2...........
0053:00000040  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0053:00000050  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0053:00000060  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0053:00000070  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................

Our tree looks like:
    [TEB] -> [0096f938]

From above we see the "38 f9 96 00" which points to the beginning of the TEB. Do remember that from an Intel architecture perspective, multi byte values are represented in little endian. Thus we need to reorder these bytes to get to the beginning of the SEH chain.

Still in WinDbg, when we dump the address at "0096f938" we get:

1
2
3
4
5
6
7
8
9
0:000> d 0096f938
0096f938  98 fb 96 00 20 6a e6 77-d6 50 f0 44 00 00 00 00  .... j.w.P.D....
0096f948  a8 fb 96 00 f6 8b e9 77-86 54 88 33 00 00 00 00  .......w.T.3....
0096f958  00 00 00 00 ff ff ff ff-4a 00 4c 00 c4 1e fe 02  ........J.L.....
0096f968  c8 fa 96 00 00 00 00 00-01 02 00 00 00 00 00 00  ................
0096f978  c4 fa 96 00 00 00 00 00-a0 30 fe 02 00 00 00 00  .........0......
0096f988  00 00 00 00 00 00 00 00-08 34 fe 02 01 00 00 00  .........4......
0096f998  00 00 00 00 00 50 e2 00-00 10 00 00 01 00 00 00  .....P..........
0096f9a8  00 00 00 00 d0 51 e2 00-02 00 00 00 00 00 00 00  .....Q..........

From above we now have "Next SEH Record" with a value of "0096fb98" and a pointer to the current handler of "0x776e6a20". Basically the first 8 bytes represent our SEH information. The first 4 bytes is the pointer to the next SEH record while the second 4 bytes is the pointer to our current handler.

Our structure now looks like:

1
2
3
 [TEB] -> [0096f938]
     |-> [ Next SEH Record ] -> [0x0096fb98] |->
      [   SE Handler    ] -> [0x776e6a20]   

Dumping the values at  "0x0096fb98", we get:

1
2
3
4
5
6
7
8
9
0:000> d 0x0096fb98
0096fb98  f0 fb 96 00 20 6a e6 77-b6 44 f0 44 fe ff ff ff  .... j.w.D.D....
0096fba8  00 fc 96 00 d7 37 e5 77-2e 53 88 33 34 fc 96 00  .....7.w.S.34...
0096fbb8  00 00 df 77 00 30 7c 00-00 b0 f0 77 00 10 00 00  ...w.0|....w....
0096fbc8  00 00 80 00 01 00 00 00-00 00 df 77 00 00 00 00  ...........w....
0096fbd8  34 fc 96 00 00 30 7c 00-28 30 7c 00 00 00 00 00  4....0|.(0|.....
0096fbe8  b0 fb 96 00 00 00 00 00-ff ff ff ff 20 6a e6 77  ............ j.w
0096fbf8  5e 55 f0 44 00 00 00 00-10 fc 96 00 de 36 e5 77  ^U.D.........6.w
0096fc08  00 00 00 00 00 00 00 00-20 fc 96 00 8c 36 e5 77  ........ ....6.w

From above we now have "Next SEH Record" with a value of "0x0096fbf0" and a pointer to the current handler of "0x776e6a20". From the above, it looks like this pointer is point to the same location as the previous one.

Therefore we have:

1
2
3
 [TEB] -> [0096f938]
     |-> [ Next SEH Record ] -> [0x0096fb98] |---------> [ Next SEH Record ] -> [0x0096fbf0] 
      [   SE Handler    ] -> [0x776e6a20]    [   SE Handler    ] -> [0x776e6a20]      

After dumping the address "0x0096fbf0" we get:

1
2
3
4
5
6
7
8
9
0:000> d 0x0096fbf0
0096fbf0  ff ff ff ff 20 6a e6 77-5e 55 f0 44 00 00 00 00  .... j.w^U.D....
0096fc00  10 fc 96 00 de 36 e5 77-00 00 00 00 00 00 00 00  .....6.w........
0096fc10  20 fc 96 00 8c 36 e5 77-00 00 00 00 6e 1a d6 bb   ....6.w....n...
0096fc20  00 00 00 00 00 00 00 00-34 fc 96 00 00 00 df 77  ........4......w
0096fc30  00 00 00 00 3f 00 01 00-00 00 00 00 00 00 00 00  ....?...........
0096fc40  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0096fc50  7f 02 00 00 00 00 00 00-ff ff 00 00 00 00 00 00  ................
0096fc60  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ...............

This now brings us to the end of the chain as we see "0xffffffff".

Now our chain looks like:

1
2
3
 [TEB] -> [0096f938]
     |-> [ Next SEH Record ] -> [0x0096fb98] |---------> [ Next SEH Record ] -> [0x0096fbf0] |---------> [END OF CHAIN] -> [0xffffffff]
      [   SE Handler    ] -> [0x776e6a20]    [   SE Handler    ] -> [0x776e6a20]       [ SE Handler ] -> [0x776e6a20]

Now that I have a better understanding of what SEH is and its structure, time to move on to the next post where I learn to exploit these.

References:
https://www.corelan.be/index.php/2009/07/25/writing-buffer-overflow-exploits-a-quick-and-basic-tutorial-part-3-seh/
https://en.wikipedia.org/wiki/Win32_Thread_Information_Block
http://www.openrce.org/articles/full_view/21
https://www.tortall.net/projects/yasm/manual/html/objfmt-win64-exception.html
https://www.microsoft.com/msj/0197/Exception/Exception.aspx

No comments:

Post a Comment