网站首页 关于作者 Bee 的所有文章

  • Bash脚本编程入门

    Shell 是 Linux 的核心部分,它允许你使用各种诸如 cd、ls、cat等的命令与 Linux 内核进行交互。 Bash 是 Linux 上众多可用的 Shell 中的一个。这些 Shell 主要的语法基本相同,但并非完全一样。Bash 是目前最受欢迎的 Shell,并在大多数 Linux 发行版中被设为默认 Shell。 当你打开一个终端或 SSH 会话时,即使你无法真切地看到它,你其实已经在运行着一个 Shell。 当你输入一个命令,它会被 Shell 解释。如果命令和语法是正确的,它就会被执行,否则你会看到一个错误。 当你可以直接运行 Linux 命令时,为什么还需要 Bash 脚本? 你可以直接在终端输入命令,它们就会被执行。 $ echo "hello world" hello world 并且,同样的操作也可以在脚本中进行: $ cat >> script.sh #!/bin/bash echo "hello world" $ bash script.sh hello world 那么,为什么我们需要 Shell 脚本呢?因为你不必一遍又一遍地输入同一个命令,你只需运行 Shell 脚本即可。 此外,如果你的脚本中有复杂的逻辑,把所有的命令都输入到终端中可能并不是一个好主意。 例如,如果你输入下面的命令,它会奏效,但这并不容易理解。不断地输入相同的命令(甚至要在 Bash 历史记录中搜索)会造成困扰。 if [ $(whoami) = 'root' ]; then echo "root"; else echo "not root"; fi 相反,你可以把命令放进 shell 脚本中,这样就更容易理解并且可以轻松运行了: #!/bin/bash if [ $(whoami) = 'root' ]; then echo "You are root" else echo "You are not root" fi 这还是比较简单的情况。尝试想象一下,一个复杂的脚本可能有五十行或一百行! 你将会学到什么? 在这个 Bash 脚本教程中,有九个部分。你将会学到: 创建并运行你的第一个 Bash Shell 脚本 使用变量 在你的 Bash 脚本中传递参数和接受用户输入 进行数学计算 操作字符串 使用条件语句,例如 if-else 使用 for、while和until循环 创建函数 ? 所有的部分都会给你一个简单的例子。如果你愿意,你可以通过访问每个部分的详细章节来更深入地学习。这些章节也都包含了实践练习。 这个教程的目标读者是谁? 这个教程适合任何想要开始学习 Bash Shell 脚本的人。 如果你是一名学生,而你的课程里包括了 Shell 脚本,那么这个系列就是为你准备的。 如果你是一个常规的桌面 Linux 用户,这个系列将会帮助你理解在探索各种软件和修复问题时遇到的大多数 Shell 脚本。你也可以使用它来自动化一些常见的、重复的任务。 在这个 Bash 脚本教程结束时,你应该可以编写简单的 Bash 脚本。 ? 希望你已经拥有 Linux 命令行和编程语言的基础知识。 如果你对 Linux 命令行完全不熟悉,我建议你先掌握基础知识。 19 个你应该知道的基础而重要的 Linux 终端技巧 你应该了解如何在命令行中进入特定的位置。为了做到这一点,你需要理解 Linux 文件系统中的路径是如何工作的。 Linux 中的绝对路径和相对路径有什么不同 接下来,这个教程系列会给你介绍目录导航和文件操作的基本知识。 终端基础:Linux 终端入门 1、编写你的第一个 Bash Shell 脚本 创建一个名为 hello.sh的新文件: nano hello.sh 这将在终端中打开 nano 编辑器。在其中输入以下几行代码: #!/bin/bash echo "Hello World" 通过按 Ctrl+X键可以保存并退出 nano 编辑器。 现在,你可以以以下方式运行 Bash Shell 脚本: bash hello.sh 你应该可以看到以下的输出: Hello World 另一种方式是首先赋予脚本执行权限: chmod u+x hello.sh 然后这样运行它: ./hello.sh ? 你也可以使用基于图形用户界面的文本编辑器来编写脚本。这可能更适合编写较长的脚本。然而,你需要切换到保存脚本的目录中才能运行它。 恭喜!你刚刚运行了你的第一个 Bash 脚本。 Bash 基础知识系列 #1:创建并运行你的第一个 Bash Shell 脚本 2、在 Bash 脚本中使用变量 变量的声明方式如下: var=some_value 然后可以像这样访问变量: $var ? 在声明变量时,等号(=)前后不能有空格。 我们通过添加一个变量来修改前面的脚本。 #!/bin/bash message="Hello World" echo $message 如果运行这个脚本,输出仍然会保持不变。 Hello World Bash 基础知识系列 #2:在 Bash 中使用变量 3、向 Bash 脚本传递参数 你可以在运行 Bash 脚本时以以下方式传递参数: ./my_script.sh arg1 arg2 在脚本中,你可以使用 $1来代表第 1 个参数,用$2来代表第 2 个参数,以此类推。$0是一个特殊变量,它代表正在运行的脚本的名字。 现在,创建一个新的 shell 脚本,命名为 arguments.sh,并向其中添加以下几行代码: #!/bin/bash echo "Script name is: $0" echo "First argument is: $1" echo "Second argument is: $2" 使其可执行并像这样运行它: $ ./argument.sh abhishek prakash Script name is: ./argument.sh First argument is: abhishek Second argument is: prakash 让我们快速看一下特殊变量: 特殊变量 描述 $0 脚本名称 $1、$2…$9 脚本参数 ${n} 10 到 255 的脚本参数 $# 参数数量 $@ 所有参数一起 $$ 当前 shell 的进程 id $! 最后执行命令的进程 id $? 最后执行命令的退出状态 你也可以通过接受键盘输入使你的 Bash 脚本变得交互式。 为此,你必须使用 read命令。你还可以使用read -p命令提示用户进行键盘输入,而不需要echo命令。 #!/bin/bash echo "What is your name, stranger?" read name read -p "What's your full name, $name? " full_name echo "Welcome, $full_name" 现在,如果你运行这个脚本,当系统提示你输入“参数”时,你必须输入。 $ ./argument.sh What is your name, stranger? abhishek What's your full name, abhishek? abhishek prakash Welcome, abhishek prakash Bash 基础知识系列 #3:传递参数和接受用户输入 4、执行算术运算 在 Bash Shell 中执行算术运算的语法是这样的: $((arithmetic_operation)) 下面是你可以在 Bash 中执行的算术运算的列表: 操作符 描述 + 加法 - 减法 * 乘法 / 整数除法(没有小数) % 模运算(只余) ** 指数(a 的 b 次方) 以下是在 Bash 脚本中进行加法和减法的示例: #!/bin/bash read -p "Enter first number: " num1 read -p "Enter second number: " num2 sum=$(($num1+$num2)) sub=$(($num1-$num2)) echo "The summation of $num1 and $num2 is $sum" echo "The substraction of $num2 from $num1 is $sub" 你可以执行 Shell 脚本,使用你选择的任意数字作为参数。 如果你尝试除法,会出现一个大问题。Bash 只使用整数。默认情况下,它没有小数的概念。因此,你会得到 10/3 的结果为3,而不是 3.333。 对于浮点数运算,你需要这样使用 bc命令: #!/bin/bash num1=50 num2=6 result=$(echo "$num1/$num2" | bc -l) echo "The result is $result" 这个时候,你将看到准确的结果。 The result is 8.33333333333333333333 Bash 基础知识系列 #4:算术运算 5、在 Bash 脚本中使用数组 你可以使用 Bash 中的数组来存储同一类别的值,而不是使用多个变量。 你可以像这样声明一个数组: distros=(Ubuntu Fedora SUSE "Arch Linux" Nix) 要访问一个元素,使用: ${array_name[N]} 像大多数其他的编程语言一样,数组的索引从 0 开始。 你可以像这样显示数组的所有元素: ${array[*]} 这样获取数组长度: ${#array_name[@]} Bash 基础知识系列 #5:在 Bash 中使用数组 6、Bash 中的基础字符串操作 Bash 能够执行许多字符串操作。 你可以使用这种方式获取字符串长度: ${#string} 连接两个字符串: str3=$str1$str2 提供子字符串的起始位置和长度来提取子字符串: ${string:$pos:$len} 这里有一个例子: 你也可以替换给定字符串的一部分: ${string/substr1/substr2} 并且你也可以从给定字符串中删除一个子字符串: ${string/substring} Bash 基础知识系列 #6:处理字符串操作 7、在 Bash 中使用条件语句 你可以通过使用 if或if-else语句为你的 Bash 脚本添加条件逻辑。这些语句以fi结束。 单个 if语句的语法是: if [ condition ]; then your code fi 注意使用 [ ... ];和then。 if-else语句的语法是: if [ expression ]; then ## execute this block if condition is true else go to next elif [ expression ]; then ## execute this block if condition is true else go to next else ## if none of the above conditions are true, execute this block fi 这里有一个使用 if-else语句的 Bash 脚本示例: #!/bin/bash read -p "Enter the number: " num mod=$(($num%2)) if [ $mod -eq 0 ]; then echo "Number $num is even" else echo "Number $num is odd" fi 运行它,你应该能看到这样的结果: -eq被称为测试条件或条件操作符。有许多这样的操作符可以给你不同类型的比较: 这些是你可以用来进行数值比较的测试条件操作符: 条件 当…时,等同于 true $a -lt $b $a ($a是小于$b) $a -gt $b $a > $b($a是大于$b) $a -le $b $a ($a是小于或等于$b) $a -ge $b $a >= $b($a是大于或等于$b) $a -eq $b $a == $b($a等于$b) $a -ne $b $a != $b($a不等于$b) 如果你在进行字符串比较,你可以使用以下这些测试条件: 条件 当…时,等同于 true "$a" = "$b" $a等同于$b "$a" == "$b" $a等同于$b "$a" != "$b" $a不同于$b -z "$a" $a是空的 还有些条件用于检查文件类型: 条件 当…时,等同于 true -f $a $a是一个文件 -d $a $a是一个目录 -L $a $a是一个链接 ? 要特别注意空格。开括号和闭括号、条件之间必须有空格。同样地,条件操作符(-le、==等)之前和之后必须有空格。 Bash 基础知识系列 #7:If-Else 语句 8、使用 Bash 脚本中的循环 Bash 支持三种类型的循环:for、while和until。 这是 for循环的一个例子: #!/bin/bash for num in {1..10}; do echo $num done 运行它,你将看到以下输出: 1 2 3 4 5 6 7 8 9 10 如果你选择使用上面的示例,可以使用 while循环这样重写: #!/bin/bash num=1 while [ $num -le 10 ]; do echo $num num=$(($num+1)) done 同样,可以使用 until循环来重写: #!/bin/bash num=1 until [ $num -gt 10 ]; do echo $num num=$(($num+1)) done ? while循环和until循环非常相似。区别在于:while循环在条件为真时运行,而until循环在条件为假时运行。 Bash 基础知识系列 #8:For、While 和 Until 循环 9、在 Bash 脚本中使用函数 Bash Shell 支持使用函数,这样你不必反复编写相同的代码片段。 这是声明 Bash 函数的通用语法: function_name { commands } 这是一个使用带参数的函数的 Bash 脚本样例: #!/bin/bash sum { sum=$(($1+$2)) echo "The sum of $1 and $2 is: $sum" } echo "Let's use the sum function" sum 1 5 如果你运行该脚本,你将看到以下输出: Let's use the sum function The sum of 1 and 5 is: 6 Bash 基础知识系列 #9:Bash 中的函数 接下来呢? 这只是一个初窥。这个 Bash 脚本教程只是一篇引言。Bash 脚本的内容还有很多,你可以慢慢地、逐渐地探索。 GNU Bash 参考是一份优秀的在线资源,可以解答你的 Bash 疑问。 GNU Bash 参考 除此之外,你可以下载这本免费书籍来学习更多在此未涵盖的 Bash 内容: 下载 Bash 初学者指南 一旦你具有足够的 Bash 基础知识,你可以通过这本免费书籍来学习高级 Bash 脚本: 下载高级 Bash 编程指南 这两本书至少都有十年的历史,但你仍然可以使用它们来学习 Bash。 ...

    2023-08-23 198
  • 攻防演练 | HW实战中钓鱼全流程梳理

    0x01前言 临近攻防演习,传统的web打点在没有0day的条件下变得非常困难,钓鱼成为一种相对容易的打点方式。本篇文章将介绍个人总结的钓鱼全流程,包括发送阶段注意事项、钓鱼话术、上线后注意事项。 本文不讨论免杀技术,均在当前已有一个能过国内主流杀软的exe,想让目标上线至我们C2服务器的情境下展开。 个人偏向于通过邮件来实施钓鱼,文章将重点讲解钓鱼邮件的全流程。当然电话、wx钓鱼的方式成功率更高,也需要更强的社牛属性。 0x02发送阶段注意事项 1、邮箱收集 网页泄露:官网联系邮箱、招标文件、招聘信息、投诉邮箱等等。 查询工具:https://hunter.io/search http://www.skymem.i nfo/srch 2、少用群发 群发的邮件内容定制化程度低、可信度低,一旦被发现认定为钓鱼邮件,防守方会对木马文件进行分析,进而导致辛辛苦苦做好的免杀马被上传到云平台,最终失去免杀效果。 我个人偏向于通过常规163邮箱来发送邮件,gophis等钓鱼工具用的不是很熟练。 当然,如果想要尝试群发,需要开启选项:“分别发送”,不然收件人会知道你同时发了很多邮件给别人,很容易被识别出来这是一封钓鱼邮件。 3、修改邮箱前缀和昵称 邮箱的昵称是可以多次更改的,每次发送邮件前修改昵称,使昵称更符合情景。收件人先看到的是你的昵称,而不是邮箱号。   4、使用代理 收件人可以看到发件人发件时的IP,请选择一个合适区域的代理,不要远到国外,也不要暴露自己真实的IP。 5、绕过邮件网关 遇到邮件网关,可以尝试压缩包加密、或将恶意链接修改为二维码图片。 0x03钓鱼话术 在不同场景要有不同的钓鱼话术,接下来将从HR、企业、xx局三个目标来定制不同话术。 HR->简历 针对HR通常将木马伪造成简历,我通常将exe的名称加长,可以达到让受害者看不到后缀名的效果,同时使用resourcehacker修改exe图标为word、wps之类的图标,再将exe压缩后发送,实现以假乱真的效果 木马名称:“xxxxx大学——xxx简历——xxxx求职咨询.exe” 受害者看到的木马:word图标、名称为“xxxx大学——xxx简历——...” 话 ...

    2023-08-23 245
  • 程序员的我改行后在做什么?

    文章目录 闲言碎语 我的梦想已经破灭了 接下来我该怎么办呢? 我感受到的整体环境是这样的 闲言碎语 今天我回家陪父母吃饭,他们一如既往地唠叨着,抱怨我这个年纪还没有结婚,没有稳定的工作等等。尽管我对他们说的很多事情都表示认同,但实际上,在我这个年纪和阶段,虽然看似有很多选择,但实际上我并没有真正的选择权。我所能做的只是努力赚更多的钱。 以下内容来自掘金用户wjt的亲身经历分享。 在这个信息爆炸的时代,我们知道应该朝着更高的目标努力。然而,当你想要迈出下一步时,你会发现自己的上限早在出生或毕业的那一刻就已经注定。虽然少数人通过努力可以突破壁垒,实现理想的高度,但这只是小概率事件。在我看来,整个社会的发展似乎早已陷入了一种怪圈。 在我刚进入社会的早些年,我有着简单的想法。我只想努力工作,提升自己的专业素养,得到老板的认可,升职加薪成为一名管理者。如果被淘汰,那肯定是因为自己不够优秀,不够努力,专业技能不够过硬,人际交往不够圆滑等等。 然而,当内卷成为热门词汇,35岁被裁员成为常态时,我回头看自己以前的想法,发现它们只是笑话。(我可能只是为自己被淘汰找借口) 现在的状况是这样的,我参与的游戏工作室项目基本处于停滞状态。我不敢关闭电脑,也不敢关机。有时候我会想,是不是全中国的三四亿人都在从事这个行业?国外一款游戏,金价直接飙升到这个地步。 至于汽车配件行业,只能说勉强维持生计。(我在游戏工作室上花费了太多精力) 我的梦想已经破灭了 按照正常情况,游戏工作室最初的阶段,我应该能挣点钱。我觉得我具备了时机、地利和人和。但现在看来,我只占了人和一项。我会编码,使用脚本模拟键鼠,写了一套脚本。然而,我并没有赚到钱。 接下来我该怎么办呢? 也许我应该去工厂打螺丝。(开个玩笑) 或者老老实实跟着我弟学习做生意吧,老实做汽车配件吧!在这个时代,似乎拥有一项技能(尤其是IT领域)的人,并不能过得很好。除非你的技能非常特别。(当今中国并不需要太多这类专业技术人员吧。) 我感受到的整体环境是这样的 我周围有很多牛人。从他们的口中和我自己的观察来看,我觉得国内IT领域的环境非常恶劣。在前端领域,除了UI库,我使用的许多库都是外国人开发的。为什么没有国人开源呢?因为国人都忙着996。我们可以在一无所知的情况下,通过复制粘贴和全局搜索解决大部分问题。机械视觉、大数据分析、人工智能等等,这些基础技术早在多年前就已经存在,为什么没有人去研究它们呢?为什么我们这一代人不断学习这个框架、那个框架?虽然搭积木很有趣,但创造一个积木难道不应该是更具挑战性的事情吗? 在招聘网站上,有一种奇怪的现象。看起来某家公司在招聘,实际上是一个培训机构。看起来某家公司在招聘兼职,实际上只是想骗你办理兼职卡。看起来某家公司在招聘快递员、外卖员、司机,实际上只是想套路你买车。真是让人气愤。这是怎样一个恶劣的生存环境。这些人难道不能从事一些正经的工作吗? 卖菜的、拉车的、搞电商的、搞短视频、搞贷款、卖保险,这些公司市值都达到了数百亿。很难看到通过创新、创造和产品质量发展起来的公司。 ...

    2023-08-23 189
  • 一位00后程序员面试近2个月的经验总结

    文章目录 首先,不要裸辞,不要裸辞,不要裸辞 第三,要对预期薪资和被拒原因有所了解 第四,锚定薪资 第五,要准备好涨薪的说辞 第六,要主动询问,预判结果 第七,不断迭代升级 总结 最近我读了一些关于找工作的文章,特别是一位00后找工作的经历,历时2个月,使用了各种途径,也遇到了各类公司。读完之后,我深感新一代的年轻人令人钦佩。他们在找工作过程中运用了许多技巧,避免了许多坑,也掌握了一些要点,我将其中的一些经验总结如下,供大家参考。 首先,不要裸辞,不要裸辞,不要裸辞 这是非常重要的。在当前的市场环境下,找工作时千万不要轻率地辞去现有的工作。裸辞会带来被动、心态不稳和议价权缺失等问题。如果手头没有备选工作,没有收入来源,而且对未来的工作也没有明确的计划,那么你会陷入非常被动的境地。无论是面试还是谈薪资,你都处于劣势。一旦找工作的时间过长,超过一个月甚至更久,你可能会陷入自我怀疑的情绪中,同时,下家公司也会根据你的找工作空档期来评估你的能力。 其次,内推是首选通道。这位00后的前端工程师在找工作时不仅使用了传统的招聘网站,还在技术平台和技术社区发表文章,寻求内推机会。他通过这些渠道获得了20多个内推机会。只要你的思路足够开阔,你就能比别人拥有更多的优势。与直接投简历相比,通过技术平台和社交平台的内推能更好地展示自己,更快地与公司拉近距离。在简历筛选过程中,你已经脱颖而出。 第三,要对预期薪资和被拒原因有所了解 在找工作的过程中,除了能力本身之外,大多数被拒的原因是期望薪资过高。许多HR也会直接告诉你:今年市场不景气,求职者众多,许多公司都在降低成本,如果你是在互联网红利时期,你的薪资期望是可以的,但现在可能就不太可能了。当然,这些原因一方面是HR的议价技巧,另一方面也反映了市场现实。 第四,锚定薪资 在简历中,不要写具体的数字,而是给出一个薪资范围,其中最低值是你理想的薪资。当面试结束后,了解具体的福利待遇、工作节奏和奖金等情况后,再根据自己的预期和面试情况进行调整。这样的调整也是试探市场,了解自己目前能够获得的薪资范围。最好是在拿到一个offer之后,再适当地上调一部分。 第五,要准备好涨薪的说辞 当HR问你为什么要提高薪资时,比如,HR会问,你上家公司才12k,现在希望18k,为什么涨幅会这么高呢?你可以回答说,经过几年的努力和业务积累,你的技术水平和业务逻辑显著提高,可以创造更大的价值。同时,你对这个行业非常热爱,平时80%的业余时间都用来学习和提升自己。另外,你也可以根据公司的工作强度、业务复杂度和挑战程度来说明涨薪的理由。 第六,要主动询问,预判结果 在找工作的过程中,许多人在回复“等消息”之后就只是等待,而有一部分求职者会在一段时间后主动询问HR和面试官,以获得更多的预判信息。甚至可以询问没有获得offer的原因,以备后续找工作时使用。在这个过程中,你实际上可以争取到更多的机会,甚至能够扭转公司正在犹豫的结果,你的主动行为会为你带来更多的机会。 第七,不断迭代升级 无论是面试中遇到的技术问题还是其他问题,面试后都需要进一步学习,为下一次面试做准备。对于面试中不懂的内容,可以查阅资料,咨询专家,动手实践等等,甚至可以整理成文章。无论采取何种形式,都是对面试过程的回顾和总结,不断迭代,让自己做好下一次面试的准备。 总结 总之,找工作的过程中还有许多其他注意事项,需要不断总结和迭代。学习他人的面试经验,提前做好准备,形成自己的面试方法论,能够让你脱颖而出。面试前后的努力往往比工作中的努力更重要,因为选择错误会大打折扣。最后,希望大家都能够获得满意的工作机会。 ...

    2023-08-23 179
  • 某博若隐若现自拍大赛

    围观地址:https://weibo.com/2479238731/NewZmCe8T...

    2023-08-23 191
  • 某博上班OOTD大赛

    围观地址:https://weibo.com/7744876007/NevOEDVXd...

    2023-08-23 182
  • 旅游赛道一个真正赚钱的玩法

    这个暑假,旅游赛道是彻底火了,不仅好玩,还能变现,果然就像雷军说的,比勤奋更重要的是顺势而为。 下面我放几个数据,这个是刚发的文件,要全面落实带薪休假制度,鼓励错峰休假,促进假日消费。 这个是今年的旅游搜索指数上涨的曲线,数据非常恐怖。 还有就是最近的现象级热搜,也很有意思,从五一的淄博烧烤到暑假一天涨粉上百万的导游小祁。 这些都代表了大家对于旅游,几乎疯狂的需求以及扩大内需的强烈决心。 下面我会从已经变现的结果来告诉大家,旅游赛道做什么方向能赚钱? 01 旅游赛道的钱在哪? 不是成为带券达人或者卖旅游卡,也不是跟同行厮杀,打价格战,而是服务高净值人群,做有钱人的生意。做一条垂直的高端旅游线路,我们群里有人通过这个玩法,起号七天就变现了8万,主打的就是一个畅玩,还能定制、游艇、马场。 而且出去旅游的,一般都是以家庭为单位,至少是两人起步,多了亲朋好友七八个的也有,一个人至少是2万的费用,那七八个是多少呢?所以,这个赛道天然自带裂变效果,可谓是一人销售多人成交。 另外这种内容做起来也并不复杂,就是精品游玩的路线解说,不需要什么好的创意,酷炫的剪辑,主要是因为现在用户的习惯已经发生了改变,现在想要搜点什么,都是在抖音或者小红书上面搜,只要你能把旅游地点的搜索词占住,总会有人搜索到你,而且还有自然推荐。 就这种玩法,群里有人在只用了七天,不到千粉的情况下,直接变现了8万,这么算的话,一个月就将近30万,这种变现能力,可谓非常的夸张。但是他自己并不是导游或者是旅行社的员工,只是自己去玩过,然后朋友是做旅行社的,能帮助他做变现,因为这个行业的通病,就是导游自己是做不好流量的。 02 为什么呢?想要做明白旅游赛道,本质是依赖运营能力,而不是旅游知识。导游一般是没有时间去学习的,旅行社也是忙得不可开交,都在忙着抢钱,忙着联系车和导游,处理游客的问题,所以他们是迫切需要你的存在,如果你找他们合作,你只需要做明白流量,他们会非常乐意帮你完成复杂的转化和交付动作,整个变现的环节会非常的轻松丝滑。 03 有些朋友可能会说,我也不知道该怎么做旅游规划,那怎么办呢?这个问题其实很好解决,因为关于旅游的路线,出去旅游过的都知道,他就那几个点,比如说去西安玩,就是钟楼,大唐,不夜城,兵马俑,大雁塔,你顺便搜一搜就知道了。 所以说旅游赛道真的适合所有人去做,线上是玩不出什么新花样的,但是只要线下把出行的品质拉高,让客人住的好,吃的好,玩的好,拍照拍的开心,这就足够了,因为大多数人都第一次去,开心才是最重要的,消费完之后,佣金到账,你也会跟着开心。 创业最基本的能力就是得学会抓住异常值,因为异常值等于机会。旅游,是一条空白了三年的老牌赛道,而且现在有一个行业的共识,就是旅游会是互联网最后一个万亿级别的赛道。那么对一个空白的万亿市场的出现,难道你不想跟他发生点什么故事吗? 我是张大力,N年互联网创业、副业、赚钱一线实战经验! 作者:张大力 </div>...

    2023-08-23 170
  • 手机语聊多开全自动视频挂机

    项目介绍: 需要设备:安卓手机,不限系统,根据手机配置,配置好的可以多开3~5个窗口,单个窗口收益30~50不等!软件已经打包在百度网盘,课程包含项目介绍和视频演示教学! ...

    2023-08-23 196
  • 特斯拉回应100G数据泄露事件:内部员工违规操作

    2023年5月,德国商报发文称特斯拉存在数据泄露事件,时间跨度从 2015 年至 2022 年 3 月,覆盖了美国、欧洲和亚洲特斯拉车主报告的投诉。在此期间特斯拉车主报告了 2400 多起自动加速问题和 1500 多起制动问题,其中包括 139 起“意外紧急制动”报告和 383 起错误碰撞警告导致的“幽灵刹车”报告,客户纷纷表达了对安全的担忧。 而据国内多家媒体报道,近日特斯拉向其员工以及美国执法部门通报了“100G数据泄露事件”的具体规模及原因。 8月18日,美国缅因州总检察长办公室发布消息称,2023年5月,特斯拉数据泄露事件影响超过7.5万人,其中包括与员工相关的各种敏感信息,例如姓名、住址、电话、电邮、薪资等等。 位于特斯拉欧洲超级工厂所在地勃兰登堡州数据保护官Dagmar Hartge表示,“这是印象中规模最大的一次数据泄露事件”。正因为数据量如此庞大,超出当时相关部门处理权限,所以该案件已经移交至荷兰当局。 根据相关法规,若是在调查中证实特斯拉确实存在违规行为,特斯拉可能要面临高额处罚,也就是其年销售额4%的罚款,大概在35亿美元(约合人民币247亿)。 特斯拉对此事进行回应,“心怀不满的前员工”滥用了他们作为服务技术人员的权限,违反了特斯拉的 IT 安全和数据保护政策,特斯拉将对涉嫌泄密的个人采取法律行动,并且没收其电子设备,禁止前雇员进一步使用、访问或传播数据等等。 换句话说,特斯拉已经承认了这一事件,指出这是“内部不法行为”的结果。此次数据泄露事件的严重性不容忽视。特斯拉作为全球领先的电动汽车制造商,在全球保有量如此之高的情况下,还需进一步加大对数据安全和隐私保护方面的投入,并真正将其落到实处。 事实上特斯拉曝出数据安全问题已经不是第一次,除了驾驶问题外,特斯拉还出现过严重的客户信息泄露问题。我们关注到,今年4月6日路透社就曾报道称,在 2019 年至 2022 年期间,特斯拉员工竟通过内部消息系统私下分享车载摄像头记录的音视频内容。 ...

    2023-08-21 251
  • 女生总是手淫自慰对身体有危害么

    女性自慰是一种正常的生理现象,适当的自慰对身体也不会产生危害。但是长期过度的自慰,也会给身体带来很大的影响。因此在生活中我们一定要多加注意,尽量避免频繁的自慰行为,尤其是频繁使用自慰器。尤其是青春期的女生不可以频繁自慰,这样会使我们在学习上不能专心,从而影响学习成绩。   女人总是自慰对身体是有伤害的,虽然自慰是一种正常的生理现象,但是长期过度的自慰会给身体带来不小的影响。比如,女人自慰很容易引起尿道发炎这种症状。这是因为女性朋友在用手或其他器械对,阴部进行摩擦时,有可能会接触到尿道口,如果我们的手指或器械卫生条件不好的话,很容易引起细菌进入尿道引起炎症。而且总是自慰,还会使我们的内分泌失调,从而破坏我们的生理周期,有些朋友会发生月经不调的现象,从而使白带的数量也上升。 自慰时我们的身体处于兴奋状态。如果长期使我们的身体处于兴奋状态,很有可能会使我们的神经受到伤害,从而引起神经衰弱。虽然自慰本身不会引起神经衰弱,但是因为有些人对自慰的认识不够,觉得它是一种不道德的行为。因此从精神上就会对自己造成压力。   由此可见女人总是自慰对身体非常有害。不但可能因为我们使用的器械不卫生而感染细菌引发炎症,还有可能会使我们精神总是处于紧张状态,而患上神经衰弱,长期自慰还有可能会使我们的白带增多。因此适度的自慰是非常重要的。除此之外,自费一旦引发性兴奋,还会对子宫造成一定程度的收缩,因此如果在来月经时自慰,很有可能会加重痛经的程度。   女性朋友在自慰时一定要注意保持个人卫生,尤其是手部的清洁,手指甲不可以过长,因为手指甲如果过长,指甲内就会存有大量的细菌,这时我们的自慰很有可能会触发细菌进入阴道或者尿道。而且自慰是尽量避免使用自慰器等器械,长期使用自慰器会对我们的精神以及身体产生危害。 ...

    2023-08-21 267
  • 肉肉是美女,性感尤物极致诱惑#泰裤辣

    肉肉是美女,性感尤物极致诱惑#泰裤辣 6p ...

    2023-08-21 266
  • Telegram的仿冒账号诈骗日新月异,”长安不夜城“遭遇Telegram群组与频道双重李鬼仿冒

    “Kirin博客”曾经报道过,”Onion666暗网导航“官方的Telegram群组里多次发生使用仿冒账号冒充群主进行行骗,而且屡屡得手。最近,有暗网网友反馈称,中文暗网交易市场”长安不夜城“也遭遇了仿冒账号诈骗,而且同时仿冒了Telegram群组与频道。 ”长安不夜城“遭遇Telegram群组与频道双重李鬼仿冒 中文暗网交易市场”长安不夜城“的真正的官方Telegram群组账号,拥有8000多成员,同时在线数百人;官方Telegram频道账号为:https://t.me/cabycout,拥有4000多订阅者。 李鬼Telegram群组账号为:https://t.me/****(仿冒账号),拥有3000多成员,从在线仅5人可以看出,都是僵尸账号;李鬼Telegram频道账号为:https://t.me/****(仿冒账号),拥有1000多订阅者。   假的”长安不夜城“群组账号 与正常的以假乱真的假冒账号一样,李鬼Telegram群组与频道不仅在账号上高度模仿官方Telegram群组与频道,从cabyc改成cabycity,而且群组与频道的logo、名称及简介信息也是直接照搬官方账号的内容。更恶劣的是,其将官方群组及频道内发布的内容也复制过来了,这样可以能够做到80%以上的相似度。 接下来,就是怎么诈骗了,他可以诱导用户称可以实现担保,所谓的担保也就是直接将USDT放骗子那,然后就没有然后了。 被骗的人到被骗也不会认为这是假的”长安不夜城“账号,于是各个群哭诉”长安不夜城“是骗子,可实际上是被李鬼账号骗子,“Kirin博客”提醒大家加强防范,以及多提醒。 某新用户被假冒”Onion666暗网导航“群主的骗子账号诈骗 最近在”Onion666暗网导航“的官方Telegram群组(https://t.me/****)里,又有用户”**星的鱼“称被群主诈骗,经“Kirin博客”证实,确实系新的骗子将头像改为”Onion666暗网导航“的logo,将用户名称改为”Onion 666 群主“,赢得了他的信任 于是假群主像他推荐了一个”黑客“(https://t.me/****),号称靠谱,可以提供渗透技术,于是先款,成功诈骗其1000RMB,数额不大,按该用户的话说”穷不了自己,富不了骗子“,但却是一个深刻的教训。 看以上简介,这个人无所不能了,代付、解码、渗透都可以做,业务面还很广:订票、香烟、订房、数据等等,再配个anonymous的头像,骗子无疑! 另外这个骗局最可笑的是,有没有谁见过哪个xxx群组的管理员的用户名是”xxx群主“。这种老式套路“Kirin博客”已经预警过多次,但还是有新人中招,于是只能再发案例提醒。 Telegram的仿冒账号诈骗手段日新月异,但无论手段与套路如何,请务必记得这句话:”Telegram群里卖软件的、卖技术的、卖数据的,99%都是骗子!请不要给Telegram群组里的任何人转账!“ 更多暗网新闻动态,请关注“Kirin博客”。...

    2023-08-21 315
  • 支付宝推出全新国际版支付宝

    看标题是不是觉得绕口,那也没辙。有件事说下:在2023年支付宝合作伙伴大会上,支付宝宣布推出了全新国际版支付宝了! 这场大会卢松松有幸参加,也见证了国际版支付宝的发布。这个全新国际版支付宝主要解决了日常消费如打车、订酒店、吃饭结账、景点购票的问题。支持主流的国际卡如Visa、Mastercard、Diners Club、Discover、JCB等。而且费率还降低了很多。 从目前解决的问题来看,国际支付宝好像还没走出国外,只是解决了老外在国内消费的问题,跟我们关系不大,不过这也是一个大进步了。 这次全新国际版支付宝升级我觉得主要是政策性产品,是面向老外的。这几年老外来中国旅游的人越来越少,而且逐年下降。我觉得最大的一个原因是:支付不方便,做公交、打电话、埋单、订的酒店啥的欧非常不方便。甚至老外连做个公交车都费劲。因为因为老外在国内消费非常不方便,所以这里并不是老外旅游的首选目的地。 另外,就算是支付方便了,有一些问题也要解决比如信用。 另一件事我觉得也能解决:那就是做跨境的人银行卡经常被冻结的问题。国际版支付宝可以在一定程度上解决银行卡经常被冻结的问题,我们很多正经做跨境电商的人的银行卡经常被封,原因就是因为一些不能说的原因老被封。短则1个月,长则1年,严重的还会面临行政罚款或刑事处罚,严重影响了海外电商人的生意和信心。 部分老外用国际版支付宝了、国内的卖家也开始让用其收款了。那未来和PayPa就差不多了。 如果支付宝在多多公关一下,让一些一些主流的电商网站,如shopee、Amazon、Lazada、eBay等都支持国际版支付宝收款的话,那么支付宝在海外也将迎来春天。只是这几年受一些因素影响太大了,一直走不出去。...

    2023-08-21 220
  • 做LOL陪玩 月入3w+ 边玩游戏边收钱(附接单流程)

    今天给大家带来的项目是如何做《英雄联盟大乱斗陪玩》月入过万。先问问大家,你玩游戏只是为了放松和解压吗?不想在赢了游戏之后还有一笔可观的收入吗?我们做游戏陪玩,是为了照顾一些想赢游戏,但是找不到厉害的队友的“老板”。时间多的每天玩玩游戏赚300-500它不香吗?所以就算我们只会玩游戏也能月入过万。大乱斗英雄操作教程(详细版)(文件夹)01.项目介绍02.怎么做陪玩03.在哪里接单04.接单时应该注意哪些05 抖音 贴吧找私单实操 ...

    2023-08-21 231
  • 【原创】苹果CMS程序海螺模版安装教程

    苹果CMS新安装海螺模版教程 第一步:下载好苹果CMS源码 第二步:把刚刚下载的源码上传到网站根目录后解压   然后访问绑定的域名安装   第三步:安装好后下载海螺模版上传到文件夹/template后解压   第四步:下载好配置文件,传到目录/application/admin/controller解压 第五步:下载第二个配置文件,/application/admin/view解压 第六步:登录网站后台-----自定义菜单配置里面添加:海螺主题设置,/admin.php/admin/conch/theme   第七步: 网站模板和手机模板都是【conch】模板目录【moban】,清理缓存。 注意微信观看功能要在conch/js/jquery.stem.js 这个文件夹修改相应的内容 第301行   幻灯片推荐9 大图模式需要上传海报图,建议尺寸1680px*580px 小图模式需设置3个推荐才显示   热播推荐1 建议推荐18个最jia(适配换一换功能)。   PS:切记一定要安装PHP扩展 《sg11》 php版本选择7.0~7.2 ...

    2023-08-21 259
  • 小米8无人直播刷机包(去授权)

    以前Kirin博客发布过一个版本 但是用不了是个引流版本要授权 这个版本不需要授权 三色不可以用 虚拟相机可用 给Kirin博客的家人们谋福利了! ...

    2023-08-21 252
  • CentOS7搭建SpringBoot项目整合ELK环境详解

    文章目录 前言 1、ELK概述 2、环境&版本 3、Elasticsearch 3.1、下载Elasticsearch 3.2、安装Elasticsearch 3.3、配置Elasticsearch 3.4、启动Elasticsearch 4、Logstash 4.1、下载Logstash 4.2、安装Logstash 4.3、配置Logstash 4.4、启动Logstash 5、Kibana 5.1、下载Kibana 5.2、安装Kibana 5.3、配置Kibana 5.4、启动Kibana 6、SpringBoot集成ELK 6.1、添加依赖 6.2、修改Logback配置 6.3、启动SpringBoot项目 6.4、在Kibana中查看日志 总结 前言 本文详细介绍了在CentOS 7操作系统上搭建ELK以及在SpringBoot项目中整合ELK的步骤。以下内容来自掘金用户汪小成。 1、ELK概述 ELK代表Elasticsearch、Logstash和Kibana三个开源项目的首字母缩写。这三个项目共同构成了一个成熟且强大的实时日志集中处理方案。在这个方案中,Logstash用于日志收集,Elasticsearch则用于数据存储和索引,而Kibana则提供了一个直观的可视化界面,用于查看存储在Elasticsearch中的日志数据。 2、环境&版本 服务器系统版本、JDK版本、ELK版本信息如下: 环境 版本 端口号 Centos 7.9   JDK 1.8   Elasticsearch 7.2.1 39100 Logstash 7.2.1 39102 Kibana 7.2.1 39101 Elasticsearch、Logstash和Kibana三个开源项目都需要在Java环境下运行,所以需要提前在服务器上安装JDK。 centos的环境搭建的JDK1.8。本文中没有讲述JDK的安装,有需要的朋友可以参考《Centos7 安装JDK1.8》文章。 3、Elasticsearch 3.1、下载Elasticsearch $ wget –c https://mirrors.huaweicloud.com/elasticsearch/7.2.1/elasticsearch-7.2.1-x86_64.rpm 为了更快的下载速度,我选择在华为开源镜像站下载Elasticsearch。 3.2、安装Elasticsearch $ rpm -ivh elasticsearch-7.2.1-x86_64.rpm 3.3、配置Elasticsearch Elasticsearch配置文件位置:/etc/elasticsearch。 进入配置文件所在文件夹: $ cd /etc/elasticsearch 备份配置文件(非必要): $ cp elasticsearch.yml elasticsearch.backup.yml 使用vim打开elasticsearch.yml配置文件,按下i进入编辑模式。修改内容如下: network.host: 0.0.0.0 http.port: 39100 discovery.seed_hosts: ["127.0.0.1:39100"] 配置项说明: network.host用于设置绑定的主机地址,可以是IP地址或主机名。http.port用于设置监听的HTTP端口,出于一些特殊原因,我将elasticsearch的端口号由默认的9200修改为39100。discovery.seed_hosts用于设置集群节点的种子主机地址,用于节点发现和加入集群。 3.4、启动Elasticsearch # 启动Elasticsearch $ sudo systemctl start elasticsearch 将Elasticsearch设置为开机启动(非必要): # 将Elasticsearch设置为开机自启 $ sudo systemctl enable elasticsearch 查看Elasticsearch的运行状态: $ sudo systemctl status elasticsearch 或者,使用如下命令检查Elasticsearch是否启动成功: # 检查Elasticsearch是否启动成功 $ netstat -antp | grep 39100 待Elasticsearch启动成功后,可以使用curl命令来测试Elasticsearch是否正常运行。例如: $ curl http://127.0.0.1:39100 如果返回类似以下内容,说明Elasticsearch已经成功运行: { "name" : "localhost.localdomain", "cluster_name" : "elasticsearch", "cluster_uuid" : "NqlpN5iJQmeSV_TvHqPo6w", "version" : {   "number" : "7.2.1",   "build_flavor" : "default",   "build_type" : "rpm",   "build_hash" : "fe6cb20",   "build_date" : "2019-07-24T17:58:29.979462Z",   "build_snapshot" : false,   "lucene_version" : "8.0.0",   "minimum_wire_compatibility_version" : "6.8.0",   "minimum_index_compatibility_version" : "6.0.0-beta1" }, "tagline" : "You Know, for Search" } 最后,使用如下命令修改Centos防火墙配置开放端口号供外访问: $ sudo firewall-cmd --zone=public --add-port=39100/tcp --permanent 重新加载防火墙规则以使更改生效: $ sudo firewall-cmd --reload 4、Logstash 4.1、下载Logstash 在华为开源镜像站下载Logstash: $ wget –c https://repo.huaweicloud.com/logstash/7.2.1/logstash-7.2.1.rpm 4.2、安装Logstash $ rpm -ivh logstash-7.2.1.rpm 4.3、配置Logstash 在/etc/logstash/conf.d文件夹下创建logstash.conf配置文件,配置文件内容如下: input {   tcp {       host => "0.0.0.0"       port => 39102       mode => "server"       codec => json_lines   } } output {   elasticsearch {       hosts => "localhost:39100"       index => "%{[appname]}-%{+YYYY.MM.dd}"   } } 配置说明: input – 用于定义数据的输入源,即Logstash的数据来源。 tcp – 用于指定Logstash监听指定的IP和端口,接收 TCP 连接传入的数据。 host – 监听的主机IP地址,这里的0.0.0.0表示监听所有可用的网络接口。 port – 监听的端口号。我这里将端口号由默认的9600改为了39102。 mode – 连接模式。 codec – 数据编码解码方式,json_lines表示接收到的数据将以JSON行的形式解析。 output – 用于定义数据的输出目录。 elasticsearch – 表示将数据输出到Elasticsearch集群。 hosts – 用于设置Elasticsearch集群的主机地址和端口号。 index – 用于指定Elasticsearch索引的名称。这里使用 %{[appname]} 表示索引名称从数据中的appname字段获取。%{+YYYY.MM.dd}表示在索引中包含日期信息。 4.4、启动Logstash $ sudo systemctl start logstash 最后,使用如下命令修改Centos防火墙配置开放端口号供外访问: $ sudo firewall-cmd --zone=public --add-port=39102/tcp --permanent 重新加载防火墙规则以使更改生效: $ sudo firewall-cmd --reload 5、Kibana 5.1、下载Kibana $ wget –c https://repo.huaweicloud.com/kibana/7.2.1/kibana-7.2.1-x86_64.rpm 5.2、安装Kibana $ rpm -ivh kibana-7.2.1-x86_64.rpm 5.3、配置Kibana 进入/etc/kibana文件夹,修改kibana.yml配置文件中如下内容: server.port: 39101 server.host: "0.0.0.0" elasticsearch.hosts: ["http://localhost:39100"] i18n.locale: "zh-CN" 配置说明: server.port – 用于指定Kibana服务监听的端口号,这里我将端口号由默认的5601改成了39101。 server.host – 用于指定Kibana服务监听的主机地址。”0.0.0.0″表示监听所有可用的网络接口,即可以从任意IP地址访问Kibana。 elasticsearch.hosts – 用于设置Elasticsearch集群的主机地址和端口号。 i18n.locale – 用于设置界面语言,这里将界面语言设置成了中文。 5.4、启动Kibana $ sudo systemctl start kibana 最后,使用如下命令修改Centos防火墙配置开放端口号供外访问: $ sudo firewall-cmd --zone=public --add-port=39101/tcp --permanent 重新加载防火墙规则以使更改生效: $ sudo firewall-cmd --reload 6、SpringBoot集成ELK Spring Boot应用输出日志到ELK的大体流程如下图所示:说明: Spring Boot应用产生日志数据,使用Logback日志框架记录日志。 Logstash作为日志收集器,接收Spring Boot应用发送的日志数据。 Logstash解析和过滤日志数据,可能会对其进行格式化和处理。处理后的日志数据被发送到Elasticsearch,Elasticsearch将日志数据存储在分布式索引中。 Kibana连接到Elasticsearch,可以查看存储在Elasticsearch中的日志数据。 6.1、添加依赖 修改pom.xml文件,添加如下配置: dependency>    groupId>net.logstash.logbackgroupId>    artifactId>logstash-logback-encoderartifactId>    version>7.2version> dependency> 6.2、修改Logback配置 修改Logback的配置文件: + +   +   60.211.159.140:39102 +   +   +       +       {"appname":"spring-boot-elk"} +   +   +     6.3、启动SpringBoot项目 这一步,我就不废话了。 6.4、在Kibana中查看日志 1、在浏览器地址样中输入服务器IP+Kibana端口号 –> 点击管理 –> 点击索引模式 –> 点击创建索引模式。2、输入索引模式名称 –> 点击下一步。3、设置时间筛选字段名称,我这里没有使用时间筛选。4、点击Discover图标就可以看到Spring Boot项目输出的日志了。 总结 以上就是作者分享的CentOS7搭建Spring Boot项目整合ELK环境全部内容详解,希望对你有帮助! ...

    2023-08-20 266
  • 响尾蛇组织近一年攻击组件汇总分析报告

    1 APT组织相关背景介绍 1.1 响尾蛇组织相关背景介绍 响尾蛇组织, 又称Sidewinder、APT-C-17、T-APT-04,是一个来自于南亚地区的境外APT组织。该组织主要针对中国、巴基斯坦、尼泊尔、斯里兰卡等亚洲地区国家进行网络间谍活动,主要针对高校,新闻,金融,媒体,政府和电信公司进行攻击,以窃取敏感信息为主要目标。该组织的相关攻击活动最早可以追溯到2012年,至今还非常活跃,大多数行动是对巴基斯坦进行攻击,窃取机密信息。 1.2 响尾蛇组织攻击过程 该组织将攻击过程分解成多个阶段,有多次网络下载过程,且连接的C2会检查访问IP所属国家,只允许本次的攻击目标所属国家的IP进行访问,另一方面,为了躲避安全软件的查杀,关键的恶意程序只在内存中执行,最终的远控程序落地为加密数据的形式,需要加载器解密后才执行。 另外响尾蛇组织也会使用开源工具进行攻击活动,在C2的网络特征,域名构造方式有很大的关联性,整体攻击过程比较简单,最终用DLL侧加载的方式在内存中解密执行Cobalt Strike的beacon载荷,实现对用户机器的控制。 此外响尾蛇组织还对Android手机用户进行攻击,通过Google Play散发恶意apk安装包,窃取目标手机中的隐私信息和机密文件。 1.3 响尾蛇组织打点技巧 在响尾蛇组织的相关攻击活动中,该组织伪造发件人邮箱,通过伪造正常的“学院通知”、“政府通知文件”、“热点事件”、“新奇事情(如:暗网数据泄露)”等相关邮件,诱导目标点击其投递的恶意链接或恶意附件,或者伪造政府邮箱登录页面,盗取合法邮箱发送钓鱼邮件。 2 涉及组件详细分析 2.1 DocxDownloader钓鱼组件 响尾蛇组织最常用的鱼叉式钓鱼组件,以抓眼的标题和相关单位的官方文件,在用户打开文档后,机器在不知不觉中被入侵。捕获的部分钓鱼文件如下表: 组件md5 名称 URL 首次上传到VT时间 056d1dc3032d04d7638c02056d5146c9 Circular 31082022.docx https://mo***gov.com/5724/1/3268/2/0/0/0/m/files-11e30891/file.rtf 2022-09-15 10:35:46 UTC b7e63b7247be18cdfb36c1f3200c1dba Product.docx https://cst***.dowmload.net/14668/1/1228/2/0/0/0/m/files-403a1120/file.rtf 2023-03-10 05:14:05 UTC 5efddbdcf40ba01f1571140bad72dccb Leakage of Sensitive Data on Dark Web.docx https://mt***south.org/5974/1/8682/2/0/0/0/m/files-b2dff0ca/file.rtf 2023-03-10 05:21:10 UTC 该组件中会包含一个RTF远程模板的链接,在文档打开时,会自动下载并执行该RTF模板。 打开时会闪过正在下载界面。 2.2 RtfDropper释放器组件 在响尾蛇的历史攻击事件中,rtfdropper组件的使用率非常高,通常文件名为file.rtf,做为docx钓鱼文档的第二阶段载荷,该组件利用office的公式编辑器漏洞CVE-2017-11882,执行释放的javascript脚本文件。 描述 详细信息 名称 file.rtf 文件大小 73294 bytes 文件类型 Rtf 文件功能 Downloader 编译时间 / 开发平台及语言 office Pdb / 是否加壳 否 VT首次上传时间 2022-05-26 18:02:22 UTC md5 54b1157ce8045f2e83340dc5d756f412 sha256 8b4259cb1619bcbf3f6760f0982d0a1d3c67aa26738a3d6f6788bf6c2a5410e5 通过rtfdump分析,可以发现该组件中嵌入了一个1.a文件(javascript脚本文件,文件名是响尾蛇组织固定使用的)和一个Equation.3结构(用于触发公式编辑器漏洞)。 该组件被执行后,公式编辑器在解析Equation.3时,在漏洞函数sub_41160F中数据复制时发生栈溢出,从而导致该函数的返回地址被改写,去执行响尾蛇组织的shellcode。 在shellcode中使用GetCommandLine,然后修改其返回指针指向的内容 解密出一段js脚本并覆盖GetCommandLine返回指针指向的内容。 最后加载mshtml和获取RunHTMLApplication的地址,调用RunHTMLApplication。 RunHTMLApplication给予4个0作为参数,触发RunHTMLApplication去调用GetCommandLine。 因为第一次调用GetCommandLine会从peb中复制一个命令行参数字符串存储在另一个空间中,在这之后GetCommandLine管理这个空间,由于第一次调用是修改了内容,覆盖为js脚本,所以在RunHTMLApplication中的GetCommandLine会得到这个脚本,又因为RunHTMLApplication的流程会去解析这个字符串,被“javascript:”引导去执行js脚本,最后调用CHTMLApp::Run执行js。而这一小段js脚本的作用就是执行1.a脚本文件。 2.3 LnkDownloader钓鱼组件 LnkDownloader是响尾蛇组织最常用的鱼叉式钓鱼攻击的组件之一,经过改进,从利用lnk文件属性中的显示bug隐藏实际的mshta调用,最后变为复制系统的mshta重命名为随机字符再去执行下载。 描述 详细信息 名称 BGI-14.pdf.lnk 文件大小 2217 bytes 文件类型 LNK 文件功能 Downloader 编译时间 / 开发平台及语言 / Pdb / 是否加壳 否 VT首次上传时间 2021-01-02 03:07:30 UTC md5 fa10f48243ea40298e0fa07787e4156c sha256 29022eab3963a624ae886a6f17f94834cb3e55377e0d32a4ad365af83bf74d74 当sLinkFilags中的HasExpString为1时,执行LNK文件会去检查EnviromentVariableDataBlock下的TargetUnicode的文件是否存在,不存在就去检查LinkTargetIDList指向的文件是否存在,存在就执行。LinkTargetIDList的最后一个sIDList中的PrimaryName被设置为hsmta.exe是为了维持HasExpString值不变,因为在检查出EnviromentVariableDataBlock中的TargetUnicode指向的文件不存在时被设置为0。 最后的效果是显示为hsmta.exe来误导用户。   描述 详细信息 名称 ***关于11月22日起工作安排调整的通知.docx.lnk 文件大小 1055 bytes 文件类型 LNK 文件功能 Downloader 编译时间 / 开发平台及语言 / Pdb / 是否加壳 否 VT首次上传时间 2022-11-24 16:42:12 UTC md5 5356a1193252b4fb2265fc8ac10327a1 sha256 f946663a780806693ea3fb034215bd6da25971eb07d28fe9c209594c90ec3225 改进后的lnk文件不再利用显示bug,是将mshta.exe复制并重命名为随机字符.exe,然后就下载执行远程HTA脚本文件。 2.4 DonetLoader加载器组件 响尾蛇组织经典的.net程序加载器,是魔改的开源项目CACTUSTORCH,用于在内存中加载后续的.net DLL程序,该组件分别作为rtf释放的1.a javascript脚本和lnk文件下载的hta文件。 组件md5 名称 文件大小 VT首次提交时间 a9dbf0cbc46dfe0202b534c63bd52a4a 1.a 900000 bytes 2019-08-13 13:49:59 UTC da8d3934fa1ddaf713ec32071eeb2987 file.hta 330170 bytes   db9562258c4a8518e0c6c43cdc0f0151 1.a 4953600 bytes 2022-01-14 07:30:57 UTC 该组织大致经过1年就会对组件进行升级改造,主要是字符串解密模块的修改。从标准base64编码->异或+自定义base64编码->字符反转+多个key异或。 2019:标准base64编码(相关文件md5:a9dbf0cbc46dfe0202b534c63bd52a4a)。 2020:异或+自定义base64编码(相关文件md5:da8d3934fa1ddaf713ec32071eeb2987)。 2021:字符反转+多个key异或(相关文件md5:db9562258c4a8518e0c6c43cdc0f0151)。 后续的加载过程都保留开源项目CACTUSTORCH的加载过程,解密后在内存加载,获取DLL的类对象“App.Program”,提供4个参数,并调用work方法。 2.5 AppDownloader下载器组件分析 在2022年之后,响尾蛇整合了早期的两个组件,开发了AppDownloader组件,通过Donetloader加载调用work方法,根据提供的参数,完成诱饵文件释放和后续载荷下载,并在内存中执行载荷,其真实文件名为App.dll,所以命名为AppDownloader。 名称 组件加载器 加载器md5 首次上传到VT时间 App.dll 1.a b1e0108df9a12d43fdf78e99d3528707 2022-01-14 07:30:57 UTC   描述 详细信息 名称 App.dll 文件大小 2200 bytes 文件类型 DLL 文件功能 Downloader 编译时间 \ 开发平台及语言 .NET Pdb \ 是否加壳 否 VT首次上传时间 2022-01-14 07:30:57 UTC md5 384CF4940E9B819CE8492FCD16EBEA6D Sha256 B8CAB453F7190514DC9F10FF6E549A715E69A2A53ECACBDC0CF0975B56C4E828 该组件是由donetloader加载并调用work方法和传递参数,当第四个参数不为空,则将该参数作为文件名,第三个参数为文件内容,在%temp%目录下释放诱饵文件,并使用mshta.exe打开该诱饵文件。 下载的数据前32位作为异或密钥解密后续的数据,然后再内存中加载。 2.6 ModuleInstaller下载器组件分析 该组件在不断改进中已经演变为一款比较成熟的恶意软件,会对前面阶段产生的痕迹进行清理,还会对不同的杀毒软件执行不同的操作,也采用了免杀效果不错的进程启动方式,使用其文件名ModuleInstaller做为组件名称。 描述 详细信息 名称 ModuleInstaller.dll 文件大小 46080 bytes 文件类型 exe 文件功能 loader 编译时间 2055-09-29 14:31:33 开发平台及语言 .NET pdb \ 是否加壳 否 VT首次上传时间 \ md5 05C1D2FD7F8E5970406B75C01DC6E949 Sha256 8B21AD911DCC66BBA525C95F1B9F9489E96BD2AADD2B7B0CFD2D53531B51231B 该组件的构造函数接收杀毒软件信息,并检测卡巴斯基、avast、avg、360杀毒这4款杀毒软件的存在。 然后根据配置信息“0100S-ABCD”中的第二或者第三个值是否为“1”,清除前面阶段的文件。 首先是清除%temp%\1.a文件,将文件内容改写为“//FFFF”,该1.a文件为前文所提到的donetloader加载器组件。 通过遍历1-4096已打开的文件句柄,获取文件绝对路径,检测路径中是否有"Microsoft\\Windows\\INetCache\\Content.Word"字符串,该路径下的文件为网络下载过程中的缓存文件,响尾蛇组织利用这个处理方式来消除其网络下载过程中产生的缓存文件。 获取系统信息:用户名、机器名,系统位数等系统基础信息。 将获取到的数据使用标准base64解码后,拼接到url的data参数中,随后使用拼接成的url下载配置数据。 将下载后的数据,使用前32位字节作为异或密钥解密后续数据,以相同的操作解密两次后得到配置数据。配置数据中包含后续载荷文件路径、下阶段载荷url,白+黑侧加载组合(control.exe和propsys.dll)。 根据url下载数据并异或解密后,将数据写入配置文件指定的文件中,将系统中的control.exe复制到相同目录下,最终该目录下存在文件:control.exe、control.exe.config、propsys.dll、[随机字符串].[随机字符串]文件,随着后续远控程序的加载可能会多出一些文件。 遇到卡巴斯基在配置字符的控制下,会使用wmi启动mshta执行js脚本去启动control.exe,以及直接向注册表run目录注册开机启动项,启动control.exe。 检测到360杀毒,直接使用process类启动隐藏窗口的control.exe。并创建快捷方式,放置在开机启动目录下。 检测到avast和avg时,注册两个计划任务,分别是延后2分钟执行control.exe和延后2分钟执行向注册表run目录添加开机启动项。 当没有检测目标杀毒软件时,就使用wmi执行schtask.exe添加计划任务,和直接向注册表RUN目录写入开机启动项。 2.7 DLLloader加载器组件分析 该组件作为白+黑 DLL侧加载利用中的恶意DLL,用来在内存中加载响尾蛇组织的关键载荷SystemAppRAT组件,功能单一,会跟据使用的白+黑利用方式变更文件名。 描述 详细信息 名称 Duser.dll,propsys.dll 文件大小 9728 bytes 文件类型 DLL 文件功能 Loader 编译时间 2021-02-09 18:16:50 开发平台及语言 .NET pdb \ 是否加壳 否 VT首次上传时间 \ md5 E4E2C1259EEA903A2953A1601E49797A Sha256 9B2C9C4FCD0BD591A58BDA2CFB8AF1C2E619FBE402CD2D9ACD0643EBB6E84D09 当DLL被加载后,会先进行Amsi绕过,Amsi可以检测.NET程序中调用的方法名,命名空间等信息来检测恶意的.NET程序,通过修改AmsiScanBuffer的前几个字节使得函数直接返回无可疑操作,达成绕过的效果。 随后读取同目录下使用随机字符命名的文件,使用其前32个字节作为异或密钥解密后续数据,解密后的数据为SystemAppRAT组件,用来进行远程控制,最后在内存中加载该组件。 2.8 SystemAppRAT远控分析 响尾蛇组织最常用的远控组件,以加密数据的形式落地为文件,被DLLloader组件加载后在内存中执行,通过自身的网络传输和机密文件收集功能,来控制被入侵的机器,窃取重要信息。   详细信息 名称 SystemApp.dll 文件大小 637952 bytes 文件类型 DLL 文件功能 RAT 编译时间 2064-02-17 19:06:49 开发平台及语言 .NET pdb \ 是否加壳 否 VT首次上传时间 \ md5 D308484A9EFA669979BD1004F8E5D748 Sha256 5CAD4B71A6A99B34FB2F4D60FA8BB5DB6A6F6DABE5468D9B3341CBC04492AAAB 首先从资源中加载配置信息。 解密后的配置信息如下,加密的方式是二进制文件的前32个字符作为key,循环与后续文件内容进行异或得到结果。配置文件中指定C2通信地址,和窃取的目标文件后缀.doc .docx .xls .xlsx .pdf .ppt .pptx。 解析完配置后,注册定时函数TreeRestoreAccessorInstance,每5秒与C2通信一次,并对C2返回的数据做出响应。 执行的命令如下: 命令 内容 1 收集系统信息,信息保存在.sif文件 2 收集文件信息 3 .docx .doc .xls .xlsx .pdf .ppt .pptx .rar .zip路径保存,信息保存在.fls文件 4 将收集到指定文件的路径保存在配置文件中 5 更新c2地址 6 更新是否上传指定文件参数 7 重置指定文件类型 8 设置文件大小限制 9 上传指定文件 10 保存配置 2.9 HtaDownloader组件 在2023年捕获到响尾蛇组织新的下载器组件,负责下载诱饵文档和恶意DLL,将恶意DLL放置到OneDrive目录下,实现侧加载。 描述 详细信息 名称 something.hta 文件大小 680 bytes 文件类型 HTA 文件功能 Downloader 编译时间 / 开发平台及语言 / 是否加壳 否 VT首次上传时间 / md5 2BCE7A8E34E4751C8E421BAA4C4A0ADA Sha256 F0CB23D26AF39BBFAE450F37BC7642B59D30EE346020485FECC5CD8C33D2190A 下载version.dll放置在本地Onedrive目录(%LOCALAPPDATA%\Microsoft\OneDrive\ ),当本地64位的Onedrive.exe和OneDriveStandaloneUpdater.exe执行时会被劫持以加载恶意version.dll,定时执行OneDriveStandaloneUpdater.exe更新Onedrive的计划任务也会变成响尾蛇组织的常驻项。   另外从巴基斯坦的内阁部门官方网站(cabinet.gov.pk)下载“Advisory No. 16”网络安全咨询16号文件,对应钓鱼文件中提及的内容。 2.10 CSloader组件 该组件为HtaDownloader组件下载的恶意DLL,被同目录下的OneDrive加载。 描述 详细信息 名称 version.dll 文件大小 275456 bytes 文件类型 DLL 文件功能 RAT 编译时间 / 开发平台及语言 / 是否加壳 否 VT首次上传时间 / md5 F2974B8D6B0B2774F49642D53BDEE8A4 Sha256 37E3465D6FCCFAE6E1C29526AA015A766F8FC26CC61ED821F3E0B44D794C99EC 其导出函数GetFileInfoSize和GetFileVersionInfoSizeW指向同一个偏移量,是Onedrive.exe导入DLL后会调用的函数。 GetFileInfoSize和GetFileVersionInfoSizeW函数中会调用函数FUN_180001120解密执行后续的载荷。 函数中先读取系统目录下的ntdll中的.text段替换掉当前进程加载的ntdll中的.text,解除函数挂钩,如果有安全软件通过在ntdll中设置钩子实现对进程行为的监控,那么该恶意文件的操作会让这种类型的监控方式失效。 通过计算硬编码16字节的数据的SHA256值,作为AES-256解密的密钥,解密出shellcode,最后执行。 执行的shellcode会反射加载一个Cobalt Strike的beacon,连接攻击者C2:35.175.135.236,实现远程控制。 2.11 ApkDownloader下载器组件分析 响尾蛇组织针对Android手机开发的恶意程序,最早在2020年由趋势科技披露相关技术细节,主要在Google Play上进行传播,该组件主要功能是下载下阶段载荷,最终在入侵手机中窃取WeChat、Outlook、Twitter、Yahoo Mail、Facebook、Gmail和Chrome等数据。目前以披露的部分恶意安装包如下: 组件md5 名称 文件大小 VT首次提交时间 07b41f9c81915c3adad6b3690ab7a99e 226617.apk 10763432 bytes 2023-03-23 09:34:02 UTC 17ccf24c4e09b1bc7ce5c0eb637a4edd Secure VPN_3.9_apkcombo.com.apk 14744189 bytes 2022-06-02 08:06:59 UTC 3DF009405C2226FA5047DE4CAFF3B927 com.securedata.vpn_v3.2.apk 6072227 bytes 2022-06-02 02:28:33 UTC   描述 详细信息 名称 226617.apk 文件大小 10763432 bytes 文件类型 Apk 文件功能 Downloader 编译时间   开发平台及语言 Android pdb \ 是否加壳 否 VT首次上传时间 2023-03-23 09:34:02 UTC md5 07b41f9c81915c3adad6b3690ab7a99e Sha256 7d237d0c62fb14391d40d8875534135a7a73b8ef47956405f4e600918d583f14 该组件先进行字符串解密,将头部的“zzzza”去除后传入函数。 将字符串使用base64解码后,先读取4字节数据,代表AES密钥长度,随后读取32字节的密钥,最后是AES加密的数据,并且该AES密钥也是网络通信数据的AES解密密钥。 根据分析结果得到AES密钥(7e 51 73 44 54 49 ac a1 fe 99 25 f3 25 29 58 e3 5a 45 7c cd 89 d4 87 78 34 3f b2 df c2 60 2c 21),使用AES-256 ECB模式解密数据后得到下阶段载荷的URL。 随后发送网络请求下载下阶段载荷。 该载荷会落地为文件保存为/data/data/<package_name>/files/fex/permFex/8496eac3cc33769687848de8fa6384c3。 最后通过DexClassLoader类加载该DEX文件,执行恶意代码,根据趋势科技报告中提到的信息,后续载荷是对手机信息的窃取。 最后注册计划任务,每10分钟去触发上文的下载执行下阶段载荷的过程。 注册开机广播,检测到开机事件会启动服务,也就是上文提到的下载下阶段DEX载荷和执行载荷。 该组件有多种获取C2的方式。 方法一:如上文的样本(07b41f9c81915c3adad6b3690ab7a99e)将C2硬编码在程序中。 方法二:在样本(17CCF24C4E09B1BC7CE5C0EB637A4EDD)中使用托管在Google Cloud上的Firebase服务提供C2。 方法三:在样本(3DF009405C2226FA5047DE4CAFF3B927)中使用Google Play的Install Referrer 服务获取数据,解密后得到C2。 3 基础设施分析 该组织会运营大量域名来针对东南亚各个地区进行攻击,并且带有访问控制,钓鱼C2上会检测请求IP所属国家,限制非目标国家IP的访问。 3.1 域名构造特征分析 从收集和整理的响尾蛇历史攻击中使用的域名,可以发现该组织比较偏向于使用攻击目标相关的机构官方域名的关键字符串来构造域名。如“*[mod/mofa]-gov*”,“*navy-gov*”,“mail[navy/mod/mofa]*”以伪装成军队和政府单位相关的域名,还有用字符错位、藏字符等方式构造域名,如“*donwloaded.com”,“*downlod.net”,“*downlod.com”。 3.2 URL特征分析 根据狩猎到的所有响尾蛇样本进行分析发现响尾蛇组织的第二阶段载荷下载URL具有明显的特点:固定的分段字符,特定的字符串“/2/0/0/”和”files-[8个随机字符]“,例如: https://[域名]/3679/1/55554/2/0/0/0/m/files-94c98cfb/hta https://[域名]/5974/1/8682/2/0/0/0/m/files-b2dff0ca/file.rtf https://[域名]/669/1/1970/2/0/0/1764305594/2X1R9Tw7c5eSvLpCCwnl0X7C0zhfHLA6RJzJ0ADS/files-82dfc144/appxed 3.3 C2网络特征分析 目前响尾蛇组织的C2有比较明显的特征是jarm="3fd3fd0003fd3fd21c3fd3fd3fd3fd703dc1bf20eb9604decefea997eabff7"和jarm="40d40d40d00040d1dc40d40d40d40de9ab649921aa9add8c37a8978aa3ea88"。且直接访问响尾蛇组织的C2地址,会直接返回404 Not Found,而且该组织多用“nginx”服务器,返回长度多数为“555”和“153”。 4 总结 响尾蛇组织常使用鱼叉攻击对目标进行打点攻击,攻击频率较高,具有一定的危险性。主要针对政府机构和军事单位等行业进行攻击,窃取该类单位的高新技术研究资料或规划信息等,相关行业及单位需要警惕并加强网络防御。另外该组织也常用DLL侧加载和无文件攻击,将关键代码隐藏在正常进程中秘密执行,安全公司应加强相关技术的检测。 5 ATT&CK模型 战术(Tactic) 技术(Technique) 过程(Procedure) TA0043-目标侦查(Reconnaissance) / / 资源开发(Resource Development) T1587.001(构建自定义恶意软件) 响尾蛇组织自定义开发了下载器、文件窃密组件等   T1588.001(获取恶意软件) 响尾蛇组织使用开源DONET加载器进行攻击。 初始访问(Init Access) T1566.001(鱼叉攻击,恶意附件) 响尾蛇组织向目标投递携带恶意附件的邮件。 代码执行(Execute) T1204.002(用户执行恶意鱼叉附件) 用户直接执行响尾蛇组织投递的恶意文件   T1203(针对客户端执行的攻击) 响尾蛇组织利用CVE-2017-11882 持久化(Persistence) T1547.001(Run注册项/启动文件目录自启动) 响尾蛇组织使用的恶意文件使用注册表自启动项实现持久化 T1053.005(计划任务) 响尾蛇组织使用的恶意文件创建计划任务实现持久化 权限提升(Privilege Escalation) / / 防御规避(Dfense Evasion) T1027.009(混淆文件或信息:嵌入式有效负载) 响尾蛇组织使用多种加载器加载恶意载荷 T1574.002(劫持执行流程:DLL侧加载) 响尾蛇组织使用DLL侧加载,在正常软件中加载远控程序。 T1218.005(系统二进制代理执行:mshta) 响尾蛇组织使用系统白文件执行远程hta脚本文件。 T1036.007(扩展名伪装) 响尾蛇组织使用pdf结合lnk的后缀名将恶意文件伪装成pdf文档文件 凭证访问(Credential Access) / / 发现(Discovery) T1518.001(安全软件发现) 响尾蛇组织使用Windows服务 winmgmts:\.\root\SecurityCenter2 检查已安装的防病毒产品。 横向移动(Lateral Movement) / / 信息收集(Collection) T1074.002(数据阶段:本地数据暂存) 响尾蛇组织将收集到信息保存在.sif、.flc、.fls等文件中。 T1005(本地系统数据) 响尾蛇组织使用组件SystemAppRAT等窃取office文档及txt文件等 命令与控制(Command and Control) T1071.001(使用现有web协议进行命令传输) 响尾蛇组织常使用HTTPS进行通信 T1132.001(数据编码/标准编码) 响尾蛇组织常使用base64对通信数据进行编码 数据渗出(Exfiltration) T1041(通过C2通道) 响尾蛇组织使用C2通道渗出数据 影响(Impact) / / 6 参考链接 https://www.group-ib.com/blog/hunting-sidewinder/ https://www.group-ib.com/blog/sidewinder-antibot/ https://mp.weixin.qq.com/s/LaWE4R24D7og-d7sWvsGyg https://www.trendmicro.com/en_us/research/20/a/first-active-attack-exploiting-cve-2019-2215-found-on-google-play-linked-to-sidewinder-apt-group.html https://mp.weixin.qq.com/s/WzmRtSt20musYWOgAEUT1Q https://mp.weixin.qq.com/s/MZadlpXbpCfQAv41rtVm3A https://mp.weixin.qq.com/s/YOyfe4a0PcKET5YiLObW7g ...

    2023-08-20 280
  • 基于LazyList的Scala反序列化漏洞透析(CVE-2022-36944)

    引言 前段时间打SCTF,大牛师傅们的WP后,在hello java那道题使用了CVE-2022-36944这个漏洞,但是查阅资料在国内乃至全世界互联网中没有找到相关分析文章,在github上找到了1个复现项目环境,研究了一些时间大概懂了一点。 没接触过Scala语言,虽然和java兼容性很强,但很多语言特性和机制都是第一次接触,而且有段时间没搞java安全了,这次相当于没有现成的分析文章,只能硬着头皮啃 POC复现环境 Github: lazylist-cve-poc “线索” For security, preventFunction0execution duringLazyListdeserialization 关于这个CVE的最详细的信息就是这位CVE发现者提交的issue,所以我能挖掘到的一切关于这个CVE的信息都是基于上面的POC环境和这个issue 利用条件 scala版本<2.13.9 允许用户伪造序列化字节流数据 前置知识 对于我本人来说,要钻透某个漏洞的话就必须要搞清楚是哪一步产生了漏洞,那么前提就是要了解这个漏洞产生流程的大框架,否则只针对链子上某点出现的反序列化干分析不仅枯燥难懂而且总感觉少了点什么 有Scala基础的师傅可以直接跳过这部分 Scala简介 Scala语言是一门多范式的编程语言,设计初衷是要集成面向对象编程和函数式编程的各种特性。Scala运行在Java虚拟机上,并兼容现有的Java程序。Scala源代码被编译成Java字节码,所以它可以运行于JVM之上,并可以调用现有的Java类库。 Scala和Java之间的联系很紧密,Scala可以看作是对Java语言的丰富和扩展,Scala比Java更加灵活和强大,支持更多的编程范式和语言特性,例如高阶函数、模式匹配、特质、偏函数、隐式转换等。 这个特性对于经验丰富的scala开发者来说很舒服,但对于第一次接触scala就要啃源码的人来说非常非常非常不友好,比如笔者 Scala也可以利用Java的丰富的生态系统,使用Java的各种框架和库。 Scala和Java之间的区别也很明显,Scala有自己的语法规则和风格,与Java有很多不同之处,例如变量声明、函数定义、类构造、异常处理、集合操作等。Scala还有一些Java没有的概念,例如伴生对象、样例类、富接口、自身类型等 基础语法即使不懂scala也差不多能看懂,所以不涉及语法糖或者比较新的机制的地方本篇文章不做论述 但scala代码的有些地方还是容易迷糊,所以在之后部分涉及到的语法看不懂的可以先自行学习一下 匹配器match Scala语言的匹配器match是一种强大的语法结构,它可以让你根据不同的条件对一个值进行分支处理,类似于Java中的switch语句,但是更加灵活和强大。 match的基本用法 // 定义一个值 val x = ... // 使用match对值进行匹配 x match { // 每个case表示一种匹配情况 case 条件1 => 结果1 // 如果x满足条件1,就返回结果1 case 条件2 => 结果2 // 如果x满足条件2,就返回结果2 ... case _ => 默认结果 // 如果x都不满足上面的条件,就返回默认结果,_表示任意值 }   当然,你也可以用其他字符表示默认结果,而与_的区别就是_作为接受其他情况的变量时不会赋予$值 object Main { def show(result:String):Unit={ println(result) } def main(args: Array[String]): Unit = { val x=11 val y=x match { case 1 => "one" case 2 => "two" case other => s"other: $other" // other是一个变量名,它会接收除了1和2以外的任何值 //case _ => s"other: $" //错误:Cannot resolve symbol _ } show(y) //other: 11   }} match可以匹配不同类型的值,比如整数、字符串、布尔值等,也可以匹配复杂的数据结构,比如列表、元组、样例类等。match还可以使用模式守卫来增加额外的判断条件,比如: x match { case 条件1 if 表达式1 => 结果1 // 如果x满足条件1,并且表达式1为真,就返回结果1 case 条件2 if 表达式2 => 结果2 // 如果x满足条件2,并且表达式2为真,就返回结果2 ...} match的其他用法 // 把match赋值给一个变量val result = x match { case 条件1 => 结果1 case 条件2 => 结果2 ...}   // 把match作为函数的参数def foo (y: Int) = {println (y)}foo (x match {case 条件1 => 结果1case 条件2 => 结果2...}) // 把match作为函数的返回值def bar (z: String): Boolean = z match {case "yes" => truecase "no" => falsecase _ => false}   总的来说,match是一个表达式,它有一个返回值 apply方法 apply方法是Scala中一个非常有用的特性,它可以让我们用一种简洁而直观的方式来创建和使用对象。 apply方法的本质是一个普通的方法,它可以定义在类或者对象中,但是它有一个特殊的语法糖,就是当我们用括号传递参数给一个类或者对象时,Scala会自动调用它的apply方法,并把参数传给它。 例如: // 定义一个类Person,有一个name属性class Person(val name: String)   // 定义一个伴生对象Person,有一个apply方法,接受一个name参数,返回一个Person实例object Person {def apply(name: String) = new Person(name)} // 创建一个Person实例,可以直接用Person("Alice"),而不需要用new Person("Alice")val alice = Person("Alice")//相当于Person.apply("Alice") // 打印alice的name属性,输出Aliceprintln(alice.name)   我们通过Person("Alice")这种方式创建了一个Person实例,而不需要用new关键字。这是因为Scala会把Person("Alice")转换成Person.apply("Alice"),也就是调用了伴生对象Person的apply方法,并把"Alice"作为参数传给它。这样就可以省略new关键字,让代码更简洁。 apply方法不仅可以定义在伴生对象中,也可以定义在类中。当我们对一个类的实例用括号传递参数时,Scala会调用该类的apply方法,并把参数传给它。 object Main {   def main(args: Array[String]): Unit = { class Person(val name: String){ //在类中定义apply方法,输出name def apply() :Unit = println(s"I am $name") } var p= new Person("lanb0") p()//相当于p.apply() //I am lanb0 }} 伴生对象 伴生对象是Scala中一种特殊的单例对象,它与一个同名的类存在于同一个文件中,这个类被称为伴生类。 伴生对象和伴生类之间有以下几个特点: 伴生对象和伴生类可以互相访问对方的私有成员,包括字段和方法。 伴生对象的成员相当于Java中的静态成员,可以直接通过对象名调用,而不需要创建对象实例。 伴生对象可以实现apply方法,用于创建伴生类的实例,这样就可以省略new关键字。 伴生对象可以实现unapply方法,用于实现模式匹配和提取器的功能。 伴生对象可以扩展一个或多个特质(trait),从而实现多重继承和混入(mixin)的效果。 下面是一个简单的例子,演示了伴生对象和伴生类的定义和使用: // 定义一个Person类,作为伴生类class Person(val name: String, val age: Int) { private val secret = "I love Scala"   def sayHello(): Unit = {println(s"Hello, I am $name, $age years old.")}} // 定义一个Person对象,作为伴生对象object Person { var count = 0 def increase(): Unit = {count += 1println(s"Person count: $count")} def showSec():Unit={println(apply("test",1).secret)} // 定义一个apply方法,用于创建Person类的实例def apply(name: String, age: Int): Person = {increase()new Person(name, age) // 返回新的Person对象} // 定义一个unapply方法,用于提取Person类的属性def unapply(person: Person): Option[(String, Int)] = {if (person == null) None // 如果person为空,返回Noneelse Some(person.name, person.age) // 否则返回Some元组}}object Main { def main(args: Array[String]): Unit = {// 使用伴生对象的apply方法创建Person类的实例,省略了new关键字val p1 = Person("Alice", 20)//Person count: 1val p2 = Person("Bob", 25)//Person count: 2 // 使用伴生对象的字段和方法 println(Person.count) // 输出2 Person.increase() // Person count: 3 Person.showSec()//输出Person count: 4 //I love Scala(伴生对象可以访问伴生类的私有成员) // 使用伴生类的字段和方法 /* println(p1.secret)// 无法访问私有成员 */ p1.sayHello() // 输出Hello, I am Alice, 20 years old. // 使用模式匹配和提取器,利用伴生对象的unapply方法 val p3=null p1 match { case Person(name, age) => println(s"$name is $age years old.") // 输出Alice is 20 years old. case _ => println("Unknown person.") } p3 match { case Person(name, age) => println(s"$name is $age years old.") // 输出Unknown person. case _ => println("Unknown person.") } }}   特质trait Scala语言中,有一个Scala语言中,有一个重要的概念叫做特质(trait),它类似于Java语言中的接口,但是比接口更加强大和灵活。 特质(trait)是一种定义了一组抽象或具体的属性和方法的类型,它可以被类(class)或对象(object)扩展(extends)或混入(mix in)。 特质可以实现多重继承,也就是说,一个类可以继承多个特质,从而获得所有特质中定义的属性和方法。 特质的定义和使用 特质的定义使用关键字trait trait PersonBody { val height: Int}     但是特质不能被实例化,因此特质没有参数,也没有构造函数。像trait PersonBody(170)或者new PersonBody(170)这样的写法就是错的,可以类比java的接口无法实例化 要使用特质,可以使用extends关键字来扩展一个或多个特质 扩展单个特质 object Main { trait PersonBody { var height: Int } class Person(name : String) extends PersonBody{ override var height: Int = 170 } def main(args: Array[String]): Unit = { var person = new Person("Cloud") println(person.height) //170 }} 注意,重写(实现)属性或方法时,需要使用override关键字来修饰 trait的方法声明必须被实现 扩展多个特质 使用with关键字来连接 object Main { trait PersonBody { var height: Int } trait PersonHobby{ var hobbyGame="Honor of King : World" def showHobby() } class Person(name : String) extends PersonBody with PersonHobby { override var height: Int = 170   override def showHobby(): Unit = { println(hobbyGame) } }def main(args: Array[String]): Unit = {var person = new Person("Cloud")person.showHobby() }}   with后面可以跟with,来扩展很多特质 object Main { trait PersonBody { var height: Int } trait PersonHobby{ var hobbyGame="Honor of King : World" def showHobby():Unit } trait PersonScore{ var math="150" def showScore():Unit } class Person(name : String) extends PersonBody with PersonHobby with PersonScore { override var height: Int = 170   override def showHobby(): Unit = { println(hobbyGame) } override def showScore(): Unit = { println(math) } } def main(args: Array[String]): Unit = { var person = new Person("Cloud") person.showHobby() person.showScore() }}/*输出Honor of King : World150*/ 自身类型self-type self-type表示一个类或特质依赖于另一个类型,即它必须和另一个类型混入(mixin)才能被实例化。 用一个简单的例子来解释Scala自身类型的概念。假设你有一个宠物猫,它有一些属性和行为,比如名字、颜色、叫声等。你可以用一个类来表示它: class Cat { val name: String = "Tom" val color: String = "Gray" def meow(): Unit = println("Meow!")} 现在,你想给你的猫添加一些新的功能,比如会说话、会唱歌、会跳舞等。你可以用特质来定义这些功能: trait Talkative { def talk(): Unit}   trait Singer {def sing(): Unit} trait Dancer { def dance(): Unit} 但是,这些功能并不是所有的猫都有的,只有一些特殊的猫才有。比如,只有会说话的猫才能唱歌,只有会唱歌的猫才能跳舞。你怎么表示这种依赖关系呢?你可以用自身类型来做到这一点: trait Talkative { def talk(): Unit}   trait Singer {self: Talkative => // 声明自身类型,表示Singer依赖于Talkativedef sing(): Unit = {talk() // 可以直接使用Talkative的成员println("La la la...")}} trait Dancer { self: Singer => // 声明自身类型,表示Dancer依赖于Singer def dance(): Unit = { sing() // 可以直接使用Singer的成员 println("Shake shake shake...") }} 这样,你就可以给你的猫混入这些特质,让它变得更有趣: val tom = new Cat with Talkative with Singer with Dancer // 创建一个会说话、唱歌、跳舞的猫tom.talk() // 输出:Meow!tom.sing() // 输出:Meow! La la la...tom.dance() // 输出:Meow! La la la... Shake shake shake... 但是,如果你试图给一个不会说话的猫混入Singer或Dancer特质,就会报错: val jerry = new Cat with Singer // 报错:illegal inheritance; self-type Cat with Singer does not conform to Singer's selftype Singer with Talkativeval lily = new Cat with Dancer // 报错:illegal inheritance; self-type Cat with Dancer does not conform to Dancer's selftype Dancer with Singer 这是因为自身类型注解限制了混入特质的对象必须满足依赖类型的条件。这样可以保证对象在使用特质的成员时不会出现错误。 惰性列表LazyList(重点) LazyList是Scala 2.13版本引入的新的集合类型,它是一种惰性求值的列表。惰性求值的意思是,列表中的元素只有在需要的时候才会被计算,而不是一开始就全部计算好。这样可以节省内存和时间,也可以表示无限的序列。 State,head及tail 名称 类型 作用 state 字段 存储LazyList对象的状态,表示惰性序列的结构和计算状态 State 特质 定义LazyList对象的状态的特质,有两个子类:Cons和Empty tail 方法 返回一个新的LazyList对象,包含除了第一个元素之外的所有元素,惰性求值 head 方法 返回LazyList对象的第一个元素,严格求值 State private sealed trait State[+A] extends Serializable { def head: A def tail: LazyList[A] } state private lazy val state: State[A] = { // if it's already mid-evaluation, we're stuck in an infinite // self-referential loop (also it's empty) if (midEvaluation) { throw new RuntimeException("self-referential LazyList or a derivation thereof has no more elements") } midEvaluation = true val res = try lazyState() finally midEvaluation = false // if we set it to true before evaluating, we may infinite loop // if something expects state to already be evaluated stateEvaluated = true lazyState = null // allow GC res } 通过lazyState()方法去计算State的head和tail,保证LazyList的实时状态正确 关键字lazy表示延迟计算,也就是使用到的时候才会计算出结果 工作原理(关键) 光看上面的这几个成员会让人很头大,所以我用了很长一段时间才把他们的内在联系和整个LazyList体系的运行机制搞明白了 首先,我们创建一个存有无限个数字"1"的LazyList val ones = LazyList.continually(1) 此时,我们println这个惰性列表,可以发现是全都没有计算的,会打印出LazyList(<not computed>) 之后,我们用drop方法取出第一个元素(索引为0),就要用到我们之前的head方法,返回LazyList对象的第一个元素。然后再次打印这个LazyList println(ones.drop(0).head)//1println(ones)//LazyList(1, <not computed>) 好了,到此结束,接下来我们分析一下LazyList的内部做了什么 内部流程 创建LazyList时,LazyList会接受一个参数lazyState(一般情况下用户不用管),这个lazyState是一个无参的匿名函数,这个匿名函数会返回一个State对象,这个State存储着head和tail方法 private sealed trait State[+A] extends Serializable { def head: A def tail: LazyList[A]} 这个匿名函数的head方法是:返回一个元素,这个元素是当前LazyList计算出的第一个元素 这个匿名函数的tail方法是: 返回一个新的LazyList,存储着除了第一个元素之外的其他元素(这里的"存储"并不是实际存在的,更恰当的说是表示其他元素的一个集合) 注意,此时匿名函数并没有被调用,也就是说state字段的head和tail都还没有实现 到目前为止,LazyList里面一个实际存储的元素都没有,所以会显示LazyList(<not computed>) 接下来,我们调用了方法来取出第一个元素 LazyList会使用state.head来获取第一个元素,此时需要用到state,所以懒加载的state字段开始初始化 private lazy val state: State[A] = { state字段在初始化过程中,会调用lazyState()方法,这个lazyState就是LazyList的构造器接受的那个匿名函数。 val res = try lazyState() finally midEvaluation = false lazyState方法执行完后会返回一个State对象,这个State的head方法返回数字1,而tail方法返回一个新的存着无限个1的LazyList LazyList使用state.head方法获取到结果之后,把结果返回给drop.head的方法调用者 之后,如果未来还要取新的元素,那么我们所使用的LazyList就是tail方法返回的那一个新的存有无限个1的LazyList,而刚开始创建的那个LazyList就被垃圾回收器收走了 通过这个流程,我们可以看出惰性列表的本质,就是不停地用方法去取值,而不是一开始就存着[1,1,1,1,1......]在内存中 LazyList如何实现序列化与反序列化(关键) SerializationProxy类,它是一个序列化代理,它是用来代替LazyList对象进行序列化和反序列化的类。 官方注解 翻译过来就是: 序列化代理用于将LazyList转换成一个可以存储或者传输的格式。 这个序列化代理适用于那些以一系列已经计算出来元素开头的LazyList。这些已经计算出来的元素会以一种紧凑的顺序格式进行序列化,然后跟着未计算出来的元素,它们使用标准的Java序列化方式来存储未计算出来的元素的结构。这样就可以实现对长的已经计算出来的惰性序列的序列化,而不会因为递归地序列化每个元素而耗尽栈空间。 序列化 private[this] def writeObject(out: ObjectOutputStream): Unit = { out.defaultWriteObject() var these = coll while(these.knownNonEmpty) { out.writeObject(these.head)//这里决定了POC里的createLazyList中,为什么需要设置一个空的state these = these.tail } out.writeObject(SerializeEnd) out.writeObject(these) } 流程可以分为以下几步: 调用out.defaultWriteObject()方法,这是一个标准的序列化操作 使用一个while循环遍历LazyList对象中已经计算出来的元素,并且使用out.writeObject方法将每个元素序列化 遇到第一个未计算出来的元素时,跳出循环 序列化一个特殊的标记SerializeEnd,表示已经计算出来的元素结束了 使用out.writeObject方法将未计算出来的元素(也就是LazyList对象的tail)进行序列化 序列化结束 反序列化 private[this] def readObject(in: ObjectInputStream): Unit = { in.defaultReadObject() val init = new ArrayBuffer[A] var initRead = false while (!initRead) in.readObject match { case SerializeEnd => initRead = true case a => init += a.asInstanceOf[A] } val tail = in.readObject().asInstanceOf[LazyList[A]] coll = init ++: tail } 流程可以分为以下几步: 调用in.defaultReadObject()方法,这是一个标准的反序列化操作。 创建了一个名为init的数组缓冲区,用来存储已经计算出来的元素。 使用一个while循环反序列化每个元素,并且判断是否是特殊的标记SerializeEnd。 如果不是,就将该元素添加到init数组缓冲区中; 如果是,就表示已经计算出来的所有元素都已经反序列化完了,跳出循环。 反序列化剩余的没有计算出的元素,并将其类型转换为LazyList 使用++:方法连接init和tail,重构LazyList 反序列化结束 漏洞分析 CVE-2022-36944的产生原因,简单来说就是scala的LazyList在反序列化时会调用一个无参匿名函数来更新LazyList的状态,而这个函数是是可以被控制的 首先是ObjectInputStream.readObject方法接受到伪造的序列化字节流之后,尝试反序列化LazyList,进而把控制权转交给SerializationProxy类的readObject方法 执行到++:方法, 跟进++:(没想到吧,我是个方法) 可以看到调用了prependedAll方法,但是在LazyList中重写了这个方法 跟进knownIsEmpty方法, 这里要让stateEvaluated为true,否则不会执行isEmpty方法 跟进isEmpty方法, 跟进state字段, 跟进LazyState函数,可以发现就是LazyList构造器接受的无参匿名函数 最终我们只需要提前将这个函数替换为符合条件的任意函数,就可以达到漏洞利用的效果 如何找到可利用的方法 从LazyList的构造器的参数定义中,可以看出,lazyState的要求是一个无参的匿名函数,其次这个CVE利用的是函数,并不能RCE,所以我们还需要找到标准java库或者scala库中可以使用的无参匿名函数 我们需要知道,在Scala中,所有无参匿名函数都会被编译器转换为实现了Function0接口的实例对象, 假如我们有以下代码: object Main { def main(args: Array[String]): Unit = { //定义一个匿名函数a val a=()=>{} }} 用scalac编译为class字节码 scalac Main.scala javap反编译 javap Main$.class scala编译器会为每一个伴生对象创建一个对象名(类名)+$结尾的类,类中的MODULE$静态成员就是伴生对象自身,存有自身的所有属性和方法 或者直接复制以下代码 object Main { class test(val func:()=>Int){ def show(): Unit = { func() } }} 然后Ctrl+左键查看func的类型信息 可以看到编译器自动将func所表示的匿名函数转换为了Function0的实现对象 那么接下来的任务,就是要找到实现了Function0的所有类 查看POC中的DefaultProviders类,发现使用的都是以$$anonfun$$lessinit$greater$x 结尾的类,这些类 scala.sys.process.ProcessBuilderImpl$FileOutput$$anonfun$$lessinit$greater$3scala.sys.process.ProcessBuilderImpl$FileInput$$anonfun$$lessinit$greater$2scala.sys.process.ProcessBuilderImpl$URLInput$$anonfun$$lessinit$greater$1 这里再稍微说一下这些类名是如何生成的,以scala.sys.process.ProcessBuilderImpl$URLInput$$anonfun$$lessinit$greater$1为例 Scala编译器在编译Scala代码时,会将匿名函数转换成Java字节码,这样就可以在Java虚拟机上运行。为了与Java兼容,Scala编译器会为每个匿名函数生成一个类,并给这个类一个特殊的名字,通常是anonfun加上一些数字和符号。这个类名的作用是唯一地标识这个匿名函数,以便在运行时调用。 $URLInput:表示ProcessBuilderImpl的内部类 $$anonfun:表示匿名函数的前缀,表示这是一个自动生成的类。 $$lessinit$greater:是<init>的转义形式,表示这个匿名函数是在构造器中定义的。 $1:是匿名函数的序号,表示这是第一个匿名函数。 去追踪一下这个类,发现最多只能看到URLInput类 那如果直接用URLInput行不行呢,尝试把代码改一下 public static Function0<Object> urlInput(Object[] args){ try { URL url = new URL((String) args[0]); return ReflectionUtil.newInstance("scala.sys.process.ProcessBuilderImpl$URLInput", new Class[]{ ProcessBuilder$.class, URL.class}, new Object[] { ProcessBuilder$.MODULE$,url});//这里要用ProcessBuilder的实例对象,否则报错 } catch (MalformedURLException e) { throw new RuntimeException(e); }   }   生成一下payload 发现报错,这是因为URLinput就是一个正常的类,而不是由Scala编译器转换过来的匿名函数,无法转换为Function0 所以说不能直接用URLinput作为利用方法 再回到scala.sys.process.ProcessBuilderImpl$URLInput$$anonfun$$lessinit$greater$1,以及URLInput类的那行定义, class URLInput(url: URL) extends IStreamBuilder(url.openStream(), url.toString) 猜测:当一个类继承了一个父类,并且这个被继承的父类的构造参数调用了子类构造参数的方法时,scala编译器会生成一个 带有$$anonfun$$lessinit$greater$类名的类。 做一个实验, class a(){ def msg(): String = { return "i am class a" }}class b (name:String)class c(url:a) extends b(url.msg()) 用sbt 生成字节码,查看生成的class 并没有生成带有$$anonfun$$lessinit$greater$类名的类,感觉还是忽略了什么 去查看IStreamBuilder类,也就是被URLInput继承的类, 发现其第一个构造参数如下 stream: => InputStream 这里的=>可不是()=>{}的简写,而是一个新的概念,叫做传名参数 传名参数是一种特殊的参数类型,它表示参数的值不是在函数调用时就确定,而是在函数体内每次使用时才计算。 可以理解为惰性求值,需要传入一个函数 更改实验代码: package zhb   class a(){ def msg(): String = { return "i am class a" }}class b (name: =>String)//这里注意冒号和等号之间的空格class c(url:a) extends b(url.msg()) clean一下,然后stb编译 多出来了c$$anonfun$$lessinit$greater$1.class, url.msg()即使改为一个带有参数的方法,也依然会生成同名类 观察其字节码可以发现其调用的a.msg() 到此为止,类比推理一下,我们终于明白scala.sys.process.ProcessBuilderImpl$URLInput$$anonfun$$lessinit$greater$1这个编译器自动生成的类其实就是url.openStream()方法转换而来的, 也就是说,在LazyList计算state时使用的LazyState(),经过我们精心构造后被替换为了url.openStream()方法 对应的可利用函数还有如下: 对于url.openStream(),虽然他自身并不是匿名函数,理应是一个函数返回值。 但是因为自己是被作为传名参数调用的,这个方法只会再被需要使用时执行,所以会存留方法的引用或者说实现。 object HelloWorld { def main(args: Array[String]) { def msg(): Unit = { println("msg used!") } class a(age: => Unit) {//传名参数 } new a(msg()) //什么都不会输出 }} 又因为是作为父类的构造参数,所以scala编译器会为父类的传名参数生成一个实现了Function0类的子类,即使这个参数的实现方法参数可能不为0 对于FileInputStream和FileOutputStream的new方法,同理 综上所述,CVE-2022-36944的可利用方法的符合条件如下: 1.作为传名参数被使用 2.满足(1)的同时,作为父类的构造参数 3.存在于受害者服务环境中的classpath中 有兴趣的师傅可以再找找有没有其他可利用方法 漏洞复现 poc.cve.lazylist.payload.Main更改为Base64方式输出 public class Main { public static void main(String[] args) throws IOException { ....   String base64=Base64.getEncoder().encodeToString(payload); System.out.println(base64); } } victim改为对Base64进行反序列化 public class Victim { public static void main(String[] args) throws IOException { String data="rO0........."; deserialize(Base64.getDecoder().decode(data));   } } urlInput 起一个http服务或者dnslog, public class Main { public static void main(String[] args) throws IOException { String fileToTruncate = "http://url"; PayloadGenerator payloadGenerator = new LazyList(DefaultProviders.URL_INPUT); byte[] payload = payloadGenerator.generatePayload(fileToTruncate); String base64=Base64.getEncoder().encodeToString(payload); System.out.println(base64);   } } 生成payload后,复制给poc.cve.lazylist.victim.Victim的data变量,执行 可以接受到http请求,但是无法弹shell fileOutput 这个payload可以用来清空文件内容,比如黑名单 或者打开一个追加流,但没什么用 比如我们创建一个waf.txt,随便写点东西 public class Main { public static void main(String[] args) throws IOException { String fileToTruncate = "文件的绝对路径"; PayloadGenerator payloadGenerator = new LazyList(DefaultProviders.FILE_OUTPUT); boolean append=false;//清空文件 byte[] payload = payloadGenerator.generatePayload(fileToTruncate,append); String base64=Base64.getEncoder().encodeToString(payload); System.out.println(base64);   } } 生成payload后,复制给poc.cve.lazylist.victim.Victim的data变量,执行后清空文件内容 fileInput 文件输入流是用来读取文件的,所以在不能使用方法的前提下没什么用 心得感悟 断断续续用了一周左右的时间,从对scala的代码都看不懂到写完这篇文章,期间走了很多弯路,甚至想放弃,直到现在都无法相信自己能硬啃下来这个CVE,所以说,坚持不一定有好的结果,但一定会有收获。 最后,请允许我以崇高的敬意给予挖掘0day的安全研究员们  ...

    2023-08-20 276
  • burpgpt:一款集成了OpenAI GPT的Burp Suite安全漏洞扫描扩展

    关于burpgpt burpgpt是一款集成了OpenAI GPT的Burp Suite安全漏洞扫描扩展,该扩展可执行额外的被动扫描以发现高度定制的漏洞,并支持运行任何类型的基于流量的分析。 burpgpt支持利用人工智能的力量来检测传统扫描工具可能遗漏的安全漏洞。它将网络流量发送到用户指定的OpenAI模型,从而在被动扫描工具中进行复杂的分析。该扩展提供了可定制的提示,使定制的网络流量分析能够满足每个用户的特定需求。 该扩展将在扫描完成后自动生成一份安全报告,并根据用户的提示和Burp发出的请求中的实时数据总结潜在的安全问题。通过利用人工智能和自然语言处理,该扩展简化了安全评估过程,并为安全专业人员提供了扫描应用程序或终端节点的更高级别概述。这使他们能够更容易地识别潜在的安全问题并优先进行分析,同时也覆盖了更大的潜在攻击面。 功能介绍 1、添加了被动扫描检查,允许用户通过占位符系统将HTTP数据提交到OpenAI控制的GPT模型进行分析。 2、利用OpenAI的GPT模型进行全面的流量分析,能够检测扫描应用程序中的安全漏洞之外的各种问题; 3、允许精确调整最大提示长度,可以对分析中使用的GPT令牌数量进行精细控制; 4、为用户提供多种OpenAI模型选择,使他们能够选择最适合自己需求的模型; 5、允许用户自定义提示,并释放与OpenAI模型交互的无限可能性; 6、与Burp Suite集成,为预处理和后处理提供所有本地功能,包括直接在Burp UI中显示分析结果,以实现高效分析; 7、通过本机Burp事件日志提供故障排除功能,使用户能够通过OpenAI API快速解决通信问题; 工具要求 1、Linux、macOS或Windows; 2、JDK v11+; 3、Burp Suite最新专业版或最新社区版; 4、Gradle v6.9+; 工具安装 首先,我们需要确保已经正确安装并配置好了Gradle。 接下来,使用下列命令将该项目源码克隆至本地: git clone https://github.com/aress31/burpgpt cd .\burpgpt</pre> 然后切换到项目目录中,构建单独的jar文件: ./gradlew shadowJar 现在,我们需要将扩展加载进Burp Suite中。首先,,我们需要切换到Extensions标签页并点击Add按钮,然后 选择.\lib\build\libs目录中的burpgpt-all jar文件并加载即可。 工具使用 广大研究人员需要在工具的设置面板中配置下列参数: 1、有效的OpenAI API密钥; 2、选择一个OpenAI模块; 3、定义max prompt大小; 4、根据需求调整提示: 配置完成后,即可执行扫描并发送请求,随后工具将生成分析结果: 工具使用样例 识别Web应用程序(使用了包含安全漏洞的加密库)中的潜在安全漏洞: Analyse the request and response data for potential security vulnerabilities related to the {CRYPTO_LIBRARY_NAME} crypto library affected by CVE-{CVE_NUMBER}:         Web Application URL: {URL}   Crypto Library Name: {CRYPTO_LIBRARY_NAME}   CVE Number: CVE-{CVE_NUMBER}   Request Headers: {REQUEST_HEADERS}   Response Headers: {RESPONSE_HEADERS}   Request Body: {REQUEST_BODY}   Response Body: {RESPONSE_BODY}       Identify any potential vulnerabilities related to the {CRYPTO_LIBRARY_NAME} crypto library affected by CVE-{CVE_NUMBER} in the request and response data and report them. 通过分析跟身份验证过程相关的请求和响应来扫描Web应用程序中的安全漏洞(使用了生物身份验证技术): Analyse the request and response data for potential security vulnerabilities related to the biometric authentication process:     Web Application URL: {URL}   Biometric Authentication Request Headers: {REQUEST_HEADERS}   Biometric Authentication Response Headers: {RESPONSE_HEADERS}   Biometric Authentication Request Body: {REQUEST_BODY}   Biometric Authentication Response Body: {RESPONSE_BODY}   Identify any potential vulnerabilities related to the biometric authentication process in the request and response data and report them. 分析无服务器功能之间交换的请求和响应数据以发现潜在的安全漏洞: Analyse the request and response data exchanged between serverless functions for potential security vulnerabilities:     Serverless Function A URL: {URL}   Serverless Function B URL: {URL}   Serverless Function A Request Headers: {REQUEST_HEADERS}   Serverless Function B Response Headers: {RESPONSE_HEADERS}   Serverless Function A Request Body: {REQUEST_BODY}   Serverless Function B Response Body: {RESPONSE_BODY}   Identify any potential vulnerabilities in the data exchanged between the two serverless functions and report them. 通过分析请求和响应数据,扫描针对单页应用程序(SPA)框架潜在的安全漏洞: Analyse the request and response data for potential security vulnerabilities specific to the {SPA_FRAMEWORK_NAME} SPA framework:     Web Application URL: {URL}   SPA Framework Name: {SPA_FRAMEWORK_NAME}   Request Headers: {REQUEST_HEADERS}   Response Headers: {RESPONSE_HEADERS}   Request Body: {REQUEST_BODY}   Response Body: {RESPONSE_BODY}   Identify any potential vulnerabilities related to the {SPA_FRAMEWORK_NAME} SPA framework in the request and response data and report them. 许可证协议 本项目的开发与发布遵循Apache-2.0开源许可证协议。 项目地址 burpgpt:【GitHub传送门】 参考资料 https://burpgpt.app/ https://github.com/aress31/burpgpt#example-use-cases  ...

    2023-08-20 250

联系我们

在线咨询:点击这里给我发消息

QQ交流群:KirinBlog

工作日:8:00-23:00,节假日休息

扫码关注