Secret 发布的文章

我一直相信,每个宣称自己是黑客的青少年,一定都有着某种非主流的情怀,这情怀无法由颜值担当,就只能籍技术派遣。我也不例外。 ——来自《我的校园黑客故事》 - 王登科

很多热爱网络的人都向往着黑客,这种情愫在懵懂时最是旺盛而又随着年龄逐渐淡去。我接触互联网的时间有些晚,也正是互联网聚变的时期,不过那个时候肉鸡还满山跑,宽带付费最是火热的时候。

我的黑客启蒙也是在那个时候开始的。懵懂时期的一些事儿实在丢人现眼,就从高中毕业开始说起吧。

考上专科几乎没有其他原因,高中不努力。而我打算报考单独招生考试,流程大概是先到意向学校官网报名,然后缴费,按考试时间参加学校的考试,最后就是等录取消息了。在各种纠结之后,还是网上报名了母校的单招考试。

而不争的事实是每个学校都有一个漏洞百出的官网。报完名之后,习惯性的翻了翻学校的站点,asp写的后台,在版权信息部分找到了管理入口,进入后习惯性的试了几个弱口令,未果。准备关掉浏览器的时候试着注入。

「欢迎回来,管理员。」

对,这么草率。抑制住内心的欣喜开始爬后台。按照以往的流程是:找上传入口->上传木马(按服务器防火墙的机制大概分为一句话马、小马、大马、图片马等等)-> 然后上传cmd.exe提权。

没找到上传入口!?

带着疑问,翻看已经发布的文章,居然还真没发过一张图片。只好作罢,继续看看还有什么有价值的东西。虽然没有上传入口,而这个账号的权限却不低,关闭报名入口,删改/下载学院的学生名单都不在话下,甚至在文章里追加一段恶意 javascript 还可以继续深挖。

快速浏览了后台,名单中包含的信息非常详细,姓名、年龄、身份证、手机号,甚至你家住哪儿村哪个屯。看着庞大的表格,居然有些不知所措。

这是否可以做点文章?

那是当然,在离考试前几天,我将它参照乌云的格式写成漏洞报告书然后打印了出来。详细的论述了漏洞地址,漏洞属性,漏洞测试,然后把后台截了两张图,最后,写出了两点修复意见。要么就把管理界面隐藏起来,要么就是过滤关键字或者转义(想都不用想肯定后者啊)。

考试前一天,特长生需要提前到学校报道,把高中的各种证书拿出来复印了一份,临走前将漏洞报告书递给招生老师,让帮忙带给网站管理员。其实提交报告书的时候,手都在抖。就算报告书尾页强调的「以上为友情测试,本人承认未下载、删除、修改任何数据,未公开该漏洞…」,但是「未经过授权的渗透测试属于违法行为」

走出校门,自豪感涌上心头。

事后发现当时的行为实在鲁莽,也十分感谢学校既往不咎:

非常感谢提交漏洞和对xxxx的支持,我们已第一时间将漏洞修复完毕,并抓捕了你。 —— 袁炜事件

后来啊。一直忙于各种闲事儿,也很少去搞破事儿了。不过大二左右,无聊逛着学校官网,找到图书馆的系统,通过机房内网尝试注入,找到上传漏洞并上传了小马,接着写了一只大马,提权进入了服务器,不过该站点长时间未更新又是一个很偏的一个子系统,C盘D盘草草翻了下也没有什么价值,然后溜达了一圈就关掉了。

从 QQ 空间翻出来的老照片

刚刚想起来还有这茬,重新打开图书馆官网看到最近有更新文章,便联系站点底部馆长邮箱,告知该漏洞信息并提醒修复,发出去两分钟就给回信了,『好的,谢谢你!』,不过该漏洞尚未修复,也就暂不公开了,邮件截图等漏洞修复完成了再补图吧。

更新:2017-8-29 补图邮件

2017-8-29 补图

我始终未成为理想中的黑客,却发展成了与之对立的码农。

我还在为生存卖力,为生活拼搏。你我共勉之。

以上,我的黑客故事。

世上三大最难懂:医生的处方、道士的符、程序员的正则

学了几年编程,也写了不少项目,业务逻辑经验攒了一堆,基础知识却落下不少。其中很多还非常重要,比如:进制换算、正则表达式、算法。当初学这些东西的时候,对高数的抗拒让我对带计算的东西也十分抵触。但是,身为码农,这些基础都不懂还怎么拿代码换烟钱?于是,决定恶补一下。

正则表达式

正则表达式,又称正规表示式、正规表示法、正规表达式、规则表达式、常规表示法(英语:Regular Expression,在代码中常简写为regex、regexp或RE),是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些匹配某个模式的文本。 ——来自维基百科

使用场景

正则表达式起始日常生活中也用过,比如搜索的时候用的*匹配(好吧,那个应该准确的叫做通配符,反正差不多就这意思嘛),下面谈谈正则使用的场景:

  1. 手机号、邮箱、
  2. URL判断
  3. 配置文件、检索关键字
  4. 模板引擎

使用原则

由于正则会将通常一串字符挨个检索,如果没找到匹配项,会从开头一直匹配到结尾,所以说,正则表达式的效率非常低的,能用内置函数尽量用内置函数。不过,一些特定场景正则表达式有他独有的优势

总结:能不用就尽量不用。

语法定义

能不用就不用不代表不学习啊,万一哪天面试就考到你正则不可能瞎写一通吧。即便是做项目在网上复制的现成的也要明白个大概意思。

组成部分

其实组成部分是很多的,这里只做基础介绍。以能写出简单正则,能看懂正则意思为目的。

正则的组成:

  1. 定界符
  2. 原子
  3. 元字符
  4. 模式修正符

匹配规则:

  1. 从左到右
  2. 默认贪婪匹配(简述就是匹配成功后继续匹配,参见#贪婪模式

定界符

定界符是正则表达式的边界,这个没有严格规定,通常以/作为正则的定界符。规则是:不能使用0-9a-zA-Z\和空格。

原子

原子在化学中讲过吧,是最小的单位。而正则中的原子同理,也是正则中最小的单位,不可再分割了。

  • \d:包含0-9
  • \D:不包含0-9
  • \w:包含0-9a-zA-Z_
  • \W:不包含0-9a-zA-Z_
  • \s:包含空白字符、空格、\n\t\r
  • \S:不包含上诉空白字符
  • \b:词边界
  • \B:非词边界
  • []:原子列表,可匹配列表原子或字符出串
  • [^]:取反,写在原子列表里为取反
  • .:除\n以外任意字符

元字符

元字符是用来修饰原子的,不能单独存在,写在原子之后

  • *:匹配任意次
  • +:至少出现一次
  • ?:可有可无,最多一次
  • {}:指定次数

    • {10}:指定十次
    • {3,5}:指定3-5次
    • {3,}:至少3次
    • {0,3}:0-3次
  • ^:指定以某个原子开头(千万别记混[^]^的区别)
  • \A:与^相同
  • $:指定以什么结尾
  • \Z:与$相同
  • |:或
  • ():限制优先级,括号里为一个整体。子模式:参见#子模式

模式修正符

与元字符用于修饰原子,而模式修正符用于修正整个正则表达式。而模式修正符必须写在正则表达式的后面

  • i:忽略大小写
  • m:多行匹配
  • s:让.匹配到\n
  • x:忽略正则表达式中的空格
  • A:与\A^一样
  • U:正则贪婪模式取反

组合

原子与不同元字符组合可以达到很多的效果,而多个元字符可以同时修饰一个原子

  • .+?:取消贪婪匹配,只匹配一个字符
  • .*?:取消贪婪匹配,匹配出0个字符

贪婪模式

仅从应用角度分析,可以这样认为,贪婪模式,就是在整个表达式匹配成功的前提下,尽可能多的匹配,也就是所谓的“贪婪”,通俗点讲,就是看到想要的,有多少就捡多少,除非再也没有想要的了。 ——来自[正则基础之——贪婪与非贪婪模式
](http://blog.csdn.net/lxcnn/article/details/4756030)

子模式

我们可以使用小括号给整个匹配模式进行分组,默认情况下,每个分组会自动拥有一个组号,规则是,从左到右,以分组的左括号为标志,第一个出现的分组为组号1,第二个为组号2,以此类推。其中,分组0对应整个正则表达式。对整个正则匹配模式进行了分组以后,就可以进一步使用“向后引用”来重复搜索前面的某个分组匹配的文本。例如:\1代表分组1匹配的文本,\2代表分组2匹配的文本等等 ——来自正则表达式的子模式详解

样例

由于正则的字符实在"火星",所以需要多加练习才能真正明白其匹配规则,下面写几个样例,以后需要直接用。

判断手机号

分析

手机号一般为11位纯数字,1打头,第二位号码段主要以3,4,5,7,8为主(个人猜测),第三位到最后一位为0-9的随机数。

代码

/^1[34578]\d{9}$/

判断邮箱

分析

邮箱号格式是[email protected],字符串中包含一个@和一个.,其他字符分为三段,第一段以0-9a-zA-Z-_组成且至少一位,第二段以0-9a-zA-Z-组成且至少一位,第三段以a-zA-Z组成且至少两位(中文域名就算了吧)。

代码

/\w[-\w.+]*@([A-Za-z0-9][-A-Za-z0-9]+\.)+[A-Za-z]{2,14}/

总结

在实际开发中所遇到的正则无非就那么几种,网上有很多大佬写好的直接可以用,而自己写的一些正则可以存下笔记,以便以后遇到相同的需求可以直接使用,毕竟效率最重要。

文档

个人用伪类在布居中比较频繁,因为觉得能用CSS完成的动画,尽量不用JS,总觉得JS或多或少会影响页面加载速度和流畅度,个人觉得比较经典,其中也有很多平常开发中遇到的一些小问题,也终于有了解释,所以写篇文章总结下。

伪类?

先来回顾伪类的使用方法,类/标签名:伪类类型便可以构造一个伪类:

selector:pseudo-class {
    property: value;
    ...
}

.class:pseudo-class {
    property: value;
    ...
}

常用的伪类:hoveractivevisitedlinkfirst-childlast-childnth-child(n)等等。

小问题

问题1

现在一个页面,需要实现a标签不同伪类下颜色不同,代码如下:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Pseudo - Secret Blog</title>
    <style type="text/css">
        a:hover {
            color: red;
        }

        a:visited {
            color: blue;
        }

        a:link {
            color: green;
        }

        a:active {
            color: yellow;
        }
    </style>
</head>
<body>
    <a href="#">Click it!</a>
</body>
</html>

效果演示:Pseudo - Secret Blog

有错么?代码看起来没错呀,我hover去哪儿呢?之前也遇到过类似的问题,代码没错啊,怎么没效果呢?

W3C中提到(CSS 伪类):

提示:在 CSS 定义中,a:hover 必须被置于 a:link 和 a:visited 之后,才是有效的。
提示:在 CSS 定义中,a:active 必须被置于 a:hover 之后,才是有效的。
提示:伪类名称对大小写不敏感。

上面提到hover必须放到linkvisited之后,而active又要放到hover之后,所有正确的书写顺序是:link -> visited -> hover -> active

问题2

first-childlast-child非常好用,使用方式各式各样,一般用于修改第一个或者最后一个的样式,下列代码大家来分析下,看看有什么错误:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Child - Secret Blog</title>
    <style type="text/css">
        ul li:first-child{
            color: red;
        }
        ul li:nth-child(2){
            color: blue;
        }
        ul li:nth-child(3){
            color: yellow;
        }
        ul li:last-child{
            color: green;
        }
    </style>
</head>
<body>
    <ul>
        <p>List</p>
        <li>First</li>
        <li>Second</li>
        <li>Third</li>
        <li>Last</li>
        <p>List End</p>
    </ul>
</body>
</html>

效果演示:child - Secret Blog

和预想的效果有差异?第一个不是红色字体而是是蓝色呢?第二个不是蓝色又是黄色的,还有最后一个的绿色也没了。

W3C解释(原文地址):

利用 :first-child 这个伪类,只有当元素是另一个元素的第一个子元素时才能匹配。例如,p:first-child 会选择作为另外某个元素第一个子元素的所有 p 元素。一般可能认为这会选择作为段落第一个子元素的元素,但事实上并非如此,如果要选择段落的第一个子元素,应当写为 p > *:first-child。

只有当元素是另一个元素的第一个子元素时才能匹配,通俗的讲,就是上面代码里,div li:frist-child并不是指向下面ul中的第一个li,因为li并不在ul中的一个元素。last-child同理。

nth-child的指向,仔细看一下就会发现,如果将p标签作为第一个的话,那么颜色就没错。而浏览器也正是这样解析的。

总结

CSS 中伪类是一个很奇怪的东西,很多错误发生在细节上却毫无察觉。

今天在Windows下安装了次Node.js环境,其中也涉及到了git的安装和初始化,或许是之前学习的时候太皮,很多命令、参数都忘得干干净净。这次不妨做个笔记,以后可能(一定)会用到。

环境

  • 操作系统:Windows 10 Version 10.0.15063
  • 安装工具:Bash On Ubantu On Windows(以下简称:WinBash)
注:因为WinBash还存在很多尚不明确的因素,安装环境受系统版本及网络影响。Ubantu、CentOS等Linux衍生系统安装方法类似。本次安装仅作参考。

注:若使用WinBash请先开启Windows开发者模式,开启方法请自行搜索。

开始

安装Git

使用apt-get经行安装,命令:

$ sudo apt-get install git

然后输入y,完成安装。

检查安装

可以执行git命令查看是否安装成功,命令:

$ git
usage: git [--version] [--help] [-C <path>] [-c name=value]
           [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
           [-p | --paginate | --no-pager] [--no-replace-objects] [--bare]
           [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
           <command> [<args>]
$ git --version
git version 2.7.4

配置Git

git安装完成,需要初始化用户信息,这通常是全局的,命令如下:

# 配置用户名
$ git config --global user.name "your_name"
# 配置邮箱地址
$ git config --global user.email "your_email"

生成&验证SSH公匙

公匙用于Github或服务器的免密登录的一个口令,一个公匙可多方登录,由于SSH的重要性,请勿泄露公匙。

公匙存在在~/.ssh目录下的id_rsa.pub,如果不存在先生成,存在则直接查看:

# 生成公匙
$ ssh-keygen -t rsa -C "[email protected]"
# 接下来直接敲三个回车
# 查看公匙
$ cat ~/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCwdB8G/vCpmZu3yI7N62GqykMcBhWZ5BI34rnBXM9CNtXASGD3Pg7erkn0kuOSzSm9RkoRtnmbA/D9TNqMxNtXUxHHjEw27yFPffit1b5Zjj651Kp.......... [email protected]

关于ssh-keygen命令参数解释:

  • -t:申明密匙类型,参数:"rsa1"(SSH-1)、"rsa"(SSH-2)、"dsa"(SSH-2)
  • -C:添加注释

验证SSH公匙

将SSH公匙添加到GithubCoding中的SSH公匙管理中,下一步操作即是验证公匙是否可用,命令:

# Github与Coding验证地址不同,以下以Github为例
$ git -T [email protected]

创建远程仓库

代码管理离不开远程仓库,远程仓库能随时同步代码、多人协助、版本回滚等。

远程仓库国内推荐使用CodingGithub,当然,类似的平台还有码云。在Github上,直接点击New repository建立仓库。

比如,我现在创建一个仓库名为test的仓库:

新建仓库

配置解释:

  • Repository name: 仓库名,不可于当前用户的其他仓库名重名
  • Public / Private: 项目是否公开,这里说明一下的是Github的私有项目是收费的
  • Add README: 是否初始化时建立README.md说明文件
  • Add .gitignore: 是否创建忽略.gitignore配置文件
  • Add license: 是否添加协议

Git基础

建立仓库

创建完成远程仓库,转向本地,初始化本地Git仓库:

# 创建目录
$ mkdir your_project/
# 切换到目录
$ cd your_project/
# 初始化仓库,创建.git目录,将此目录作为git工作空间
$ git init
Initialized empty Git repository in /Users/secret/Desktop/test/.git/

初始化完成本地仓库,需要将本地仓库和远程仓库进行关联:

首先需要获取远程仓库的地址,可以打开刚刚新建的test的仓库:

获取远程仓库链接

在输入框中的内容就是该仓库的远程地址,最右边可以一键复制。

现在将本地仓库与远程仓库进行关联:

$ git remote add origin [email protected]:isecret/test.git

存入缓存区并提交

可以先尝试创建一个文件,然将它添加到缓存中:

# 创建test.txt文件
$ touch test.txt
# 编辑该文件,你同样可以选择其他编辑器
$ vim test.txt
# 保存完成后,将其添加到缓存中
$ git add test.txt
# 提交本次修改
$ git commit -m 'Create and edited test.txt'
[master (root-commit) 40a635b] Create and edited test.txt
 1 file changed, 1 insertion(+)
 create mode 100644 test.txt

参数说明:

  • git add 文件名是将此文件加入缓存区,也可以使用git add .将此目录加入缓存区
  • git commit-m参数是给此次提交的动作给一个描述,比如修改了什么地方,修复了什么Bug等
  • git add .git commit -m '描述'可以合并写为git commit -am '描述'

查看提交记录

文件修改后提交至缓存区后,便会生成一个提交记录的HEAD信息及其描述,在后续使用可以回滚到当前版本。好比于修改代码,越改越乱的情况,就可以直接回到上一个版本重新来写。

# 查看提交版本,commit后边的内容便是版本号,最后一行是注释信息
$ git log
commit c172fa948ab343276c84ec3bbf11d0c0cd027b3c
Author: isecret <[email protected]>
Date:   Sun Jul 23 12:57:36 2017 +0800

    Create and edited test.txt

查看修改记录及状态

这个顾名思义,查看当前版本的改动。在Github上能高亮显示出,不过在命令行也能查看到。

首先,我先在text.txt中再增加一段Hello World,然后查看改动:

# 增加一段Hello World!
$ vim test.txt
Hello Git!Hello World!
$ git diff
diff --git a/test.txt b/test.txt
index 106287c..d149c10 100644
--- a/test.txt
+++ b/test.txt
@@ -1 +1 @@
-Hello Git!
+Hello Git! Hello World!
# 插入:2,内容 Thanks for us!
$ vim test.txt
# 查看当前状态
$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   test.txt

no changes added to commit (use "git add" and/or "git commit -a")

参数说明:

  • 直接使用git diff用于查看当前未git add的内容修改
  • 已经git add但还没提交,使用git diff --cached查看内容修改
  • git diff HEAD是上面两条的合并
  • git diff HEAD1 HEAD2 src可以比较两个版本的src文件夹的差异
  • git status会列出还没添加到缓存区的文件/目录

分支

分支在Git中是一个很重要的概念,意味着你能脱离主线开发,在不影响主线的情况下还能继续工作。

而分支又简单分为基础操作、冲突合并、分支管理、bug分支、远程分支。

查看分支

# 查看当前所有分支
$ git branch -a
* master

折腾完hexo,开始处理一些小细节,之前调试主题的时候就发现NexT并没有对代码进行压缩处理,详情见:如何优化NexT主题?

为何要压缩代码?

首先,没有比较就没有伤害:

压缩前后对比图

这是主页压缩前后的对比图,主要将多余空格和换行给去掉,CSS和JS同理。

压缩的优势?列出以下四点,欢迎补充:

  • 减小了文件的体积
  • 减小了网络传输量和带宽占用
  • 减小了服务器的处理的压力
  • 提高了页面的渲染显示的速度

gulp能做什么?

gulp是一款基于Node.js的一款利用数据流自动化构建工具,利用其插件可以对文件进行IO操作,其中包括压缩代码等功能。

gulp的安装

注:安装此插件务必确认安装Node环境及包管理工具(npm或cnpm)

任何一款js插件,首先是参考文档说明。详见:官方文档

首先,需要安装gulp及其配套的插件。

$ cd blogdir/
$ cnpm install gulp --save
$ cnpm install gulp-htmlclean --save
$ cnpm install gulp-htmlmin --save
$ cnpm install gulp-minify-css --save
$ cnpm install gulp-uglify --save

注:cnpm为淘宝npm镜像,如果发现cnpm提示command not found,请自行安装或使用npm,使用方法与npm相同,不过将镜像存储在国内加快包下载速度。

完成后查看package.json是否包含上列安装的包:

"dependencies": {
    "gulp": "^3.9.1",
    "gulp-htmlclean": "^2.7.14",
    "gulp-htmlmin": "^3.0.0",
    "gulp-imagemin": "^3.3.0",
    "gulp-minify-css": "^1.2.4",
    "gulp-uglify": "^3.0.0",
    "hexo": "^3.2.0",
    "hexo-deployer-git": "^0.3.0",
    "hexo-generator-archive": "^0.1.4",
    "hexo-generator-category": "^0.1.3",
    "hexo-generator-index": "^0.2.0",
    "hexo-generator-tag": "^0.2.0",
    "hexo-renderer-ejs": "^0.2.0",
    "hexo-renderer-marked": "^0.2.10",
    "hexo-renderer-stylus": "^0.3.1",
    "hexo-server": "^0.2.0"
  }

然后新建gulpfile.js文件到hexo根目录,内容如下:

var gulp = require('gulp');

//Plugins模块获取
var minifycss = require('gulp-minify-css');
var uglify = require('gulp-uglify');
var htmlmin = require('gulp-htmlmin');
var htmlclean = require('gulp-htmlclean');

// 压缩 public 目录 css文件
gulp.task('minify-css', function() {
    return gulp.src('./public/**/*.css')
        .pipe(minifycss())
        .pipe(gulp.dest('./public'));
});

// 压缩 public 目录 html文件
gulp.task('minify-html', function() {
  return gulp.src('./public/**/*.html')
    .pipe(htmlclean())
    .pipe(htmlmin({
         removeComments: true,
         minifyJS: true,
         minifyCSS: true,
         minifyURLs: true,
    }))
    .pipe(gulp.dest('./public'))
});

// 压缩 public/js 目录 js文件
gulp.task('minify-js', function() {
    return gulp.src('./public/**/*.js')
        .pipe(uglify())
        .pipe(gulp.dest('./public'));
});


// 执行 gulp 命令时执行的任务
gulp.task('default', [
    'minify-html','minify-css','minify-js'
]);

至此,安装完成。

gulp的使用

gulp的使用很简单,只需要在部署之前将代码压缩即可:

$ hexo clean
$ hexo g
INFO  Start processing
INFO  Files loaded in 723 ms
INFO  Generated: index.html
$ gulp
[13:18:33] Using gulpfile ~/blog/gulpfile.js
[13:18:33] Starting 'minify-html'...
[13:18:33] Starting 'minify-css'...
[13:18:33] Starting 'minify-js'...
$ hexo d
INFO  Deploying: git
INFO  Clearing .deploy_git folder...
INFO  Copying files from public folder...