逻辑:
1.课程详情页加载后,用token判断用户是否登录,登录状态则调用checkAuth的接口(只传入courseId),后端会返回hasAuth为true/false
2.点击某一章节时,登录状态则调用checkAuth的接口(传入courseId & chapterId),后端会返回hasAuth为true/false和videoId,如果这俩都有,则跳页面到视频播放页
3.跳转到视频播放页,加载完毕:请求课程详情接口、getPlay接口(传入courseId & chapterId)——后端返回formt,videoURL,duration等
功能:
4.自动跳转至上次播放时间:
加载完视频播放页,调checkHistory得到上次的记录——接着使用视频控制进度的组件uni.createVideoContext的seek方法,将checkHistory返回的lastTime传入
5.记录播放历史:
video标签上绑定@timeupdate方法,这个方法在播放进度变化时触发,也就是只要在播放就在不停的触发,所以每次进入方法都this.timer++,当它等于25时也就是每隔6s,调用recordHistory记录播放进度的接口,并使this.timer变回为1
6.倍速播放:
下载f-drop-menu插件,绑定videoList,以及changeSpeed事件,使用视频控制进度的组件uni.createVideoContext的playbackRate方法
7.下一节/重学一次
在data中,分别用new Map来new空的实例对象 ,Map字典数据结构是为了方便以[键,值]的形式存储数据,给每个小节做标记。
在初次进入视频页,调课程详情接口时,返回的数据是章嵌套节的结构。所以先循环章,再循环节,将这个实例对象使用set方法,将小节信息设置成键值对的数组,目的是为了给每个小节做标记。
给video绑定了ended事件——在播放结束时用这个实例对象的get方法查找读取key对应的键值,找到下一个章节对应的信息。
判断——如果下个章节有内容,就提示下一节/重学的选项。
8.视频防盗
在video标签中加上视频来源,否则后端会判断为为非法入侵。
<template> <view class="course-play"> <u-navbar title="视频" class="header"></u-navbar> <video id="myVideo" :src="videoUrl" controls :header="{'Referer':'http://testapp.cn'}" :poster="cover" @timeupdate="timeupdate" @ended="playEnded" class="video-play"></video> <view class="video-control"> <view class="" @tap="dropSpeed">倍速:{{speed}}</view> <f-drop-menu :list="videoList" v-model="show" @click="changeSpeed"></f-drop-menu> </view> <view class="tabs"> <u-tabs-swiper ref="uTabs" :list="list" :current="current" @change="tabsChange" :is-scroll="false" swiperWidth="750"></u-tabs-swiper> </view> <swiper class="swiper" :current="swiperCurrent"> <swiper-item class="swiper-item"> <scroll-view scroll-y style="height: 800rpx;width: 100%;"> <u-collapse accordion class="
来源 | https://xuxin123.com/web/vue3-directive
不知道大家在工作中用上vue3了没有,vue3好是好,但是有部分插件并没有更新到3.0的,比如我比较喜欢的自定义滚动条overlayscrollbars,vue3直接使用overlayscrollbars-vue会报错,今天我们主要介绍一下如何使用指令来应用这些插件,自定义滚动条overlayscrollbars以及拖拽sortablejs。
directive 指令的话这里就不多说了,参考官方文档(https://v3.cn.vuejs.org/api/options-assets.html#directives),overlayscrollbars以及sortablejs都是提供了js方式调用的,我们可以在指令里面进行插件的初始化。
main.js:
import { createApp } from 'vue' import directive from './directive' const app = createApp(App) directive(app) directive:
import { Sortable } from 'sortablejs' import 'overlayscrollbars/css/OverlayScrollbars.css' import OverlayScrollbars from 'overlayscrollbars' export default function(app) { app.directive('focus', { mounted(el) { el.focus() } }) app.directive('sortable', { mounted(el, binding) { const config = binding.value new Sortable(el, config || {}) } }) app.directive('OverlayScrollbars', { mounted(el, binding) { const config = binding.
网站如何让别人访问?很多新手用户看着网上的那些网站很羡慕,不知道网站怎么才能让别人看见,并可以访问,尤其是很多想要做属于自己的网站的,下面我们就来聊聊看自己做的网站如何才能让别人在互联网上访问。
要想别人在互联网上能访问到你的网站,首先你需要了解一些关于互联网网站方面的知识。网站访问流程:
1、当用户在浏览器输入网址
2、点击确认
3、网址跳转到对应的网页上
或者:
1、打开浏览器搜索关键词
2、找到你的网站并点击
3、跳到对应的网站页面
即可完成访问。
网站被访问的原理
网站访问背后的原理大致如下:
1、在浏览器输入网址
2、首先在浏览DNS缓存中查询有没有对应的IP和端口
3、接着在本地HOST缓存查询DNS信息
4、进入路由器中查询DNS缓存信息(如果未查到对应的DNS缓存信息,那么接着会在本地首选的DNS服务器查询DNS缓存信息)
5、进入根域名服务器查询DNS缓存信息(全球共13台)
6、接着进入顶级域名查询DNS缓存信息
7、进入主域名查询DNS信息
8、查询对应的DNS信息后,通过IP之地和端口去访问对应的资源(TCP连接3次:第一次建立连接,第二次发送http、get、post等报文,第三次浏览器获取http响应报文)
9、服务器端收到浏览器访问请求,首先判断是否合法,然后接受或拒绝访问
10、接受访问,读取http报文并解析
11、加载网站资源(如果是静态资源,则加载对应的html、css、img等服务器端对应的资源,如果是动态资源,则通过cgi或者fastcgi协议,启动php-fpm程序、php-fpm加载配置文件php.ini,然后php-fpm对php代码进行处理,最后按cgi或fastcgi格式返回处理结果)
12、最后wed服务器返回http报文信息
完成访问。
简单的说,用户如果要使得自己的网站能在互联网上能让别人访问到,首先需要域名、网站程序、服务器三类,缺一不可。域名绑定服务器,网站模板放在服务器里面,然后通过访问域名、让服务器加载网站模板并展现给用户浏览,可以说服务器是网站在互联网上运行的基础。
举例:域名相当于互联网上家的牌子,比如那谁谁家在哪(IP相当于详细地址,这个域名需要解析到IP上),网站程序就相当于家的样子,服务器就相当于你这个家。通过详细的地址门牌号(域名IP)找到你的家(服务器),然后看见的就是你家的样子(网站模板),这就是访问网站的大致过程。
如果想别人通过浏览器搜索关键词访问你的网站,那就需要网站做好相应的排名优化,排名优化做的越好,通过关键词访问你网站的人数就越多,当网站有一定流量时,因此我们就可以通过网站流量在互联网上去获得收益(也就是钱),这也是目前各大网站获取收益的方式之一。
除去域名、网站、服务器等费用(可以忽略,每年也就几百块),可以说简直是很适合个人无成本创业或者居家创业,很多互联网企业也是靠着这种方式起家的。
总结:自己的网站怎么才能让别人访问?其原理比较复杂,但大致过程很简单,而且也可以靠着网站完成创业和收益(很多站长都是靠自己的网站增加主业或副业收益的),不过其中有很多值得注意的细节,比如域名的选择、网站程序、服务器的选择等等,这些都关系到网站的排名优化效果。
介绍 在Mysql中 使用 select from … into outfile 导出数据时报错
ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option so it cannot execute this statement
分析原因 其实原因很简单,因为在安装MySQL的时候限制了导入与导出的目录权限。只允许在规定的目录下才能导入。
可以通过以下命令查看secure-file-priv当前的值是什么
SHOW VARIABLES LIKE "secure_file_priv"; 可以看到,本地value的值为 /var/lib/mysql-files 。/var/lib/mysql-files代表什么意思呢?经查资料:
NULL,表示禁止。如果value值有文件夹目录,则表示只允许该目录下文件(PS:测试子目录也不行)。如果为空,则表示不限制目录。 解决方案 把导入文件路径改成secure-file-priv目前的value值对应路径即可
如果secure-file-priv的value值为NULL
就把路径修改为准备导出文件的放置路径
修改配置文件 /etc/my.cnf
vim /etc/my.cnf secure_file_priv = 重启mysql服务生效
mysql> SHOW VARIABLES LIKE "secure_file_priv"; +------------------+-------+ | Variable_name | Value | +------------------+-------+ | secure_file_priv | | +------------------+-------+ 1 row in set (0.
项目场景: 将一个web项目打包部署到docker容易中,使用docker安装一个tomcat容器,通过宿主访问容器中的资源
问题描述: 宿主机不能访问容器中部署的web项目
原因分析: 因为docker的虚拟ip网段是172.17.*。*与局域网的ip网段不同,无法进行通信,即访问不到资源
解决方案: 网上解决方式有很多,本文记录较为方便的一种方式:
在docker 创建和启动容器时加上 --net=host 指令,表示容器与宿主机共享同一个网卡,可以解决网段不一致的问题。
docker run -id --name=c_tomcat2 -p 8080:8080 -v $PWD:/usr/local/tomcat/webapps --net=host tomcat 结果 成功访问到容器中部署的项目:
目录
0x01 什么是SSTI
0x02 漏洞存在位置
0x03 漏洞如何发掘检测
0x04 漏洞复现
0X05 防御方法 0x01 什么是SSTI SSTI,即服务器端模板注入(Server-Side Template Injection)。攻击者在服务器输入语句,服务端将其作为Web应用模板内容的一部分,在进行目标编译渲染的过程中,进行了语句的拼接,执行了所插入的恶意内容,从而导致信息泄露、代码执行、GetShell等问题。
补充:
1)模板引擎是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,用于网站的模板引擎就会生成一个标准的文档,就是将模板文件和数据通过模板引擎生成一个HTML代码。
2)模板注入请不要认为只存在于 Python 中,凡是使用模板的地方都可能会出现 SSTI 的问题,SSTI 不属于任何一种语言,沙盒绕过也不是。
0x02 漏洞存在位置 常见的模板引擎:
1、php 常用的 --Smarty Smarty算是一种很老的PHP模板引擎了,非常的经典,使用的比较广泛 --Twig Twig是来自于Symfony的模板引擎,它非常易于安装和使用。它的操作有点像Mustache和liquid。 --Blade Blade 是 Laravel 提供的一个既简单又强大的模板引擎。 2、Java 常用的 --JSP 这个引擎我想应该没人不知道吧,这个应该也是我最初学习的一个模板引擎,非常的经典 --FreeMarker FreeMarker是一款模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页、电子邮件、配置文件、源代码等)的通用工具。 它不是面向最终用户的,而是一个Java类库,是一款程序员可以嵌入他们所开发产品的组件。 --Velocity Velocity作为历史悠久的模板引擎不单单可以替代JSP作为Java Web的服务端网页模板引擎,而且可以作为普通文本的模板引擎来增强服务端程序文本处理能力。 3、Python 常用的 --Jinja2 flask jinja2 一直是一起说的,使用非常的广泛,是我学习的第一个模板引擎 --django django 应该使用的是专属于自己的一个模板引擎,我这里姑且就叫他 django,我们都知道 django 以快速开发著称,有自己好用的ORM,他的很多东西都是耦合性非常高的,你使用别的就不能发挥出 django 的特性了 --tornado tornado 也有属于自己的一套模板引擎,tornado 强调的是异步非阻塞高并发 SSTI 产生实例:
1.刚入大学,迷惘是大多数 高考完,填志愿的时候,重新审视自己,发现自己并没有什么过人之处。各科分数都比较平均,没有玩得特别溜的科目。当时想起来小时候的经历,就是特别喜欢捣鼓家里的各种小电器,总是玩得不亦乐乎,瞬间,我觉得可以报一下电子信息类的专业,但面对现实,我冷静下来了,我的分数压根抱不到好学校好的电子专业,毕竟这些专业对人、对学校的要求比较高,因为专业需要比较扎实的基本学习和物理基础,但我还是有自知之明的,学得也不怎么强,特别是对抽象事物的理解,也比较吃力,因此也就放弃了这个想法。
后来,在家人这边了解到了一个叫信息管理与信息系统的专业,我百度了一下,发现这个专业很神奇,需要学习的科目可谓很多,会计、经济学、运筹学、管理学、java、数据库、网页设计、系统分析与设计等等,当时我就想,这个是个好东西呀,这个专业学这么多东西,在学习的过程中,就知道自己对哪些科目比较有兴趣和更强大把控能力,然后在后面对这些科目进行专供,不就可以打造属于自己的特长了吗。有了这个想法之后,便决定报读了这个专业。
就这样,2017年的九月份,就踏实了大学的旅程;
很幸运的是,在大一碰到以为同学院的师姐,我很感谢她,姓陈,叫她陈师姐吧,送给我了两本书《大学生的坟》和《异类》。读完这两本书,我感觉大学应该怎么过了,如果想读的网友,可以找一下,作者是刘兴奇。这两本书剖析的现在大学生普遍存在的问题,例如迷惘。文中的建议大概是目标导向,增强自己的软实力和打造自己的特点,让自己变得更加有竞争力,现在我应该回头读一读了,很多都忘记了,不过当时确实给我挺大的帮助。如果你是刚进大学,想明确自己的方向,不妨读一读,肯定会有收获的。
2. 在提升自己的路上一路奔跑 在大学期间,我主要干两件事,一件是改善自己内向的性格,让自己和其他人沟通无障碍,能够准确表达自己的想法。第二件事情的学习自己喜欢的东西。第一件事情,我有了比较明确的计划,参加学校的社团,多社交,在社交中,学习和别人沟通和表达自己的想法。其次是多参加学校组织的活动,比较什么创新创业大赛、互联网+,我参加的目的很简单,就是锻炼自己上讲台演讲的能力和胆量。在这个过程中,往往需要克服自己。第一次参加演讲的时候,我的做法是专注,让自己专注与演讲,这样就会忽略台下观众,不会让他们干扰到自己,就会减少恐惧。如此一来,多参加演讲,自然而然地就会习惯。
第二件事情上,就是给自己定下一个目标,就是做一个网站出来。当时还是在大一,根本不知道一个网站究竟是怎么搭建起来的,一上网百度,全是自己看不懂的东西。但是因为学校在大二也会开java课程,因此我就在大一开始学习了java基础。在学习的过程中,我是抱着强烈的目的去学习的,就是如何搞出一个像样的网站。但后来还是没有搞出来,哈哈哈。但是在这个过程中,我掌握了java的基础语法和规范,也为我打下了编程的基础,在很多编程语言中,分支结构和判断都是类似的,很多都是相同的,不同的是规范。
在大二的时候,偶然看到学校的一个公众号的一个工作室招人,这个刚好是对接技术这一块的,我想,我是不是可以去试试。我当初也报名了。当初面试官给我的需求是,用微信小程序开发出一个校卡丢失找回的功能。我当时一脸懵逼,what,这个是啥玩意。但还好当时没有放弃,自己在大学生慕课网找了些视频,后来不知道什么原因,既然让我找到了jsp技术,就是用java语言搞出来的一种动态网站技术,我想,这不是我一直要寻找的东西吗?我当时如获至宝,一头扎进了jsp的世界里,由于当时玩得很爽,渐渐得喜欢上这个东西。后来把数据库也一起折腾了。就这样,过完了我的大二生涯。在这个过程中,逐渐了解到了编程这一块领域的职业,比如后端开发、前端开发。及其用到的主要技术栈,后面也开始涉及前端这一块的开发,开始学习网页布局和JavaScript的学习中来。
大三开始,是一个重要的转择点,但是没有继续研究后端技术,开始了前端的学习。当时有一个想法就是把自己平时学习的东西,总结起来,要定期输出,以检验自己是否真的学懂了。我有两个办法,一个是写博客,另外一个就是搭建属于自己的网站。
因为自己在大学了拿过奖学金,因此有一些闲置的钱可以购买服务器,因为在华为云中,有学生优惠,我就买了一年的云服务资源。当时我做了一个可以上传图片、写文字、点赞、留言的传统增删改查的网站,前端技术主要用到了boostrap和jquery,后端是使用了serverlet和mybatis,花了我大概一个月的大二暑假时间,但是做出来还是很有成就感,感觉自己又可以了。后来学习了vue开发技术,又开始前面的jquery改造之路。
就这样,很快就到了大四,但是刚好碰上疫情,找实习也不好找,前后端都投了简历,但是只有前端有笔试和面试邀请,我就这样,进了前端开发的浪潮,一直坚持走到现在。
3. 一些建议 1.迷惘不可怕,多读书,多实践。迷惘最大的问题是,知道的东西少,比如我在接触编程之前,我都不知道自己喜欢什么。我是通过网上的一些文章了解到的。当然,我不是让大家都去编程啥的,只是让大家知道,多去看看文章和书籍,说不定可以找到自己热爱的东西,然后坚持下去,迷惘的问题不就迎刃而解了。
2.学习中,需要定期总结和输出。光是输入,而没有输出,很容易忘记,而且理解不深。
最后,希望我的文章能够帮助到一些刚入大学想寻求自己突破的你,如果写得不好,可以留言交流。
12月23日,“创变者”2021年度腾讯Light论坛在厦门正式举办。在论坛上,由全国妇联宣传部指导,腾讯公司联合中国儿童中心主办,企鹅伴成长、腾讯华东总部、腾讯SSV创新办学实验室、企鹅爱地球、腾讯优图实验室、腾讯云AI、腾讯云微搭承办的第二届腾讯Light·公益创新挑战赛正式启动。
活动现场公布了儿童安全保护/教育、素养教育、生物多样性保护/教育三大更具“可持续性”和“科技向善”视野的赛题,并邀请社会各界参赛者通过腾讯云微搭低代码、腾讯云提供的AI技术,以小程序、H5或PC Web网站的形式打造创新应用,助力解决三大赛题背后的热点问题。
腾讯高级执行副总裁、云与智慧产业事业群CEO汤道生致辞表示,“服务于人”是人工智能最大的价值,用AI助力更美好的世界,这样的探索存在于实验室里,存在于产业中,也正走向更广阔的社会应用中。
两年前,腾讯提出“科技向善”的使命愿景,今年又将“推动可持续社会价值创新”写进公司战略。在新一届Light·公益创新挑战赛中,腾讯将继续以开放共建的方式,与更多不同行业的参赛者一同探索人工智能与更广泛的社会价值的结合。
全国妇联宣传部表示,党和国家高度重视未成年人健康成长,始终坚持儿童优先原则,新周期中国儿童发展纲要明确要求探索在网络空间开展儿童思想道德教育的新途径、新方法,落实政府、企业、学校、家庭、社会保护责任,为儿童提供安全、健康的网络环境。希望腾讯Light·公益创新挑战赛能涌现出更多优秀作品,通过科技的力量,助力培养担当民族复兴大任的时代新人。
中国儿童中心表示,作为国家级公益性儿童发展、教育和服务机构,中心致力于为儿童提供优质的教育、创设儿童友好的成长环境。以人工智能为核心的互联网信息技术革命,给教育事业发展提供了更多的可能,希望通过此次挑战赛,联合腾讯召集有创造力和责任感的开发者及相关人士,用数字科技助力儿童的教育和成长。
厦门火炬高新区管委会党工委委员、总工程师邱尖,全国妇联宣传部网络新媒体处处长张玉山,中国儿童中心网络信息中心副主任邵彬,厦门大学南强特聘教授、国家杰出青年科学基金获得者纪荣嵘,腾讯副总裁、腾讯华东总部总经理张立军,腾讯副总裁、腾讯安全管理部总经理朱劲松,腾讯云副总裁、腾讯优图实验室总经理吴运声,腾讯集团市场与公关部副总经理林涛,腾讯SSV创新办学实验室联合负责人梁栋,腾讯云微搭低代码负责人王倩等嘉宾出席论坛并共同见证了本次大赛的启动仪式。
启动仪式现场
01
打造联结科技创新与社会需求的平台 Light挑战赛联动社会力量实现公益创变
首届Light·公益创新挑战赛于2020年12月正式举办,设置「野生动植物保护」、「未成年人网络保护」、「适老化无障碍设计」三大赛题,吸引了663支队伍近3000名参赛者报名参与。
今年4月,腾讯将可持续社会价值创新纳入公司核心战略,成立可持续社会价值事业部(SSV),在公司内部设立向善实验室群,聚焦基础科学、教育创新、养老科技等公益领域,希望通过技术开放与联合开发,与社会各界共同探索和建设可持续发展的社会价值。
基于此,今年Light·公益创新挑战赛的赛题设置也将更具“可持续”和“科技向善”视野,聚焦素养教育、儿童安全保护/教育、生物多样性保护/教育三个赛道,为下一代的健康成长保驾护航。
厦门火炬高新区管委会党工委委员、总工程师邱尖在致辞中表示,2020年腾讯面向全国发起Light计划,今年厦门很高兴成为Light论坛的主办城市。同时,腾讯优图AI创新中心即将落户厦门,未来期待与腾讯进一步深化在产创融合、人才培养和科研课题等方面的合作,推动青年科技人才和研究团队的交流实践。
本届挑战赛之所以选择在厦门举办,也是基于厦门人工智能方面的发展优势和持续投入。“依托雄厚的产业基础、丰富的创新资源和完整的产业链条,厦门在人工智能领域的人才储备、产业生态、数据规模等方面优势明显。”
张立军在致辞中表示,近年来腾讯与厦门市政府共同推动AI技术在社会治理、城市管理、公共服务、智慧医疗和智慧教育等领域中落地,已取得了十分亮眼的成果。双方都希望通过本届挑战赛,以“云+AI”的方式,携手各方探索科技公益的落地路径,为社会创造更多可持续发展的社会价值。
腾讯副总裁、腾讯华东总部总经理张立军
践行科技向善的过程不会一蹴而就,而是多方参与的“马拉松长跑”。朱劲松表示,举办腾讯Light·公益创新挑战赛的初衷,就是想让这场“马拉松”有更多人来接力和聚力,推动技术与公益的跨界联结。“用户、产业、社会的关系是三位一体,相辅相成的,最终指向的都是满足社会需求,为社会创造价值。”
他认为,“跨界”既是实现用户、产业、社会三位一体的重要路径,也是让科技创新与社会创新齐头并进的加速器,期待和广大技术志愿者、有志于公益的热心人士,一起用科技做出一些美好的改变。
腾讯副总裁、腾讯安全管理部总经理朱劲松
一直以来,腾讯都在践行“科技向善”的公司愿景和理念,通过 AI、云计算等技术创造可持续社会价值、输出公益领域的技术解决方案。
“人工智能在助力产业数字化升级的同时,也对可持续社会价值进行探索。”吴运声认为,为了支持和支撑整个社会的可持续发展,我们应该向公众呼吁,基于长远发展考虑构建不断创新、可持续的科技公益。
腾讯云副总裁、腾讯优图实验室总经理吴运声
此外,在首届挑战赛同时斩获一等奖和公益潜力之星奖项的小程序——有光和解忧暖心喵App的开发者胡淼淼,也进行了演讲。
他表示,自正式上线以来,已经有7000多暖心师和100多心理咨询师,在小程序上为未成年人回复近10万封信,而这一切成果都离不开腾讯所开放的技术和资源。“腾讯云、腾讯AI让有光.暖心喵能够正式上线,而QQ、微信则为有光.暖心喵提供了更便捷的用户触达渠道。”胡淼淼表示。
有光和解忧暖心喵App的开发者胡淼淼
02
三大赛题聚焦可持续发展社会价值
赛制升级吸引更多参赛者参与科技公益
活动现场公布了本届Light·公益创新挑战赛的三大赛题——儿童安全保护/教育、素养教育、生物多样性保护/教育,邀请参赛者基于赛题发挥创新思维,运用腾讯云微搭低代码进行开发,并使用最少一项基于腾讯云提供的AI技术,打造相应的创新应用。
在儿童安全保护/教育赛题中,参赛者会聚焦现实世界和网络空间中未成年人安全问题频发的重点场景,融合AI技术设计出兼具实用性和前瞻性的解决方案,让儿童在现实世界和网络空间中,避免遭受校园霸凌、不良信息等侵害,构建一个孩子能够安全、健康成长的安全世界。
在素养教育赛题中,参赛者关注发展素养教育过程中遇到问题与挑战,如教学方式单一、教学资源不足等,通过AI技术开发对应的教学工具,通过增强课堂互动、增加教学方式等形式,帮助教师和学生提升教学效率及学习体验,让学生能够在课堂上掌握更多人文、科学等领域的知识和技能,从而达到德智体美育全面发展的目标。
而生物多样性保护/教育赛题鼓励参赛者充分发挥AI技术的优势,开发出能够激发和培养未成年人对生物多样性保护意识的技术解决方案,从小培养孩子守护生物多样性的观念,从而为国家生物多样性治理体系和治理能力现代化提供助力,进一步促进人与自然和谐共生。
值得一提的是,本届Light·公益创新挑战赛除了赛题更新、让赛事更加聚焦于创造可持续发展的社会价值外,还打破了作品形式上的限制:参赛者可以自由选择,提交通过腾讯云微搭低代码、腾讯云提供的AI技术打造的小程序、H5或PC Web网站。
腾讯云微搭低代码负责人王倩表示,打破作品形式上的限制,是希望为参赛者提供更加自由的开发环境,而吸引更多志同道合的技术人员参与到挑战赛中,可以为创造可持续发展社会价值提供更多助力。
今年,腾讯还发布了技术公益创投计划,面向长期致力于信息无障碍、应急救灾、科技助老、生态环保、文化遗产保护五大领域事业的公益组织等提供具有针对性的资金、技术和资源支持,本届挑战赛所孵化的优秀作品也有机会得到技术公益创投计划的支持。
作为本届Light·公益创新挑战赛的公益传播大使,艺人俞灏明、陈意涵Estelle也分享了自己对于科技公益和赛题的看法。俞灏明表示对生物多样性赛题最感兴趣,希望有更多爱好公益的有志之士能够参与到此次的挑战赛中,用人工智能为保护生物多样性、保护未成年人提供更多的帮助。
活动现场,陈意涵Estelle表示其最为关注未成年人安全保护教育的赛题,“网络空间和现实世界中存在很多未知风险和安全隐患,青少年的安全保护意识薄弱,更需要社会的保护。希望通过技术的发展,能够给未成年人营造一个干净爽朗的环境。”
作为一家科技企业,腾讯致力于发挥自身能力与技术优势,通过探索科技公益的实践路径来更好地回馈社会。
2019年,腾讯优图实验室首创的“跨年龄人脸识别技术”帮助寻回多名走失儿童,年龄跨度最大的超18年;2020年,腾讯天籁实验室发起“天籁行动”,免费开放腾讯天籁AI音频技术,以提升人工耳蜗降噪效果、打造远程服务等方式改善听障人群的听力体验;腾讯云小微也通过AI知识图谱能力联合动保专家共同打造“神奇雪豹在哪里”小程序,助力提升社会公众对濒危野生动物的保护意识。
此次发起第二届Light·公益创新挑战赛,腾讯希望通过开放合作,连接社会力量助力科技公益持续发展,呼吁更多技术志愿者通过这一平台,让自己的公益创想变为现实,也希望Light·公益创新挑战赛可以孵化更多创新的科技公益作品,源源不断地向社会输出可持续发展的社会价值。
点击链接,即可报名参赛,用AI给世界带来一丝改变。
腾讯light.公益创新挑战赛
通过学习 HttpClient 的工作机制 ,我们知道对于HTTP请求,HttpClient 实际上是构建了一个链式的处理流程:
在HttpBackend的处理流程中请求被发出。在HttpBackend的前面可以设置多个的拦截器,对请求进行处理。
HttpClient 的详细说明请参考:Angular 中的 HttpClient 请求详解
1、编写拦截器 要实现拦截器,就要实现一个实现了 HttpInterceptor 接口中的 intercept() 方法的类。
以下代码实现一个除了添加打印外,不做其他处理的拦截器:
import { Injectable } from "@angular/core"; import { HttpInterceptor, HttpHandler, HttpRequest, HttpEvent } from '@angular/common/http' import { Observable } from "rxjs"; import { mergeMap } from "rxjs/operators"; @Injectable() export class InterceptorA implements HttpInterceptor { intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { req = this.handleRequest(req); return next.handle(req).pipe( mergeMap(evt => this.handleResponse(evt)) ); } /** * 请求参数拦截处理 */ handleRequest(req: any) { console.
实际探测可以在白天和晚上分别进行探测。
1.利用NetBIOS快速探测内网 nbtscan工具已经上传到我的资源,大家可以下载。此工具用于扫描本地或远程TCP/IP网络上开放NetBIOS名称服务器。有Windows和Linux两个版本,将其上传到目标服务器就可以直接使用。使用命令如下:
nbtscan.exe 192.168.1.0/24 2.利用ICMP协议快速探测内网 依次对内网中每个IP地址执行ping命令,可以快速找出内网中所有存活的主机。在渗透测试中,可以使用如下命令循环探测整个C段,如下:
for /L %I in (1,1,254) DO @ping -w 1 -n 1 192.168.1.%I | findstr "TTL=" 也可以使用VBS脚本进行探测,脚本如下:
strSubNet = "192.168.1." Set objFSO = CreateObject("Scripting.FileSystemObject") Set objTS = objfso.CreateTextFile("C:\Users\jjwzzd\Desktop\1.txt") For i = 1 To 254 StrComputer = strSubNet & i blnResult = Ping(strComputer) If blnResult = True Then objTS.WriteLine strComputer & " is alived! :)" End If Next objTS.close WScript.Echo "ALL Ping Scan ,All Done!
有一些问题,可能你一直都没时间真正去搞懂,今天的主题就算其中一个。
在Windows中,很多和位图相关的结构体中,会有一个所谓的”planes”的成员。举个例子,在BITMAPINFOHEADER这个结构体中有一个biPlanes的成员,而且它还必须设置为1。在BITMAP结构体中有一个bmPlanes成员。那么,这东西,到底有啥用呢?
请听在下给翻译翻译。
EGA(Enhanced Graphics Adapter,算老古董啦)显卡驱动支持16位色。和只能支持4个颜色的CGA(Color Graphics Adapter,算老老古董啦)相比,这可是一个巨大的进步(那可不)。
如果系统支持16色的颜色空间,则每个像素需要4个位来表示。你可能会认为,将显卡内存的每个字节表示为两个像素,一个在视频区底部的四位,另一个则是顶部的四位。但由于技术原因,显存的结构并没有那么简单。
在实际的设计中,像素的位数据并不是一个接一个的摆放的,颜色通道被拆分为各自独立的单色位图。换句话说,像素被以”另外一种方式”切片。如下图所示:
在上图中,假设我们希望显示8个像素,它们的颜色值分别为 {0, 3, 5, 6, 8 B, D, E}。
显卡内存并不是按该顺序存储半个字节,而是将半字节分成它们的组成位,并将相同位置的所有位集合在一起。 换句话说,采用横向读取而不是向下读取。
在一个默认的16色的调色板中,颜色被系统按照一定的规则进行分配,例如位0表示蓝色通道,位1表示绿色通道,位2表示红色通道,位4表示强度通道。根据这个规则,这4个位可以被解释为:强度平面,红色平面,绿色平面和蓝色平面。对于最后三个平面,您可以想象每个平面都代表了如果只有相应的电子枪在发射时你看到的情况。
由于这是EGA的本机颜色格式,因此需要有一种方法在BITMAP结构中表达这种颜色格式,以便 Windows可以表示与设备相关的位图。
因此诞生了平面颜色格式。对于16色平面的位图,平面数为 4,每个像素的位数为 1。
总结 对于现代16位色/32位色的显示系统来说,不用太过担心,因为始终只会有一个颜色平面,所以简单地设置它为 1 就可以了。
所以,且把它看做一个”兼容性存在”即可。
最后 Raymond Chen的《The Old New Thing》是我非常喜欢的博客之一,里面有很多关于Windows的小知识,对于广大Windows平台开发者来说,确实十分有帮助。
本文来自:《What is the purpose of the bmPlanes member of the BITMAP structure?》
文章目录 样本信息样本行为详细分析病毒主体解密ShellCodeShellCode主体 病毒DLL脱壳DllEntryPoint感染过程 总结分析 样本信息 MD5:b4964c8ac85b1e428c9eefe572237b21
类型:exe32
分析工具:DIE、OD、x32dbg、IDA
样本行为 该样本是感染性极强的病毒,属于Parite家族,其运行后会先解密并运行一段ShellCode,ShellCode会解密文件末尾的病毒DLL并通过SetWindowsHookExA将其注入explorer进程,创建新线程来感染本地磁盘和网络资源中的exe文件和scr文件。
详细分析 病毒主体 拿到病毒样本之后,先拖到DIE中看一下,发现它是32位的exe文件,C++写的,无壳。
解密ShellCode 拖到IDA里,发现没解析出个啥,再拖到OD里,入口是:
可以发现,一上来是个循环,这其实是个解密:
我们在数据窗口看一下解密前的数据:
再看一下解密后的:
ShellCode主体 然后 call 进入0066519C,这其实是一段ShellCode。主要有四个行为:
上来的第一个函数,获得了Kernel32.dll中一系列函数的地址。先LoadLibraryA,然后GetProcAddress。查询注册表键值,HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer中PINF的值,如果查询失败则继续第三步。
在Temp目录中释放一个.tmp文件,文件名是随机字符串。经查验,该tmp文件实质上是个DLL,具体释放过程如下: 首先GetModuleFileNameA获得当前进程完整路径,然后CreateFileA获得文件句柄(0x94)。
然后生成一个随机文件名,并创建文件,句柄为0x98。
SetFilePointer设置进程文件的文件指针,位置为0x243AFC;然后ReadFile循环从进程文件中读数据,每次读的大小为0x2800。数据窗口中显示的是读出来的数据。
随后调用的一个解密函数,解密后的数据一看就很明显了,是PE文件。然后将解密后的数据写入tmp文件。
重复读写,直到完成,总大小为2B000。 加载该DLL文件,并运行其导出函数Initiate。
Initiate函数的行为:
检测互斥体Residented是否存在,不存在的话,通过SetWindowsHookExA设置消息钩子,消息类型为WH_CALLWNDPROC,钩子子程为DLL的导出函数AttachHook。
这样,当有进程产生WH_CALLWNDPROC消息时,DLL就会被注入到该进程中。
病毒主体的分析到这里就差不多结束了,接下来看一下释放的病毒DLL的行为。 病毒DLL 拖到DIE中看了下,发现有UPX壳。
脱壳 用UPX直接脱壳,但是失败了。
那就手动脱一下壳吧,这里用的是ESP定律。先拖到OD里看看:
运行完pushad这一句时,ESP变红,右键空白处,点击HW break[ESP]。
然后F9继续运行,断点断到这里:
F8走一步就找到OEP了。
最后显示:
也不知道为什么?后面同事给指了条明路,改用x32dbg。进来之后首先进入的是系统函数:
继续运行,找到pushad后,然后还是用ESP定律,最终找到OEP:
点击最上方插件->Scylla,弹出窗口,先点击Pick DLL选择目标LL,然后在下面的编辑框输入真正的OEP地址,然后依次点击IAT Autosearch、Get Imports、Dump,Fix Dump按钮。
将脱壳后的文件拖入DIE,发现脱壳成功。脱壳成功后就可以通过IDA看源代码了,有源码再结合OD动态调试会更方便一点。
DllEntryPoint 病毒Dll在入口处会先判断当前进程是不是explorer进程,它只对explorer进程进行操作。
主要功能是在sub_2F1B5C中实现,其行为有:
创建互斥体Residented;加载自身DLL;删除temp目录下的.tmp文件,被占用的除外;将自身路径写入注册表HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer中的PINF;SetWindowsHookExA挂钩当前线程,钩子类型还是WH_CALLWNDPROC;
创建感染线程,线程回调函数为sub_2F5778()。
线程回调函数中,主要就是遍历磁盘和网络资源,感染.exe文件和.scr文件。但是不会感染C:\Windows\system32\dllcache\下的文件以及readbook.exe、rundll32.exe。 遍历磁盘:
遍历网络资源:
感染过程 真正对文件进行感染的函数是sub_2F2C7C(),这块分析需要对PE文件结构很熟悉,下面直接放IDA中的代码分析。
接下来挨个看一下其中的各个子功能:
判断目标文件是否有PE头。
读取目标文件的节表以及后面0x28字节的内容,为后续新增节做准备。
判断目标文件是否已经被感染,即看最后一个节表头中节区名称是否符合条件。
随机生成新增节的名称,生成算法如下,上面判断的算法也是由此而来。
修正新增节表头中的数据成员。
构造解密代码,后续会将其写入新增节的开头,作为目标文件新的EP。判断目标文件是否具备感染条件,即看其导入表中有没有kernel32.dll,如果有则Hook其IAT和INT。
listProjectVOSForFeishu: @Override public List<DashMenuTreeNodeVO> listProjectVOSForFeishu() { List<ProjectDashboardTabChartVO> projectDashboardTabChartVOList = dashboardMapper.listProjectDashboardTabChart(true); if (CollectionUtils.isEmpty(projectDashboardTabChartVOList)) { return Collections.emptyList(); } DashMenuTreeNodeVO root = new DashMenuTreeNodeVO(); for (int i = 0; i < projectDashboardTabChartVOList.size(); i++) { ProjectDashboardTabChartVO vo = projectDashboardTabChartVOList.get(i); root.add(vo); } return new LinkedList<>(root.getChildren()); } DashMenuTreeNodeVO: package com.soyoung.ztdata.bi.core.vo.report; import com.soyoung.ztdata.bi.core.enums.DashMenuTypeEnum; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import java.util.*; /** */ @Slf4j public class DashMenuTreeNodeVO { private String id; private String name; /** * 当前节点类型 */ String type; /** * 排序字段 */ private Integer sortNum; /** * 是否可编辑 */ private Boolean edit = false; /** * 是否可删除 */ private Boolean del = false; /** * 子节点 */ private Set<DashMenuTreeNodeVO> children = new TreeSet<>((o1, o2) -> { if (null == o1.
现象:接口默认1min超时,超过时间直接504
考虑到业务,存在超级慢的接口,需要调大超时时间。网上一搜…一言难尽… 大部分文章都提到以下两个配置spring.mvc.async.request-timeout和server.tomcat.connection-timeout,但实测,不能达到效果。
最终想到接口经过nginx转发,在nginx中加了proxy_read_timeout配置后实现效果。
location /xxx { root html; proxy_pass http://172.26.1.1:8888; index index.html index.htm; proxy_read_timeout 150; # 此行生效 } 考虑spring/tomcat本身是否有相关配置,翻阅了官方文档和源码,最终得到结论:
对于同步接口,暂时没有(没找到)超时时间配置。对于异步接口,有超时时间配置(具体往下看spring.mvc.async.request-timeout)。 下方列了两个大部分文章都提到的配置项描述、使用方式,以及其他超时时间配置方法:
server.tomcat.connection-timeout Amount of time the connector will wait, after accepting a connection, for the request URI line to be presented.
引用[1]
按照我的理解,server.tomcat.connection-timeout是建立连接需要的时间,非连接处理的时间
spring.mvc.async.request-timeout Amount of time before asynchronous request handling times out. If this value is not set, the default timeout of the underlying implementation is used.
关注公众号【高性能架构探索】,回复【pdf】,免费获取计算机经典资料
在上篇文章中,我们分析了线上coredump产生的原因,其中用到了coredump分析工具gdb,这几天一直有读者在问,能不能写一篇关于gdb调试方面的文章,今天借助此文,分享一些工作中的调试经验,希望能够帮到大家。
写在前面 在我的工作经历中,前几年在Windows上进行开发,使用Visual Studio进行调试,简直是利器,各种断点等用鼠标点点点就能设置;大概从12年开始转Linux开发了,所以调试都是基于GDB的。本来这篇文章也想写写Windows下调试相关,奈何好多年没用了,再加上工作太忙,所以本文就只写了Linux下GDB调试相关,对于Windows开发人员,实在对不住了😃。
这篇文章,涉及的比较全面,总结了这些年的gdb调试经验(都是小儿科😁),经常用到的一些调试技巧,希望能够对从事Linux开发的相关人员有所帮助
背景 作为C/C++开发人员,保证程序正常运行是最基本也是最主要的目的。而为了保证程序正常运行,调试则是最基本的手段,熟悉这些调试方式,可以方便我们更快的定位程序问题所在,提高开发效率。
在开发过程,如果程序的运行结果不符合预期,第一时间就是打开GDB进行调试,在对应的地方设置断点,然后分析原因;当线上服务出了问题,第一时间查看进程在不在,如果不在的话,是否生成了coredump文件,如果有,则使用gdb调试coredump文件,否则通过dmesg来分析内核日志来查找原因。
概念 GDB是一个由GNU开源组织发布的、UNIX/LINUX操作系统下的、基于命令行的、功能强大的程序调试工具。
GDB支持断点、单步执行、打印变量、观察变量、查看寄存器、查看堆栈等调试手段。在Linux环境软件开发中,GDB是主要的调试工具,用来调试C和 C++程序(也支持go等其他语言)。
常用命令 断点 断点是我们在调试中经常用的一个功能,我们在指定位置设置断点之后,程序运行到该位置将会暂停,这个时候我们就可以对程序进行更多的操作,比如查看变量内容,堆栈情况等等,以帮助我们调试程序。
以设置断点的命令分为以下几类:
breakpointwatchpointcatchpoint breakpoint 可以根据行号、函数、条件生成断点,下面是相关命令以及对应的作用说明:
命令作用break [file]:function在文件file的function函数入口设置断点break [file]:line在文件file的第line行设置断点info breakpoints查看断点列表break [±]offset在当前位置偏移量为[±]offset处设置断点break *addr在地址addr处设置断点break … if expr设置条件断点,仅仅在条件满足时ignore n count接下来对于编号为n的断点忽略count次clear删除所有断点clear function删除所有位于function内的断点delete n删除指定编号的断点enable n启用指定编号的断点disable n禁用指定编号的断点save breakpoints file保存断点信息到指定文件source file导入文件中保存的断点信息break在下一个指令处设置断点clear [file:]line删除第line行的断点 watchpoint watchpoint是一种特殊类型的断点,类似于正常断点,是要求GDB暂停程序执行的命令。区别在于watchpoint没有驻留某一行源代码中,而是指示GDB每当某个表达式改变了值就暂停执行的命令。
watchpoint分为硬件实现和软件实现两种。前者需要硬件系统的支持;后者的原理就是每步执行后都检查变量的值是否改变。GDB在新建数据断点时会优先尝试硬件方式,如果失败再尝试软件实现。
命令作用watch variable设置变量数据断点watch var1 + var2设置表达式数据断点rwatch variable设置读断点,仅支持硬件实现awatch variable设置读写断点,仅支持硬件实现info watchpoints查看数据断点列表set can-use-hw-watchpoints 0强制基于软件方式实现 使用数据断点时,需要注意:
当监控变量为局部变量时,一旦局部变量失效,数据断点也会失效如果监控的是指针变量p,则watch *p监控的是p所指内存数据的变化情况,而watch p监控的是p指针本身有没有改变指向 最常见的数据断点应用场景:定位堆上的结构体内部成员何时被修改。由于指针一般为局部变量,为了解决断点失效,一般有两种方法。
命令作用print &variable查看变量的内存地址watch *(type *)address通过内存地址间接设置断点watch -l variable指定location参数watch variable thread 1仅编号为1的线程修改变量var值时会中断 catchpoint 从字面意思理解,是捕获断点,其主要监测信号的产生。例如c++的throw,或者加载库的时候,产生断点行为。
命令含义catch fork程序调用fork时中断tcatch fork设置的断点只触发一次,之后被自动删除catch syscall ptrace为ptrace系统调用设置断点 在command命令后加断点编号,可以定义断点触发后想要执行的操作。在一些高级的自动化调试场景中可能会用到。
不是强制如此做。但不这样做可能会出现问题。且不好维护管理。大家都这样做有一定的道理。也好同步维护别人的代码。
src/main/java:主程序入口 Application,可以通过直接运行该类来 启动 Spring Boot应用
src/main/resources:配置目录,该目录用来存放应用的一些配置信息,比如应用名、服务端口、数据库配置等。由于我们应用了Web模块,因此产生了 [static](https://so.csdn.net/so/search?q=static)目录与templates目录,前者用于存放静态资源,如图片、CSS、JavaScript等;后者用于存放Web页面的模板文件。
src/test:单元测试目录,生成的 ApplicationTests 通过 JUnit4实现,可以直接用运行 Spring Boot应用的测试。 application.properties/application.yml 用于存放程序的各种依赖模块的配置信息,比如 服务端口,数据库连接配置等。
## 1)代码层的结构
根目录:com.springboot
1.工程启动类(ApplicationServer.java)置于 com.springboot.build 包下
2.实体类(domain)置于 com.springboot.domain
3.数据访问层(Dao)置于 com.springboot.repository
4.数据服务层(Service)置于 com,springboot.service, 4.1,数据服务的实现接口(serviceImpl)至于 com.springboot.service.impl
5.前端控制器(Controller)置于 com.springboot.controller
6.工具类(utils)置于 com.springboot.utils
7.常量接口类(constant)置于 com.springboot.constant
8.配置信息类(config)置于 com.springboot.config
9.数据传输类(vo)置于 com.springboot.vo
## 2)资源文件的结构
根目录:src/main/resources
1.配置文件(.properties/.json等)置于config文件夹下
2.国际化(i18n))置于i18n文件夹下
3.spring.xml置于META-INF/spring文件夹下
4.页面以及js/css/image等置于static文件夹下的各自文件下
命名包名目录的方式 :com.公司名的简写.项目的名字.业务模块名
目录 1、resolveBeanClass()2、prepareMethodOverrides()3、resolveBeforeInstantiation()1)applyBeanPostProcessorsBeforeInstantiation()2)applyBeanPostProcessorsAfterInitialization() protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) { RootBeanDefinition mbdToUse = mbd; // Make sure bean class is actually resolved at this point, and 确保此时真正解析了 bean 类,并且 // clone the bean definition in case of a dynamically resolved Class 在动态解析类的情况下克隆 bean 定义 // which cannot be stored in the shared merged bean definition. 不能存储在共享的合并 bean 定义中 Class<?> resolvedClass = resolveBeanClass(mbd, beanName); if (resolvedClass != null && !
SpringConfig:
package com.lagou.edu; import com.alibaba.druid.pool.DruidDataSource; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.*; import javax.sql.DataSource; /** * @author 应癫 */ // @Configuration 注解表明当前类是一个配置类 @Configuration //开启注解扫描 @ComponentScan({"com.lagou.edu"}) //引入外部资源文件 @PropertySource({"classpath:jdbc.properties"}) //Import() 此注解是在这个配置类里引入其它配置类,将多个配置类都可以通过此注解引入,以此配置类为总入口, // 应用程序加载时加载这一个类就可以了 /*@Import()*/ public class SpringConfig { //@Value对变量复制 @Value("${jdbc.driver}") private String driverClassName; @Value("${jdbc.url}") private String url; @Value("${jdbc.username}") private String username; @Value("${jdbc.password}") private String password; //@Bean 将方法返回的对象加入SpringIOC容器中 @Bean("dataSource") public DataSource createDataSource(){ DruidDataSource druidDataSource = new DruidDataSource(); druidDataSource.setDriverClassName(driverClassName); druidDataSource.setUrl(url); druidDataSource.setUsername(username); druidDataSource.setPassword(password); return druidDataSource; } }
翻译:興趣使然的小胃
稿费:200RMB(不服你也来投稿啊!)
投稿方式:发送邮件至linwei#360,或登陆网页版在线投稿
一、前言
在过去的几年中,随着框架不断完善成熟,PowerShell也在不断获得人们的关注和欢迎,因此,在攻击行动中越来越多地看到PowerShell的身影也就不足为奇了。PowerShell为攻击者提供了系统各种原生功能支持,通过快速查看PowerShell恶意工具的泛滥形势,你可以对此类工具的增长态势有个整体了解。
微软对高版本的PowerShell做了些处理,提供了包括Transciption、ScriptBlock等多种方式来记录PowerShell的活动日志,因此基于PowerShell的攻击需要在运行时对其代码进行混淆编码。
首先让我们来看一下PowerShell的“-EncodedCommand”参数。
如PowerShell上述的使用说明,“EncodedCommand”是其一个命令,旨在对复杂字符串进行封装以便PowerShell在命令行中进行执行。你可以利用此命令对关键字符串进行隐藏,以躲避防护软件的探测。
本文主要有两个目的,其一,本文在“整体分析”中会分析利用Palo Alto Networks AutoFocus服务识别收集的4,100个PowerShell攻击样本(这些样本均使用了EncodedCommand技术),来了解PowerShell攻击中所使用的技术及攻击方式;其二,我将利用解码后样本对PowerShell代码进行分类,为后续识别或研究工作提供参考。
二、整体分析
在开始分析前,我首先需要识别使用该技术的样本。因为PowerShell为用户提供了多种灵活调用参数的方法,因此样本的识别工作并不像想象中的那么容易。
以下三个样本使用那个了三种不同的方法来调用EncodedCommand参数:
大多数编码数据都是利用模板或公开工具生成而来,每当攻击者需要运行shellcode或下载另一个恶意文件时,他们并不需要重复造轮子。这一点可以通过以下情况证实:攻击代码中的底层代码基本一致,只有其中的文件下载地址及其他信息存在略微不同。为了对数据进行分析,我需要尝试识别代码并确定代码的生成方式,或者至少能够对代码进行分组归类。
2.1 分析方法
为了说明这个工作的困难程度,我们可以回看2012年Matthew Graeber发布的一篇关于PowerShell脚本的博文,脚本可以加载shellcode至内存并运行。这个脚本也是此类技术的基础模板,大多数公开工具参考了脚本以期获得同样功能。
以下是TrustedSec系列工具中的社会工程学工具集(Social-Engineer Toolkit,SET)和Magic Unicorn工具经过两次迭代后的表现形式。对比两个样本,你可以发现,初始变量名上SET使用的是“$c”,而Magic Unicorn使用的是“$nLR”。与此类似,SET中“$size”与Magic Unicorn中“$g”对应,“$sc”与“$z”对应,“$x”与“$kuss”对应。
SET:
脚本使用3到4个随机数字字符对一些变量进行处理,但不是所有的变量都会被替换,因此我可以得知其变量生成机制。此外,如果没有经过Magic Unicorn脚本或其他形式的随机化处理,当这个特定片段被复制到其他工具中时我也可以鉴别出来。
对代码进行分析时,如果代码经过了许多人多年的重度重复使用,那么你总会碰到不适合分析的代码。我试图通过特征值尽可能准确地对代码进行分类,但不一定能做到足够准确,因为没有什么能够阻止别人简单地将代码复制粘贴到自己的工具中。
总体而言,我分析了27类公开工具或技术,它们具有独特的标识符,可以作为归类依据。在编号归类后我会对每个变种进行深度分析。首先我们来看一下变种的分支细目、样本数以及所占的样本百分比,如下表所示:
我们所分析的样本中,超过一半使用了“DownloadFile-StartProcess”技术或前文所述的shellcode注入技术。
2.2 整体分布及统计
我们在4,100个样本中发现了4中文件格式。如下表所示:
可知,EXE和DOC格式占了绝大部分。进一步后我们发现,77%的DOC文件(即1,326个样例)可以归到“Downloader DFSP”变种,该变种通过DownloadFile-StartProcess方法实现下载器功能,如以下代码所示:
有1,159个DOC文件样本(占比87%)可以归到Cerber勒索软件变种中,这意味着存在一款生成恶意Word文档的模板工具,可以用来创建带有启动PowerShell功能的恶意宏文档。
投递DOC文档的主要渠道是使用SMTP/POP3协议,这与现今勒索软件使用电子邮件进行恶意Word文档投递的情况一致。
图1. 投递恶意PowerShell文档的渠道
图2描述了攻击目标的行业分布,其中高等教育、高科技、专业领域、律政行业及医疗保健方面的分布所差无几。
图2. 检测到恶意PowerShell文档的行业分布
图3. AutoFocus在过去12个月捕获的恶意Powershell文档样本数。
接下来让我们看一下EXE样本。在分类方面,这些样本基本都是恶意软件家族的变种,没有特别的地方。有趣的是,它们的攻击目标似乎倾向于高科技行业。
图4. 检测到恶意PowerShell可执行文件的行业分布
与DOC类别样本相比,其在时间上的分布更为均匀。
图5. AutoFocus在过去12个月捕获的恶意PowerShell可执行文件样本数
以上状况的一种可能性是两类样本的分发渠道不同。比如DOC样本主要是通过电子邮件附件进行分发投递,而EXE样本主要是通过Web浏览器进行投递。
在对具体命令分析前,我要说的最后一件事是我们所检测到的使用EncodedCommand技术的一个DLL文件。这个DLL文件不包含导出函数,通过DLLMain入口调用后,该DLL会启动一个PowerShell Empire stager,从网站下载一个经过异或处理的脚本,并使用PowerShell的Invoke-Expression cmdlet运行。该样本与2021年10月Symantec发布的一篇博文中描述的Odinaff恶意软件家族的有关。
三、数据前期分析及统计
开始分析base64编码数据前,我观察了每个进程的启动方式,这种分析方法可以了解与EncodedCommand配合使用的附加参数情况。
3.1 EncodedCommand:(4,100个样本,占比100%)
使用此参数向PowerShell传递base64编码字符串并运行。
3.2 WindowStyle Hidden:(2,083个样本,占比50.8%)
使用此参数避免PowerShell执行时显示运行窗口。其中“-window hidden”方法使用最多主要与前文提到的Cerber勒索软件有关。
3.3 NonInteractive:(1,405个样本,占比42.4%)
使用此参数避免显示一个交互对话窗口。此方法与WindowStyle隐藏方法配合使用以隐藏执行痕迹。
三大遗憾 1.实习辞职遇疫情干扰,未能实现毕业旅行
实习经历–从2020年9月份开始,在学校巩固了一下前端的基础,便踏上寻找前端实习岗位的旅程。这段时间,投过许许多多的简历,但是由于之前没有相关的工作经验,回复不多,但也收到一些校招笔试的邀请,但因为自己算法方便确实是有些不足,最后错失了许多游戏行业机会,最后迫于学校压力,选择一家软件公司实习。在里面做的工作也就是修修补补。当然,收获还是有的,接触到了自动化部署一套流程和前端微服务框架项目,但没有自己从0到1搞过项目,缺乏对项目整体流程把控的经验。差不多到34月份凭借自己的努力也得到了认可,但想想在这里经常加班且待遇方面比较起来,性价比不高,最后选择另外一家靠电子商务的企业。因为不着急入职,想着在入职之前,好好去玩玩,但刚好碰上疫情干扰,无奈被迫放弃出远门的想法(坚持生命至上原则,哈哈哈哈)。
2.毕业匆匆,没有好好道别
“曾经的毕业季,我们是看客,往返于台阶,脚步匆忙,相机快门按下,捕捉不到我们的身影。只有我们自己知道,我们心里满是祝福语与憧憬。如今的毕业季,主角是我们,从容站在台阶,快门声响后,照片留下我们的身影,而我们已各自奔向自己热爱的远方”,这个是我在毕业时,写在朋友圈的一段后,感慨四年大学青春时光飞快,脚步匆匆,一心想逃离学校的牢笼,去实现自己积攒四年的目标。拍完毕业照当天下午,就收拾好行李,无需送别,独自走上广州搬砖的道路。大学期间,和舍友关系自我觉得甚好,走前的一天晚上,每人一打生蚝,想把湛江的味道留存于记忆中。我们经常开展“卧谈会”,会谈谈自己的一些打算和问题,偶尔会吐槽我上铺兄弟,哈哈哈。从大一开始,我们积极参加学校班级的各种活动,在此期间,也得到了一些锻炼,虽然在后来觉得我们好像是“小丑般”的存在,但不可否认的是,我们做了别人不敢做的事情,成长总是这样,会想起来,总是会让人觉得尴尬。
对这些兄弟,很遗憾的是,没有能和他们在毕业答辩前一起去旅行,但是忙于毕业论文的修改,心里放不下,想话多点时间做好一点,因此没有同去,很抱歉,为此,我心里总是觉得愧疚。
关于某某,很遗憾,我还是相望于江湖吧。薄情非我意,只是因为不想不堪往事。但现在想想,当初应该好好谈谈,就当做是一场自我救赎,一场愉快的告别,从此各自幸福吧。
3.参加工作之后,没有坚持写博客
猛然回头发现,我最新的一片文章竟然是2020年9月发表的文章,2021年几乎是0输出。为此我深感内疚。这一年,沉迷于网络游戏的时间过多,没有花花时间去过多总结学习和工作上的问题,我想,这个也是自己成长缓慢的原因。技术的输出是有必要的,因此我痛下决心,接下来的每周时间,输出两篇文章,请广大网友监督。
三大收获 1.换了新窝,得到舒服的生活和工作环境
实习期间,因为贫穷,和朋友租了环境较差的房子,生活得很压抑。在那种环境生活,容易影响人的心态(况且我这种人又是那种容易心情低落之人),那时候曾经堕落过一段时间,无心进取,无心社交,心里总是无法平静下来好好沉淀,致使成长过于缓慢,错失春招良好机会。但也不能归罪于环境的影响,最主要是自己心态不够强大,而被环境的邪恶力量干扰。
后来,捉住春招的末班车,得到一份还算可以的offer,于是,重新找房子,换了一个舒适的环境,每日沐浴着阳光醒来,是件幸福的事情。工作环境也挺OK,可以自己独立从0到1接触项目,成长速度比之前快了不少,觉得自己有进步,这种感觉可以使得人更加干劲。
2.收获了友谊,重拾篮球热爱
虽然有人说,工作与生活应该分离,但我觉得兴趣相投的人碰在一块,往往可以搞事情。除了日常工作与同事有接触外,我们会定期来一场篮球运动。虽然一开始总是尴尬与总是被保安赶,到后来有了“靠山”,打球这件小热爱,也可以定期实现。工作之后,还能来一场篮球,挥洒汗水与压力,是件幸福的事情。
3养成良好的生活习惯,过上更加自律生活
现在每天生活规律,早起早睡,哈哈哈,基本很少熬夜,还得感谢公司错峰上下班。虽然偶尔会失眠,但也不碍事,早晨一杯咖啡下去,状态满满。我改掉许多之前不良生活习惯,感觉自己有种可以把控生活的能力,不想以前,总是缺乏自律,状态很糟糕,为此,我下决心,改过自新,好好找回以前的自己。
2022年的目标与期望 1.坚持学习,每周总结与输出必要的心得
2.在工作上,扩大自己的影响力,成为中坚力量
3.在生活上,保持自律,为了更加没有的未来,好好控制的欲望,适当游戏,适当学习,适当社交