Posts List

博客考古:从漏洞、工具到生活折腾

前言 # 最近翻了一下自己的博客,感觉像是在翻一个大型考古现场。 有些文章现在看还挺有意思,有些文章则属于“当年我为什么会写这个”的系列。早期有不少内容就是学习笔记,甚至有些只是把一个小问题解决了顺手记一下。现在再把这些文章全部端上来,其实没什么意义。毕竟人总不能一直回味自己当年怎么配置环境、怎么写第一个 demo。 所以这篇文章不打算做一个完整目录。完整目录这种东西博客本身已经有了,再写一遍除了显得勤奋,其实也没啥用。这里更像是笔者给自己做一次“技术路线复盘”:哪些文章代表了一个阶段,哪些东西后来真的影响了我的方向,哪些坑虽然当时痛苦,但现在回头看也挺值。 简单来说,这篇文章不是“我的全部文章总结”,而是“我觉得还值得拿出来说几句的文章”。 安全:从看热闹到修系统 # 安全应该是这个博客后面最主要的内容。最开始写 XSS、CSRF、SSRF 的时候,更多还是在分析一个个具体漏洞。这个参数怎么进来的,为什么能打到页面,为什么这里能绕过,为什么框架没有兜住。那时候写漏洞文章,会有一种解谜的快感。 但写着写着就会发现,漏洞分析最有意思的地方不是 payload 本身,而是背后的错误假设。开发以为这里不会被外部访问,浏览器以为自己只负责执行规则,框架以为开发者知道自己在干什么,最后大家都觉得自己没问题,问题就出来了。 比如 XSS 这类问题,很多时候不是“不知道要过滤”这么简单,而是你要理解数据从输入到展示到底经过了多少层。富文本、模板、DOM、编码、浏览器解析,每一层都可能有自己的脾气。SSRF 和开放重定向也类似,它们会不断提醒你:系统边界从来不是你画在架构图上的那条线。 后来写 MyBatis、GORM、Kibana、Webpack 这些文章,关注点就更偏开发侧了。很多漏洞并不是因为技术多高深,而是大家太相信默认行为了。ORM 很好,框架也很好,但框架不会替你理解业务,也不会替你判断输入是否可信。这个道理听起来简单,真到代码里就不一定了。 相关文章导航: XSS 漏洞知解 123 富文本场景下的 XSS 偶遇 XSS 漏洞 跨站请求伪造(CSRF)攻击 服务端请求伪造(SSRF)攻击 白名单,被谁饶过了? MyBatis 和 SQL 注入的恩恩怨怨 AI 审代码,靠谱吗? 让你的SQL盲注快起来 Kibana 任意代码执行漏洞 hey,我能看到你的源码哎 黑产代码解密–利用canvas加载代码 使用浏览器作为代理从公网攻击内网 ChatGPT账户接管 - 通配符网页缓存欺骗 通过 Cookie Tossing 劫持 OAUTH 流程 安全工程:不只是把洞挖出来 # 只会发现漏洞是不够的。这个道理说起来很简单,但真正做企业安全的时候会特别明显。 如果一个漏洞提上去之后没人修,或者责任人不准,或者状态没人跟,或者修完没人验证,那这个漏洞和写在本子上的愿望差不多。安全真正麻烦的地方,往往不是技术本身,而是怎么把事情推进下去。 这也是为什么我后来写了 GShark、安全运营平台、被动扫描器、Burp 插件、Zeek、Qradar、SAST 这些内容。它们看起来不像单个漏洞那么刺激,但更接近实际工作。安全运营平台那篇其实印象挺深,倒不是因为技术多复杂,而是因为需求太碎。各种角色、权限、状态、通知、资产、漏洞、事件,像一堆线头缠在一起。你不把它们一根根捋顺,后面就会一直打结。 GShark 也是类似。一开始只是想监测 GitHub 敏感信息,后面慢慢就会想到 GitLab、SearchCode、权限、任务、前端体验、误报处理。安全工具做着做着,最后都会变成工程问题。工具能不能长期跑,能不能让别人愿意用,能不能降低处理成本,这些问题比写一个扫描规则更难。 相关文章导航:

大佬,您这是在借鉴嘛

今天闲来没事看到一篇文章,感觉质量挺好的,就想翻译一下。之前写过一个将文档导出成 markdown 的插件,因为这个插件一开始是为了翻译 Medium 文章开发的,但是后来因为 Medium 的 json 接口启用了,所以这个插件后面也不怎么维护了。不搜不知道,一搜吓一跳,居然发现一个和插件差不多的插件,不会吧,这么烂的插件也有人抄?后来仔细看了一看,这个大佬应该是在借鉴我的插件,辛苦地改了几个中文。 两款插件名名字几乎一模一样,只是这个借鉴者加了一个后缀:掘金翻译计划版。不确定和掘金有没有关系,我知道掘金是有一个翻译项目的,以前我也参与过。 对比 # 插件介绍 # 我的插件 # 李鬼插件 # 代码对比 # 上面的简洁基本上已经展现了浓重的李鬼味道,本着客观严谨的态度,我还是去看了一下代码。 我的插件 # 李鬼插件 # 除了一个 js 文件的引用,几乎可以说是一模一样了。核心的文件是 widget.js 这个文件,这个属于插件自身的 js 文件。 从这代码对比,可以看得出这个借鉴者巨大的工作量。 总结 # 鄙人的这款插件是在 GitHub 上开源的,当时也是出于个人需求搞得这么个小玩意,但是没想到居然还有李鬼借鉴,还真是离谱他妈给离谱开门。大家如果有空的话,还是动一下发财的小手点一下 Report,这个李鬼插件还是下架比较好。我也联系了这个开发同学,希望他能及时下架。

火眼红队工具遭窃

原文:Unauthorized Access of FireEye Red Team Tools 译者:madneal welcome to star my articles-translator, providing you advanced articles translation. Any suggestion, please issue or contact me LICENSE: MIT 概述 # 一个由国家支撑的顶尖的竞争者窃取了火眼的红队工具。 因为我们认为竞争者已经拥有这些工具,并且我们不知道攻击者是否打算自己使用被盗的工具还是公开披露它们,所以火眼在此博客中发布了数百种对策,以使安全社区能够保护自己免受这些工具的攻击。我们已将防御策略整合到我们的火眼产品中,并与合作伙伴,政府机构共享了这些策略,以显着限制不良行为者利用红队工具的能力。 您可以在这火眼的 GitHub 仓库中找到策略列表。 红队工具和技术 # 红队是一组经过授权和组织的安全专家,模仿潜在的对手针对企业安全状况的攻击或利用能力。我们的红队的目的是通过演示成功攻击的影响并向防御者(即,蓝队)展示防御方法,以改善企业网络安全。过去15年来,我们一直在为全球客户进行红队评估。截至目前,我们已经建立了一套脚本,工具,扫描器和技术,以帮助改善客户的安全状况。不幸的是,这些工具被顶尖攻击者窃取。 被盗工具的范围从用于自动化侦察的简单脚本到类似于 CobaltStrike和 Metasploit 等公开可用技术的整个框架。许多红队工具已经发布给社区,并已分发到我们的开源虚拟机 CommandoVM 中。 其中一些工具是公开可用的工具,经过修改可以逃避基本的安全检测机制。其它的工具和框架是我们红队内部定制开发。 没有零日漏洞或者未知技术 # 攻击者窃取的红队工具不包含零日漏洞。这些工具采用了世界各地其他红队所使用的众所周知且有据可查的方法。尽管我们认为这种盗窃不会大大提高攻击者的整体能力,但火眼会尽一切努力防止这种情况的发生。 请务必注意,火眼尚未看到任何对手散布或使用这些工具,我们将继续与安全合作伙伴一起监视任何此类活动。 有益于社区的检测 # 为了使社区能够检测到这些工具,我们正在发布防御策略,以帮助组织识别这些工具(如果它们在野出现)。为了应对我们的红队工具的盗窃,我们针对 OpenIOC,Yara,Snort 和 ClamAV 等公开可用技术发布了数百种对策。 可在此处找到火眼 GitHub 仓库上的对策列表。我们将发布检测,并将随着我们开发新的或改进现有检测的主机,网络和基于文件的指标的重叠对策而继续更新公共存储库。 此外,我们在 GitHub 页面上发布了需要解决的 CVE 列表,以限制红队工具的有效性。 火眼产品能够帮助客户免于这些工具攻击 # 火眼的各个团队都在努力制定对策,以保护我们的客户和广大社区。 我们已将这些对策整合到我们的产品中,并与我们的合作伙伴(包括国土安全部)共享了这些对策,这些合作伙伴已将这些对策纳入其产品中,从而为社区提供了广泛的覆盖范围。 有关可用的检测签名的更多信息,可以在GitHub仓库中找到。

Wmic 使用中的一些问题

Wmic, 即 Windows Management Instrumentation Command-Line Utility,通过这个工具我们可以获取计算本地的很多信息。 起源 # 我起初是希望写一个 bat 脚本来获取计算机安装的程序和功能列表以及计算机最近安装的一些补丁信息。程序和功能列表以及补丁信息可以通过计算机的控制面板去查看,但是这样一点都不 geek,能用脚本解决的当然要用脚本去解决啦。 程序和功能 # 通过 wmic product 我们可以获取程序和功能的安装信息。 wmic product get name,description 这样我们就可以获取计算机上安装的程序和功能列表以及其相应的描述。当然除了 name 以及 description 之外我们还可以使用 vendor 以及 version 来获取程序的厂商名称以及对应的版本号。另外,如果我们希望把结果导入到 txt 文件中,我们还可以使用万能的管道符号: wmic product get name, description > products.txt 这样我们就可以获取结果的 txt 文件,是不是很方便。然而,当我们将使用 wmic 导出的结果和控制面板中的程序和功能相比较的话,我们会发现有些程序没有出现在结果中,比如 Google Chrome。 通过 wmic 只能获取大部分程序列表,它们的安装包一般都是使用 Windows Installer 制作的,安装过程中调用 Windows Installer 服务进行安装。但是 Windows Installer 并不是唯一的制作安装包的工具,因此 wmic 往往可能获取的还不是完整的程序和功能列表。至于完整的程序和功能列表,可以参考这篇文章。 补丁信息 # 经常我们需要获取计算机的补丁安装情况。通过 systeminfo 可以获取一部分补丁安装信息,但是信息一般比较少。在这里,我们依然可以通过使用 wmic 来获取补丁安装信息。 wmic qfe list full

通过七牛云建立私有图床

七牛云是国内一家领先的云存储公司,可以利用七牛云存储对象存储图片。虽然现在各种图床,但还是希望能够搭建一个私有的图床。所以一直有希望使用七牛云搭建图床的想法,之前一直没有好好地看懂七牛云的 SDK,后来在仔细地看了一遍之后,终于知道如何利用官方的 SDK 来实现图片上传。过年在家花了一点时间,后来陆续也写了一点,完成了这个七牛云图床 chrome 拓展。 注册账户 # 首先你可以通过这个链接注册你的七牛云账户。在成功注册账户之后,可能还需要绑定手机号,你就可以创建存储空间,可以理解成为文件存储的文件夹。 创建好存储空间(bucket)就已经完成了私有图库的第一步。 开发 # 在这也会对所有代码一一解释,主要是讲解一下在开发中遇到的一些问题。首先基于七牛云存储开发,有必要学会七牛云存储 API 的使用。可以在官方 SDK 文档获取所有文档。本拓展的开发主要是基于 js 来进行开发,因此我们只需要了解 js SDK 文档。 文档中提到了一点:JS-SDK 依赖服务端颁发 token,可以通过以下二种方式实现: 利用七牛服务端 SDK 构建后端服务 利用七牛底层 API 构建服务,详见七牛上传策略和上传凭证(https://developer.qiniu.com/kodo/manual/1208/upload-token) 第一个方法还需要搭建服务器来颁发 token,显然这种方法不太经济,如果仅仅是为了这个图床搭建一个后端服务,就不太划算了。因此,我选择第二种,在客户端来生成 token。这种方法就需要你了解上传策略以及上传凭证。 上传策略是资源上传时附带的一组配置设定。通过这组配置信息,七牛云存储可以了解用户上传的需求:它将上传什么资源,上传到哪个空间,上传结果是回调通知还是使用重定向跳转,是否需要设置反馈信息的内容,以及授权上传的截止时间等等。上传策略主要是 scope 和 dealine 这两个字段是必须要的。scope 是指定上传的目标资源空间 Bucket 和资源键 Key,这里我们只需要设置 bucket。deadline 是上传凭证有效截止时间。Unix时间戳,单位为秒。该截止时间为上传完成后,在七牛空间生成文件的校验时间,而非上传的开始时间,官方建议建议设置为上传开始时间 + 3600s。 function genPolicy(scope) { let policy = { scope: scope, deadline: (new Date()).getTime() + 3600 } return policy; } 按照上述算法流程构建客户端的上传 token,官方有提供上传凭证的在线示例,通过整理形成了自己的 token.js。 完成本地 token 的,我的开发就完成了一大步。这个拓展需要两个界面的设置,就是包括图片上传页面以及七牛云存储配置页面。关于这两个页面的设计,我也就不一一赘述,主要讲几点: 七牛云信息存储 # 为了上传图片,我们需要配置 AK,SK,bucket 以及 domain。这些都可以在七牛云的控制台里面获取,因此我们需要在首次打开拓展的时候检查是否具有这些数据。至于这些配置信息保存在什么地方,一开始打算采取的是 chrome.storage 来进行存储,这样做的好处是可以利用账号同步数据,但缺点是操作不方便,是异步的。后来还是决定使用 localStorage,一来使用起来非常方便,二是我们并不是特别需要账号同步。因此,我们首先会检查配置信息是否存储在 localStorage,否则就打开配置页:

你可能不知道谷歌浏览器开发工具的其他用处

原文链接 原文链接似乎翻墙才可以访问 译者:neal github: https://github.com/neal1991 你可能不知道谷歌浏览器开发工具的其他用处 Chrome内嵌开发者工具。它具有丰富的功能特色,比如元素,网络以及安全。今天,我们将完全关注javascript的console. 当我才开始编程的时候,我只是将console用作纪录服务器的响应。但是后来经过一些教学的帮助,我开始发现console可以做的更多。 在这我们讲一些你可以用console做更多有用的事情。如果你是用chrome浏览这篇文章,你可以马上就试试效果。 选择节点元素 如果你熟悉jquery的话,你应该知道$(’.class’)和$(’#id’)事多的么的重要。你可以根据id或者类名选择相应的元素。 同样你可以在console使用同样的方式来访问元素。$(’tagName’) $(’.class’) $(’#id’)和document.querySelector(’’)是等同的。这个将返回文档中第一个匹配这个选择器的元素。 你可以用$$(’tagName’)来访问,注意这边的两个美元符号可以访问所有符合这个选择器的元素。这些元素会组成一个数组 2.将你的浏览器转化成一个编辑器 你是否想过可以直接在浏览器中直接编辑?答案是肯定的,你可以将你的浏览器转化成一个文本编辑工具。你可以在dom元素中任意添加或者删除文本。 你不需要检测html中的元素。取而代之,你只要去console里面输入以下: document.body.contentEditable = true 3.寻找dom中元素绑定的事件 当调试的时候你可能希望知道dom元素中绑定的事件。console工具能使你很轻松就找到这些事件。getEventListeners($(‘selector’))将会返回一个数组包含所有事件的对象。你可以展开这个对象看到所有的事件: 如果希望找到某个特定事件的监听,你可以这么做: getEventListeners($(‘selector’)).eventName[0].listener 这将展示所有和这个事件相关的监听。比如: getEventListeners($(’.firstName’)).click[0].listener 4.监听事件 如果你想监听特定元素绑定的事件的时候,你也可以在console里面这么做。你可以使用以下的这些命名: monitorEvents($(‘selector’))将会监听符合这个选择器的元素的所有事件,并且将会显示这些事件当事件被触发的时候。 monitorEvents($(‘selector’),’eventName’)将会监听符合这个选择器的特定事件。你可以将事件的名称作为一个参数传入到这个函数中。 monitorEvents($(‘selector’),[’eventName1’,’eventName2’….])将会监听符合这个选择器的事件。 unmonitorEvents($(‘selector’))这个会停止监听并且在console里面显示出所有的事件。 5.找到语句块执行的时间 console里面有一个很重要的函数叫做console.time(’labelTime’)能够启动一个计时器。另外又一个函数叫做console.timeEnd(’labelName’)能够结束相应的计时器。 比如我们想看到一个循环的执行时间,我们可以做如下处理: console.time('myTime'); //Starts the timer with label - myTime for(var i=0; i < 100000; i++){ 2+4+5; } console.timeEnd('mytime'); //Ends the timer with Label - myTime //Output - myTime:12345.00 ms 6.将变量的值以表格形式呈现 当我们有如下的一个数组的时候: var myArray=[{a:1,b:2,c:3},{a:1,b:2,c:3,d:4},{k:11,f:22},{a:1,b:2,c:3}] 我们可以使用console.table(variableName)从而以表格的形式更好地展现数据的属性。

sftp没有关闭session导致服务器sshd进程未关闭

项目中需要用Sftp上传下载文件,通过jsch中的sftp实现。代码上了服务器之后,发觉服务器多了很多进程没有被关闭。 连接sftp代码: protected boolean connectToServer() { try { JSch jsch = new JSch(); jsch.getSession(userName, hostname, port); Session sshSession = jsch.getSession(userName, hostname, port); logger.debug("HostName:" + hostname + "|Port:" + port); logger.debug("Session created"); sshSession.setPassword(password); Properties sshConfig = new Properties(); sshConfig.put("StrictHostKeyChecking", "no"); sshSession.setConfig(sshConfig); sshSession.setTimeout(TIMEOUT); //ms sshSession.connect(); sftp = (ChannelSftp) sshSession.openChannel("sftp"); sftp.connect(); if (!sftp.isConnected()) { logger.error("Failed to connect FTP server " + hostname); return false; } logger.debug("Username:" + userName + "|Password:" + password); } catch (Exception ex) { logger.error(ex); } return true; } 其实每次执行完都会

常用的正则表达式

正则表达式的用处很多,在很多地方都可以用得到,下面介绍一些常用的正则表达式 一、校验数字的表达式 数字:^[0-9]*$ n位的数字:^\d{n}$ 至少n位的数字:^\d{n,}$ m-n位的数字:^\d{m,n}$ 零和非零开头的数字:^(0|[1-9][0-9]*)$ 非零开头的最多带两位小数的数字:^([1-9][0-9]*)+(.[0-9]{1,2})?$ 带1-2位小数的正数或负数:^(-)?\d+(.\d{1,2})?$ 正数、负数、和小数:^(-|+)?\d+(.\d+)?$ 有两位小数的正实数:^[0-9]+(.[0-9]{2})?$ 有1~3位小数的正实数:^[0-9]+(.[0-9]{1,3})?$ 非零的正整数:^[1-9]\d*$ 或 ^([1-9][0-9]){1,3}$ 或 ^+?[1-9][0-9]$ 非零的负整数:^-[1-9][]0-9″$ 或 ^-[1-9]\d$ 非负整数:^\d+$ 或 ^[1-9]\d*|0$ 非正整数:^-[1-9]\d*|0$ 或 ^((-\d+)|(0+))$ 非负浮点数:^\d+(.\d+)?$ 或 ^[1-9]\d*.\d*|0.\d*[1-9]\d*|0?.0+|0$ 非正浮点数:^((-\d+(.\d+)?)|(0+(.0+)?))$ 或 ^(-([1-9]\d*.\d*|0.\d*[1-9]\d*))|0?.0+|0$ 正浮点数:^[1-9]\d*.\d*|0.\d*[1-9]\d*$ 或 ^(([0-9]+.[0-9][1-9][0-9])|([0-9][1-9][0-9].[0-9]+)|([0-9][1-9][0-9]))$ 负浮点数:^-([1-9]\d*.\d*|0.\d*[1-9]\d*)$ 或 ^(-(([0-9]+.[0-9][1-9][0-9])|([0-9][1-9][0-9].[0-9]+)|([0-9][1-9][0-9])))$ 浮点数:^(-?\d+)(.\d+)?$ 或 ^-?([1-9]\d*.\d*|0.\d*[1-9]\d*|0?.0+|0)$ 二、校验字符的表达式 汉字:^[\u4e00-\u9fa5]{0,}$ 英文和数字:^[A-Za-z0-9]+$ 或 ^[A-Za-z0-9]{4,40}$ 长度为3-20的所有字符:^.{3,20}$ 由26个英文字母组成的字符串:^[A-Za-z]+$ 由26个大写英文字母组成的字符串:^[A-Z]+$ 由26个小写英文字母组成的字符串:^[a-z]+$ 由数字和26个英文字母组成的字符串:^[A-Za-z0-9]+$ 由数字、26个英文字母或者下划线组成的字符串:^\w+$ 或 ^\w{3,20}$ 中文、英文、数字包括下划线:^[\u4E00-\u9FA5A-Za-z0-9_]+$ 中文、英文、数字但不包括下划线等符号:^[\u4E00-\u9FA5A-Za-z0-9]+$ 或 ^[\u4E00-\u9FA5A-Za-z0-9]{2,20}$ 可以输入含有^%&’,;=?$\”等字符:[^%&’,;=?$\x22]+ 禁止输入含有的字符:[^\x22]+ 三、特殊需求表达式 Email地址:^\w+([-+.]\w+)@\w+([-.]\w+).\w+([-.]\w+)*$ 域名:[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+/.? InternetURL:[a-zA-z]+://[^\s]* 或 ^http://([\w-]+.)+[\w-]+(/[\w-./?%&=]*)?$ 手机号码:^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$ 电话号码(“XXX-XXXXXXX”、”XXXX-XXXXXXXX”、”XXX-XXXXXXX”、”XXX-XXXXXXXX”、”XXXXXXX”和”XXXXXXXX):^($$\d{3,4}-)|\d{3.4}-)?\d{7,8}$ 国内电话号码(0511-4405222、021-87888822):\d{3}-\d{8}|\d{4}-\d{7} 身份证号(15位、18位数字):^\d{15}|\d{18}$

http响应代码解释

200:成功响应 302:找到,但是请求的资源在另外一个不同的url中。 400:错误请求。这个请求不能被服务器所理解,客户端必须修改请求。 401:未认证,这个请求需要用户认证。 404:未找到。服务器没有找到任何和这个请求符合的资源。

markdown语法规则

标题 标题是每篇文章最常用的格式,在markdown中如果要定义标题的话,只要在这段文字之前加#号就可以了。 一级标题 # 二级标题 # 三级标题 # 以此类推,总共六级标题,建议在#号之后加上一个空格,这是标准的markdown语法。 列表 列表主要分为有序列表和无序列表。只需要在文字前加上-或*即可变成无序列表,有序列表直接在文字前加上1. 2. 3. 符号和要在文字之前加一个空格就可以了。 1 2 3 1 2 3 引用 如果你要饮用一段话的话,那么你只要在引用的文字前加上>这种尖括号就可以了 这是我要引用的文字 图片和链接 插入链接和图片的方法很像,区别在于一个感叹号 图片为: {ImgCap}{/ImgCap} 链接为: 粗体和斜体 粗体和斜体也很简单,用两个包含一段文本就是粗体的语法,用一个包含一段文本就斜体的语法。 这是粗体 这是粗体 表格 Tables are cool col1 clo2 col3 分割线 分割线的语法只需要三个*号就可以了 分割线上 分割线下