2024年9月

基于
electron32+vue3 setup+pinia2
桌面端os管理解决方案
ElectronVue3OS

vue3-electron32-os
全新原创
Electron32+Vite5+Vue3+Pinia2+ArcoDesign+Echarts+Swiper
搭建桌面版os管理模板。内置
macos+windows
两种桌面布局风格、
自研可拖拽式栅格布局模板引擎、支持JSON动态配置桌面菜单/Dock菜单

技术栈

  • 编辑器:vscode
  • 技术框架:vite^5.4.1+vue^3.4.37+vue-router^4.4.3
  • 跨平台框架:electron^32.0.1
  • 组件库:@arco-design/web-vue^2.56.0 (字节前端vue3组件库)
  • 状态插件:pinia^2.2.2
  • 拖拽插件:sortablejs^1.15.2
  • 图表组件:echarts^5.5.1
  • markdown编辑器:md-editor-v3^4.19.2
  • 模拟数据:mockjs^1.1.0
  • 打包构建:electron-builder^24.13.3
  • electron+vite插件:vite-plugin-electron^0.28.7

项目特色

  1. Electron32封装高性能多开窗口管理
  2. 支持macos/windows两种桌面模板风格
  3. 支持动态json配置桌面菜单和Dock菜单
  4. 自研栅格化拖拽布局引擎
  5. 支持自定义桌面主题壁纸、全场景高斯模糊UI质感
  6. 支持主窗口和新开窗口打开路由页面

项目框架结构

electron-vite-macos使用
vite5.x
整合
electron32
搭建项目框架模板,遵循
Vue3 setup
语法糖编码风格。

目前Electron32-Vue3-Macos桌面端os系统已经同步到我的原创作品集。

https://gf.bilibili.com/item/detail/1106958011

入口配置main.js

/**
* 渲染进程配置入口main.js
* @author andy
*/import { createApp } from'vue'import'./style.scss'import App from'./App.vue'import { launchApp } from'@/windows/actions' //引入路由及状态管理 import Router from './router'import Pinia from'./pinia' //引入插件 import Plugins from './plugins'launchApp().then(config=>{if(config) {//全局窗口配置 window.config =config
}
//初始化app实例 createApp(App)
.use(Router)
.use(Pinia)
.use(Plugins)
.mount(
'#app')
})

electron-os桌面布局结构

内置提供了macos和windows两种风格桌面模板。

<!--桌面模板-->

<scriptsetup>import { appState } from'@/pinia/modules/app'

  //引入布局模板
import MacosLayout from'./template/macos.vue'import WindowsLayout from'./template/windows.vue'const appstate=appState()

const DeskLayout
={
macos: MacosLayout,
windows: WindowsLayout
}
</script> <template> <divclass="vu__container":style="{'--themeSkin': appstate.config.skin}"> <component:is="DeskLayout[appstate.config.layout]" /> </div> </template>

<scriptsetup>import Wintool from'@/layouts/components/wintool/index.vue'import Desk from'@/layouts/components/mac/desk.vue'import Dock from'@/layouts/components/mac/dock.vue'
</script>

<template>
  <divclass="vu__layout flexbox flex-col">
    <divclass="vu__layout-header">
      <Wintool/>
    </div>
    <divclass="vu__layout-body flex1 flexbox">
      <Desk/>
    </div>
    <divclass="vu__layout-footer">
      <Dock/>
    </div>
  </div>
</template>

electron-os桌面栅格模板

桌面图标自定义变量

const deskGridVariable =ref({'--icon-radius': '10px', //圆角
  '--icon-size': '60px', //图标尺寸
  '--icon-gap-col': '30px', //水平间距
  '--icon-gap-row': '30px', //垂直间距
  '--icon-labelSize': '12px', //标签文字大小
  '--icon-labelColor': '#fff', //标签颜色
  '--icon-fit': 'contain', //图标自适应模式
})

自定义桌面json配置项

/**
* label 图标标签
* imgico 图标(本地或网络图片) 支持Arco Design内置图标或自定义iconfont字体图标
* path 跳转路由地址
* link 跳转外部链接
* hideLabel 是否隐藏图标标签
* background 自定义图标背景色
* color 自定义图标颜色
* size 栅格布局(16种) 1x1 1x2 1x3 1x4、2x1 2x2 2x3 2x4、3x1 3x2 3x3 3x4、4x1 4x2 4x3 4x4
* onClick 点击图标回调函数
* children 二级菜单配置
* isNewin 新窗口打开路由页面
*/

桌面菜单JSON配置

const deskMenu =[
{
uid:
'd137f210-507e-7e8e-1950-9deefac27e48',
list: [
{imgico: markRaw(Today), size:
'2x2'},
{label:
'日历', imgico: markRaw(Calendar3x3), size: '3x3'},
{label:
'Electron32', imgico: '/electron.svg', link: 'https://www.electronjs.org/'},//... ]
},
{
uid:
'g270f210-207e-6e8e-2650-9deefac27e48',
list: [
{label:
'Appstore', imgico: '/static/mac/appstore.png'},//... ]
},
{
uid:
't165f210-607e-4e8e-9950-9deefac27e48',
list: [
{label:
'Vue.js', imgico: '/vue.svg', link: 'https://vuejs.org/',},
{label:
'Vite.js官方文档', imgico: '/vite.svg', link: 'https://vitejs.dev/',},//... ]
},
{
uid:
'u327f210-207e-1e8e-9950-9deefac27e48',
list: [
{label:
'Electron32', imgico: '/electron.svg', link: 'https://www.electronjs.org/'},
{label:
'首页', imgico: markRaw(IconHome), path: '/home', color: '#fff', isNewin: true},
{label:
'工作台', imgico: 'elec-icon-dotchart', path: '/home/dashboard', color: '#fff'},//... {
label:
'用户中心',
children: [
{label:
'主页', imgico: '/static/svg/ucenter.svg', path: '/setting'},
{label:
'用户管理', imgico: markRaw(IconUserGroup), path: '/user', color: '#fff'},//... ]
},
{
label:
'设置',
children: [
//... ]
},
{
label:
'收藏网址',
children: [
{label:
'Electron32', imgico: '/electron.svg', link: 'https://www.electronjs.org/'},
{label:
'Vite.js', imgico: '/vite.svg',},//... ]
},
{
label:
'公众号', imgico: '/static/qrimg.png', color: '#07c160',
onClick: ()
=>{
Modal.info({
//... })
}
},
]
}
]

electron32+vue3实现Dock菜单

dock菜单支持如下参数配置

/**
* label 图标tooltip提示
* imgico 图标(本地或网络图片) 支持Arco Design内置图标或自定义iconfont图标
* path 跳转路由页面
* link 跳转外部链接
* color 自定义图标颜色
* onClick 点击图标回调函数
* children 二级菜单
* isNewin 是否新窗口打开路由页面
*/

OK,以上就是electron32+vue3实战开发桌面端os系统的一些知识分享,希望对大家有所帮助哈~

Electron打包下载卡顿问题

electron打包进度卡住,下载停滞不前,设置electron淘宝镜像源依然无效,可以尝试下面方法。
直接去
https://registry.npmmirror.com/binary.html
下载相关文件。

下载对应的electron版本文件。

直接将下载的electron打包文件放到C盘下
C:\Users\andy\AppData\Local\electron\Cache

通过手动下载打包文件,electron打包时就跳过下载步骤,很快就能打包成功了。

vite.config.js配置@/无路径提示解决方法

安装如下方式配置vscode的@路径提示

  1. vscode安装Path Intellisense插件
  2. 点击左下角齿轮,点击设置
  3. 点击右上角这个图标

配置如下代码

"path-intellisense.mappings": {"@": "${workspaceFolder}/src"}

保存退出,@/就会有路径提示了。

最后附上两个最新Electron+Vite5实例项目

https://www.cnblogs.com/xiaoyan2017/p/18290962

https://www.cnblogs.com/xiaoyan2017/p/18366451

本文书接上回《
主观与客观,破除DDD凭经验魔咒
》,关注公众号(老肖想当外语大佬)获取信息:

  1. 最新文章更新;

  2. DDD框架源码(.NET、Java双平台);

  3. 加群畅聊,建模分析、技术实现交流;

  4. 视频和直播在B站。

开个玩笑

“我不是针对这一个问题,我是说所有的反DDD模式都是垃圾”,作为教练,在团队中我时常用这样的玩笑来调侃不符合DDD价值观的判断逻辑和决策结果,并指出具体不符合的点在哪里,由于大家已经相互非常了解,能够很快反应过来并建立共识,从而不断修正决策逻辑和决策结果,使问题的范围和解决方案收敛在一个确定的范围内,持续地保持对系统复杂度的掌控。

===

前提条件

首先需要对齐我们讨论的场景,主要在下面的条件范围内:

  1. 软件系统是长期迭代的

  2. 软件系统是业务向的系统

在这个条件范围下,我们可以解读为:

  1. 我们认为迭代成本是软件成本的重要组成部分

  2. 我们认为自己打造的软件系统的业务复杂度高于技术复杂度

成本与复杂度

为了尽可能降低系统迭代的综合成本,本质上就是掌控系统复杂度,而系统复杂度由业务复杂度和技术复杂度共同构成。

为了实现“掌控系统复杂度”的目标,基于复杂度守恒定律,我们有以下观点:

  1. 复杂度不可被消除,只可被转移

  2. 尊重业务固有复杂度

  3. 避免引入额外技术复杂度

而我们在《
关于领域驱动设计,大家都理解错了
》一文推导过关于复杂度的结论:

  1. 系统复杂度与元素的数量和元素的关系有关;

  2. 元素的关系对系统复杂度的影响远远大于元素的数量所产生的影响;

===

核心观点

如果你已经跟随《
老肖的领域驱动设计之路
》系列一路读过来,那么我们接下来的推导过程就需要在之前构建的认知基础上进行,这里列出核心观点以供复习:

  1. 领域驱动设计是一种价值观

  2. DDD价值观:边界明确是最重要的事

  3. 软件长期主义:可维护性是最重要的事

  4. DDD是软件工程的第一性原理

基于上面这些观点,DDD的核心,就是掌控系统元素之间的关系,明确边界,将复杂度控制在一个个有限的范围内,完全匹配软件工程的成本控制的逻辑,那么是不是就可以得出下面的结论:

  1. 符合DDD价值观,意味着符合软件工程的成本利益

  2. 反DDD的模式,意味着不符合软件工程的成本利益

那么回到本文的标题,“所有反DDD模式都是垃圾”,更准确的描述应该是“所有反DDD模式都是不符合软件工程成本利益的”,我认为,这个逻辑是成立的。

如果你认同《
DDD是软件工程的第一性原理?
》一文的观点,那么同样也能得出这样的结论,违反软件工程第一性原理,当然会适得其反,走向系统快速失控的深渊。

所以,很抱歉,如果你的软件设计思维,没有围绕着“明确和维护边界”来开展,那么大概率是错误的价值判断思路,系统的复杂度大概率也很难被掌控,而具象化出来的现象,就是我们常说的“迭代不动了”。

那么,快来和我一起实践DDD吧!

大家好,我是Edison。

在这个已经被AI大模型包围的时代,不了解一点大模型的基础知识和相关概念,可能出去聊天都接不上话。刚好近期我也一直在用GPT和GitHub Copilot,也刚好对这些基础知识很感兴趣,于是学习了一下,做了如下的整理总结,分享与你!

一句话描述GPT

GPT:
Generative Pre-Training Transformer,
即三个关键词:
生成式
预训练
变换模型

GPT模型通过在大量数据上
学习
到的
语言模式
,预测下一个
字(token)
,生成自然语言文本。

大模型的6大关键技术

大模型

类似于人类的大脑,通过思考和规划来完成任务;

Prompt(提示词工程)

类似于人类的沟通,上级通过布置任务来让下级完成一项任务;

RAG(检索增强生成)

类似于人类想要暂时完成一件任务,但是这件任务暂时不会做。例如马上要大学期末考试了,我们需要临时抱佛脚突击一周,以求得考试及格分数,但是考完试以后,这些知识就忘得一干二净了。或者说类似于大学期末的开卷考试,反正知识点都在书里,你平时都没学过,得先找一找,找到了就把相关答案写在试卷上,考完了还是忘得一干二净,但是你的目标达到了:考试及格60分万岁!

Fine-tunig(微调)

类似于人类想要彻底学会一个技能,例如想要学会大模型的技术,我们需要通过系统的培训以及通过实战去真正的掌握大模型技术。

Function Calling(函数调用)

类似于人类使用工具完成一件任务,例如想要查询成都的天气情况,我们要么直接打开天气预报的App,要么直接在百度上搜索,总之是通过工具来完成这件事。

Agent

类似于人类通过沟通、分工和协作来完成一件复杂的任务,通常会结合使用到上面提到的五个技术来完成任务,而且大模型时代的Agent也不是单兵作战而是多个Agent之间合作来完成任务。例如想要开发一个客服项目,需要产品经理Agent、架构师Agent、开发者Agent、测试者Agent、运维Agent 和 项目管理Agent 像人类一样去沟通协作,最后才能把这个项目自动地完成。

知识问答的3种主要方式

大模型直答

最常见的方式:直接向LLM提问,LLM给出回答。

大模型微调(Fine-Tuning)

首先,将企业私有知识加给通用大模型进行微调形成私有大模型;然后,再将问题给到私有大模型进行回答。

大模型RAG(检索增强生成)

首先,对企业的知识库进行检索得到相关的知识片段;然后,将知识片段和原问题组合成新的提示词发给通用大模型得到回答;

3种方式的效果对比:

总结:在企业落地知识问答库时,如果为了追求成本和回答准确度,
推荐使用RAG方案

AI Agent到底是什么?

在产品层面:
AI Agent是AGI时代新的应用形态

这其实是应用形态的演进:在AGI时代之前是移动互联网时代,它的产品形态是APP。

在进入AGI时代后,产品形态变为了AI Agent。未来现有的部分高级程序员写的应用就不再会是App,而是AI Agent了!

在技术层面:
面向过程架构 → 面向目标架构 的转变
(软件架构的范式迁移)

比如,在App时代写一个用户系统,需要把整个用户从注册到登录再到回放,一步一步地把整个流程结合if-else把它开发出来。这个生成的过程我们叫做面向过程的架构,需要预定义指令、逻辑和规则。

但是,在AI Agent时代,很多情况下不需要把这些指令一个一个地指出来,只需要一句话就行了,比如说提供一个prompt“请帮我完成一个用户系统,它包含用户注册、登录、查询等功能”,然后大模型就会帮你去完成。这个生成的过程我们叫做面向目标的架构,具有目标导向和动态规划的特点,由AI Agent自主生成。

大模型和Agent有啥区别?

Agent会在大模型的推理结果基础之上,
使用一些工具
(如调用API)完成某个特定的任务,这个技术也被称为Function Calling(函数调用)。

当下大模型的参数量提升AI Agent的理解力和泛化能力,使其能够更好地处理多种任务和上下文信息,这增强了AI代理的自然语言处理能力,从而提供更加个性化、连贯的交互体验,是当下Agent的构建关键!

总结:大模型时代下的
AI Agent = LLM × (规划+记忆+工具+行动)

AI Agent的应用场景
通常与特定任务或环境紧密相关
。例如,在智能家居系统中,AI Agent可以根据用户的生活习惯和偏好自动调节家庭设备的运行状态。在游戏中,AI Agent能够提供具有挑战性的对手或复杂的游戏环境动态。

Agent架构的核心流程

Agent架构有三个重要的模块:
规划模块(Planning)、执行模块(Action) 和 观察模块(Observation)
,如下图所示:

举个例子,假设我们有一个prompt“请用python画一个圆心”。

首先,在规划模块,Agent会将这个需求拆解为三个子项:写Python代码、调用IPython解释器、调用Docker运行环境;

其次,在执行模块,Agent会分别执行拆解的事项,也就是去调用各种工具;

最后,在观察模块,Agent会对每一步的执行结果做观测,如果check完毕没问题,就给到用户最终的答案。如果觉得有问题,比如执行的过程中出现了Timeout之类的错误,就会做一些Retry的操作。如果Retry次数超过了最大重试次数,这时候就可能会把这个进程Kill掉,然后重新进入规划模块重新规划。

在这三个模块或者说能力中,最重要的当属
规划
模块!

大模型和程序员的关系

目前ChatGPT对程序员到底有哪些实质性的帮助?

第一点:Code Review

ChatGPT能够理解代码,并针对代码给出针对性的建议和优化方案;

第二点:写测试用例、单元测试、集成测试等,这些ChatGPT都很擅长!

第三点:对线上问题的定位和分析

线上问题的各种疑难杂症,ChatGPT都能胜任!

第四点:SQL的翻译

实现两种数据库的SQL语言转换,比如将Oracle的SQL脚本转换成MySQL的SQL脚本。

有了AI编程,还需要程序员吗?

第一,在冯诺依曼架构体系下,程序需要的是
确定性计算

第二,由于大模型本身的概率性,目前大模型生成的代码还具备
一定的随意性和不确定性

第三,目前大模型更擅长的是一些
抽象层次比较低
的工作,比如一段代码或一个算法的实现,写一个单元测试等等。而一些抽象层次比较高的工作,比如需求分析、架构设计、领域设计、架构选型等,这些工作反而是大模型不擅长的,而这些工作是比较具备有竞争力的,这恰恰是一些高级程序员以及系统架构师的价值所在。

应用实践AIGC有几层境界?

第一层境界:简单对话;

通过ctrl-c/v出结果,人人都会。

第二层境界:系统掌握Prompt Engineering;

通过系统掌握好提示词工程,真正赋能工作提效。

目前,Edison还处于这一层。

第三层境界:将AIGC融入业务流程,指挥AIGC完成复杂的任务;

通过掌握AIGC的技能,并完成业务领域知识的深入结合。

第四层境界:拥有自己的大模型;

熟悉大模型的架构原理,通过开源大模型微调,最好能够拥有一定的行业数据壁垒。

第五层境界:参与设计训练大模型;

比如从事ChatGPT等研发工作。

如何掌握AI大模型开发技能?

第一步:掌握开发AGI时代新应用程序的技能;

比如:大模型应用内核、LangChain开发框架、向量数据库等;

第二步:搞定开发企业级AI Agent的应用技能;

比如:AI Agent、大模型缓存、算力等;

第三步:驾驭开发企业级专有大模型的技能;

比如:RAG、微调等;

第四步:深入应用大模型技术成为开发大师;

比如:大模型预训练、LLMOps等;

小结

大模型应用开发学习实践之路漫漫,我们IT开发者也会逐渐从Application的开发转向Agent的开发的范式的转变,一起加油吧!

参考资料

玄姐聊AGI:
https://space.bilibili.com/412720389
(推荐观看玄姐的视频)

甲子光年,《2024年AI Agent行业报告》

LoRA模型是小型的Stable Diffusion模型,它们对checkpoint模型进行微小的调整。它们的体积通常是检查点模型的10到100分之一。因为体积小,效果好,所以lora模型的使用程度比较高。

这是一篇面向从未使用过LoRA模型的初学者的教程。你将了解LoRA模型是什么,在哪里找到它们,以及如何在AUTOMATIC1111 GUI中使用它们。然后,你将在文章末尾找到一些LoRA模型的演示。

LoRA模型是什么?

LoRA(Low-Rank Adaptation)是一种微调Stable Diffusion模型的训练技术。

虽然我们已经有像Dreambooth和文本反转这样的训练技术。那么LoRA有什么用呢?

LoRA实际上可以看做是Dreambooth和文本反转embeddings的折中方案。Dreambooth功能虽然强大,但模型文件会比较大(2-7 GB)。文本反转非常小(约100 KB),但能做的事情比较少。

LoRA介于两者之间。它的文件大小更容易管理(2-200 MB),并且训练能力相当不错。

因为checkpoint比较大,所以硬盘空间存储会是一个问题。而LoRA是解决存储问题的优秀方案。

像文本反转一样,
你不能单独使用LoRA模型
。它必须与模型检查点文件一起使用。LoRA通过对配套的模型文件进行小的修改来改变风格。

LoRA是定制AI艺术模型的绝佳方式,而不会占用太多本地存储空间。

LoRA如何工作?

LoRA对Stable Diffusion模型中最关键的部分进行小的修改:
交叉注意力层
。研究人员发现,微调这部分模型就足以实现良好的训练。交叉注意力层是下面Stable Diffusion模型架构中的黄色部分。

交叉注意力层

交叉注意力层的权重以
矩阵
的形式排列。矩阵只是按列和行排列的一堆数字,就像Excel电子表格上一样。LoRA模型通过将自己的权重加到这些矩阵上来微调模型。

如果LoRA模型需要存储相同数量的权重,它们的文件怎么会更小呢?
LoRA的技巧是将矩阵分解成两个更小的(低秩)矩阵。
通过这样做,它可以存储更少的数字。让我们通过以下示例来说明。

假设模型有一个100行100列的矩阵。那是10000个数字(100x 100)需要存储在模型文件中。LoRA将矩阵分解成一个1000x2矩阵和一个2x100矩阵。那只有400个数字(100 x 2 + 2 x 100,如果矩阵够更大的话,LoRA模型会减少的更多。这就是为什么LoRA文件要小得多的原因。

image-20240703105705024

在这个例子中,矩阵的

是2。它比原始尺寸低得多,所以它们被称为
低秩矩阵
。秩可以低至1。

这种操作必定会带来数据上的缺失,但是在交叉注意力层来说,这些损失是无伤大雅的。所以Lora这种做法是可行的。

在哪里找到LoRA模型?

Civitai

image-20240703110017448

寻找LoRA的首选地点是Civitai。该网站托管了大量LoRA模型的集合。应用LORA过滤器以仅查看LoRA模型。不过里面的大多数模型都是:女性肖像,动漫,现实主义插图风格等。

Hugging Face

image-20240703110326192

Hugging Face是另一个LoRA库的好来源。你会发现更多种类的LoRA模型。但那里的LoRA模型可能没有C站多,并且也不太直观。因为没有图片预览。

如何使用LoRA?

这里,我将介绍如何在AUTOMATIC1111 Stable Diffusion GUI中使用LoRA模型。

AUTOMATIC1111原生支持LoRA。你不需要安装任何扩展。

第1步:安装LoRA模型

要在AUTOMATIC1111 webui中安装LoRA模型,请将模型文件放入以下文件夹。

stable-diffusion-webui/models/Lora

第2步:在提示中使用LoRA

要在AUTOMATIC1111 Stable Diffusion WebUI中添加带权重的LoRA,请在提示或否定提示中使用以下语法:

<lora: name: weight>

name
是LoRA模型的名称。它可以与文件名不同。
weight
是应用于LoRA模型的权重。默认值为1。将其设置为0将禁用模型。

那么怎么知道lora的名字是什么呢?

其实我们并不需要手动输入lora的名字,我们只需要点击下面的lora标签:

image-20240703111227834

你应该看到一个已安装的LoRA模型列表。单击你想要使用的模型。

LoRA短语将被插入到提示中。

就是这样!

使用LoRA的注意事项

你可以
调整乘数
以增强或调整效果。将乘数设置为0将禁用LoRA模型。你可以在0和1之间调整风格效果。

一些LoRA模型是使用Dreambooth训练的。你需要包括一个
触发关键词
才能使用LoRA模型。你可以在模型页面上找到触发关键词。

类似于嵌入,你可以同时使用
多个LoRA模型
。你也可以将它们与嵌入一起使用。

在AUTOMATIC1111中,LoRA短语不是提示的一部分。在应用LoRA模型后,它将被删除。这意味着你不能使用像[keyword1:keyword2: 0.8]这样的提示语法来使用他们。

实用的LoRA模型

这里介绍一些在实际应用中比较实用的Lora。

add_detail

image-20240703112744179

谁不想要AI图像中更多的细节?细节调整器允许你增加或减少图像中的细节。现在,你可以调整你想要的细节量。

使用正LoRA权重来增加细节,使用负权重来减少细节。

add_saturation

这个lora可以给图片添加一些饱和度,效果如下:

image-20240703113008727

add_brightness

这个lora可以用来控制图片的亮度:

image-20240703134833039

总结

LoRA模型是checkpoint模型的小型修改器。你可以通过在提示中包含一个短语轻松地在AUTOMATIC1111中使用它们。

我将在以后的文章中告诉你如何自己来训练一个LoRA模型。

点我查看更多精彩内容:www.flydean.com

80后用菜刀,90后用蚁剑,95后用冰蝎和哥斯拉,以phpshell连接为例,本文主要是对这四款经典的webshell管理工具进行流量分析和检测。

什么是一句话木马?

1、定义
顾名思义就是执行恶意指令的木马,通过技术手段上传到指定服务器并可以正常访问,将我们需要服务器执行的命令上传并执行
2、特点
短小精悍,功能强大,隐蔽性非常好
3、
举例
php一句话木马用php语言编写的,运行在php环境中的php文件,例:
<?php @eval($_POST['pass']);?>
4、原理
以最为常见的php一句话木马为例,"
<?php ?>
"为php固定规范写法,"
@
"在php中含义为后面如果执行错误不会报错,"
eval()
"函数表示括号里的语句全做代码执行,"
$_POST['pass']
"表示从页面中以
post方式
获取变量pass的值

三、冰蝎

1、Behinder v2.0

(1)实现原理

①首次连接webshell时,客户端首先向服务器端发起一个GET请求

②服务器端随机产生一个
16位
的密钥,把密钥回显给客户端,同时把密钥写进服务器侧的Session中

③客户端获取密钥后,对二进制payload先进行
AES加密
(本地openssl模块),再通过POST方式发送至服务器端

④服务器收到数据后,从Session中取出密钥,进行AES解密,解密之后得到二进制payload数据

⑤服务器解析二进制payload文件,执行任意代码,并将执行结果加密返回

客户端解密服务器端返回的结果

(2)代码分析

冰蝎的通信过程可以分为两个阶段:
密钥协商

加密传输
第一阶段-密钥协商


通过 GET 或者 POST 方法,请求服务器密钥


服务端使用随机数MD5的高16位作为密钥


并且存储到会话的$_SESSION变量中


返回密钥给攻击者

第二阶段-加密传输


客户端把待执行命令作为输入,利用 AES 算法进行加密,并发送至服务端


服务端接受密文后进行 AES 运算解密,执行相应的命令


执行结果通过AES加密后返回给攻击者

(3)数据包分析

第一阶段-密钥协商

冰蝎为了实现可以在webshell内添加任意内容 (比如gif89a子类的文件头或者其它标示字符) 冰蝎在初始化密钥时会对webshell进行两次访问,然后比较两次页面返回的差异,把两次请求都相同的字符记录一个位置,后续加密会用到这两个位置(beginIndex,endIndex)

第二阶段-加密传输

使用密钥进行AES解密信息如下:

(4)流量特征

1、Accept字段

冰蝎默认 Accept 字段的值很特殊,这个特征存在于冰蝎的任何一个通讯阶段

2、UserAgent字段

冰蝎内置了17种 UserAgent ,每次连接 shell 会随机选择一个进行使用

3、长连接和Content-Length

冰蝎通讯默认使用长连接,避免了频繁的握手造成的资源开销。默认情况下,请求头和响应头里会带有
Connection: Keep-Alive
Content-Length: 16
##

16就是冰蝎2连接的特征

四、
密钥传递时URL参数


密钥传递时,URI只有一个
key-value
型参数

Key是黑客给shell设置的密码,一般为10位以下字母和数字

Value一般是2至3位随机纯数字

webshell的扩展名一般为可执行脚本

五、
传递的密钥


加密所用密钥是长度为16的随机字符串,小写字母+数字组成

密钥传递阶段,密钥存在于Response Body中

2、Behinder v3.0

(1)代码分析


相比于冰蝎2,冰蝎3取消了动态密钥获取

密钥使用的是连接密码的MD5值的前16位,并存储于Session中

(2)数据包分析

Request请求包

Response响应包

(3)流量特征

1、
Accept字段

头部特征:application/xhtml+xml,application/xml,application/signed-exchange

2、
UserAgent字段

最新版本冰蝎内置了14种 UserAgent ,每次连接 shell 会随机选择一个进行使用

(4)检测规则

alert:记录所有匹配的规则并记录与匹配规则相关的数据包,生成一个警告

msg:规则名称,规则中的第一个字段,ids告警上显示的信息

flow: 特定时间内具有相同数据的数据包(5元组信息)同属于一个流

content:检测数据包中是否存在此内容

pcre:正则表达式

flowbits:可以确保例如两个不同的数据包同时匹配时会生成警报

classtype类别:根据规则检测到的活动类型为规则分类

sid特征标示符:用于唯一性规则标识,sid不能重复

alert http any any -> any any(msg:"MALWARE-BACKDOOR Behinder webshell online detected"; flow:established,to_client; pcre: "/\r\n\r\n[A-Za-z0-9]{16}$/"; content:"200 OK"; content: "Content-Length: 16"; fast_pattern;nocase; flowbits: set, bx_first_get_resp; noalert; classtype:web-attack;sid:3000021; rev:1; metadata:created_at 2019_11_20, updated_at 2019_11_20;)
alert http any any
-> any any(msg:"MALWARE-BACKDOOR Behinder webshell online detected"; flow:established,to_server; content:"GET"; http_method; pcre:"/\.(php|jsp|asp|jspx|aspx)\?\w{1,8}=\d{1,10} HTTP/1\.1/";flowbits:isset, bx_first_get_resp; flowbits:set, bx_second_get_req; noalert;classtype:web-attack; sid:3000022; rev:1; metadata:created_at 2019_11_20,updated_at 2019_11_20;)
alert http any any
-> any any(msg:"MALWARE-BACKDOOR Behinder webshell online detected"; flow:established,to_client; pcre: "/\r\n\r\n[A-Za-z0-9]{16}$/"; content:"Content-Length: 16"; fast_pattern; nocase; flowbits: isset,bx_second_get_req; flowbits:set, bx_second_get_resp; noalert;classtype:web-attack; sid:3000023; rev:1; metadata:created_at 2019_11_20,updated_at 2019_11_20;)
alert http any any
-> any any(msg:"MALWARE-BACKDOOR Behinder webshell online detected"; flow:established,to_server; content:"POST"; http_method; pcre:"/\.(php|jsp|asp|jspx|aspx) HTTP/1\.1/"; flowbits:isset, bx_second_get_resp;flowbits:set, bx_first_post_req; noalert; classtype:web-attack; sid:3000024;rev:1; metadata:created_at 2019_11_20, updated_at 2019_11_20;)
alert http any any
-> any any(msg:"MALWARE-BACKDOOR Behinder webshell online detected"; flow:established,to_client; pcre: "/[^\w\s><=\-'"\:\;\,\!\(\)\{\}][\w]{2}[^\w\s><=\-'"\.\:\;\,\!\(\)\{\}][a-zA-Z\d]{2}/";content: "200 OK"; content: "Content-Type: text/html";flowbits: isset, bx_first_post_req; classtype:web-attack; sid:3000025; rev:1;metadata:created_at 2019_11_20, updated_at 2019_11_20;) alert http any any -> any any(msg:"MALWARE-BACKDOOR Behinder webshell-jspx online"; flow:established,to_server; pcre:"/\r\n\r\n[a-zA-Z\d\+\/]{10,}\/[a-zA-Z\d\/]{50}/"; content:"Content-Type: application/octet-stream"; fast_pattern; flowbits:isset, bx_second_get_resp; flowbits: set, bx_req_jspx; noalert;classtype:web-attack; sid:3000026; rev:1; metadata:created_at 2019_11_20,updated_at 2019_11_20;)
alert http any any
-> any any(msg:"MALWARE-BACKDOOR Behinder webshell-jspx online"; flow:established,to_client; pcre:"/[^\w\s><=\-'"\:\;\,\!\(\)\{\}][\w]{2}[^\w\s><=\-'"\.\:\;\,\!\(\)\{\}][a-zA-Z\d]{2}/";content: "200 OK"; content: "Content-Type: text/xml";fast_pattern; flowbits: isset, bx_req_jspx; classtype:web-attack; sid:3000027;rev:1; metadata:created_at 2019_11_20, updated_at 2019_11_20;)