---
# System prepended metadata

title: 驗證碼繞過on server

---

# 驗證碼繞過on server
- 驗證碼
	- 功用
		- 防止登錄暴力破解
		- 防止機器惡意註冊
	- 流程
		- 客戶端request登錄頁面,後台生成驗證碼
		- 生成驗證碼
			- 後台使用演算法生成圖片,並將圖片response給客戶端
			- 同時將算法生成的值全局賦值存到SESSION中
		- 校驗驗證碼
			- 客戶端將認證信息和驗證碼一同提交
			- 後台對提交的驗證碼與SESSION里面的進行比較
			- 客戶端重新刷新頁面,再次生成新的驗證碼
			- 驗證碼算法中一般包含隨機函數,所以每次刷新都會改變
	
- 常見問題 (服務端認證不嚴格)
	- 驗證碼在後台不過期,導致可以長期被使用
	- 驗證碼校驗不嚴格,邏輯出現問題
	- 驗證碼設計的太過簡單和有規律,容易被猜解

- 漏洞
	- 驗證碼無時效性 沒有被銷毀
- source code分析
  ![image](https://hackmd.io/_uploads/ByLfF3RL6.png)
  
  ![image](https://hackmd.io/_uploads/B1sfYhRUa.png)

	
	 ```php
	  <?php
	  /**
	   * Created by runner.han
	   * There is nothing new under the sun
	   */
	  
	  $PIKA_ROOT_DIR =  "../../";
	  include_once $PIKA_ROOT_DIR.'inc/config.inc.php';
	  include_once $PIKA_ROOT_DIR.'inc/mysql.inc.php';
	  
	  
	  $SELF_PAGE = substr($_SERVER['PHP_SELF'],strrpos($_SERVER['PHP_SELF'],'/')+1);
	  if ($SELF_PAGE = "bf_server.php"){
	      $ACTIVE = array('','active open','','','active',"","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","");
	  
	  }
	  
	  include_once $PIKA_ROOT_DIR.'header.php';
	  
	  
	  $link=connect();
	  
	  
	  $html="";
	  if(isset($_POST['submit'])) {
	      if (empty($_POST['username'])) { //先判斷username是否為空
	          $html .= "<p class='notice'>用户名不能为空</p>";
	      } else {
	          if (empty($_POST['password'])) {//再判斷password是否為空
	              $html .= "<p class='notice'>密码不能为空</p>";
	          } else {
	              if (empty($_POST['vcode'])) {//再判斷驗證碼是否為空
	                  $html .= "<p class='notice'>验证码不能为空哦！</p>";
	              } else {
	  //              验证验证码是否正确
	                  if (strtolower($_POST['vcode']) != strtolower($_SESSION['vcode'])) {//驗證碼認證
	                      $html .= "<p class='notice'>验证码输入错误哦！</p>";
	                      //应该在验证完成后,销毁该$_SESSION['vcode'] leak!!!
	                  }else{
	  
	                      $username = $_POST['username']; //再驗證username和password
	                      $password = $_POST['password'];
	                      $vcode = $_POST['vcode'];
	  
	                      $sql = "select * from users where username=? and password=md5(?)";
	                      $line_pre = $link->prepare($sql);
	  
	                      $line_pre->bind_param('ss',$username,$password);
	  
	                      if($line_pre->execute()){
	                          $line_pre->store_result();
	                          //虽然前面做了为空判断,但最后,却没有验证验证码!!!
	                          if($line_pre->num_rows()==1){
	                              $html.='<p> login success</p>';
	                          }else{
	                              $html.= '<p> username or password is not exists～</p>';
	                          }
	                      }else{
	                          $html.= '<p>执行错误:'.$line_pre->errno.'错误信息:'.$line_pre->error.'</p>';
	                      }
	                  }
	              }
	          }
	      }
	  }
	  
	  
	  
	  ?>
	  
	  
	  <div class="main-content" xmlns="http://www.w3.org/1999/html">
	      <div class="main-content-inner">
	          <div class="breadcrumbs ace-save-state" id="breadcrumbs">
	              <ul class="breadcrumb">
	                  <li>
	                      <i class="ace-icon fa fa-home home-icon"></i>
	                      <a href="burteforce.php">暴力破解</a>
	                  </li>
	                  <li class="active">验证码绕过(on server)</li>
	  
	              </ul><!-- /.breadcrumb -->
	              <a href="#" style="float:right" data-container="body" data-toggle="popover" data-placement="bottom" title="tips(再点一下关闭)"
	                 data-content="这个验证码好像一直有效哎!用户还是那三个默认用户.">
	                  点一下提示~
	              </a>
	  
	          </div>
	  <div class="page-content">
	  
	  
	  <div class="bf_form">
	      <div class="bf_form_main">
	          <h4 class="header blue lighter bigger">
	              <i class="ace-icon fa fa-coffee green"></i>
	              Please Enter Your Information
	          </h4>
	  
	          <form method="post" action="bf_server.php">
	  <!--            <fieldset>-->
	                  <label>
	                      <span>
	                          <input type="text" name="username" placeholder="Username" />
	                          <i class="ace-icon fa fa-user"></i>
	                      </span>
	                  </label>
	                  </br>
	  
	                  <label>
	                      <span>
	                          <input type="password" name="password" placeholder="Password" />
	                          <i class="ace-icon fa fa-lock"></i>
	                      </span>
	                  </label>
	                  </br>
	                  <label>
	                          <span>
	                              <input type="text" name="vcode" placeholder="验证码" />
	                              <i class="ace-icon fa fa-lock"></i>
	                          </span>
	                  </label>
	                  </br>
	                  <label>
	                      <img src="../../inc/showvcode.php" onclick="this.src='../../inc/showvcode.php?'+new Date().getTime();" />
	                  </label>
	  
	  
	                  <div class="space"></div>
	  
	                  <div class="clearfix">
	                      <label><input class="submit" name="submit" type="submit" value="Login" /></label>
	                  </div>
	  
	          </form>
	          <?php echo $html;?>
	  
	  
	      </div><!-- /.widget-main -->
	  
	  </div><!-- /.widget-body -->
	  
	  
	  
	  </div><!-- /.page-content -->
	  </div>
	  </div><!-- /.main-content -->
	  
	  
	  
	  <?php
	  include_once $PIKA_ROOT_DIR.'footer.php';
	  ?>
	  ```
	- session要設置過期時間 此題無設置
		![image](https://hackmd.io/_uploads/S13BFhCIa.png)

	- 驗證碼function.php
		![image](https://hackmd.io/_uploads/B188Fn0UT.png)
        
        ![image](https://hackmd.io/_uploads/ByjIKnR8T.png)

- 爆破流程
	- 用burp suite抓包
	- 傳至repeater進行下一步分析
		- 查看source code發現驗證碼由JavaScript隨機生成，藉由點擊一次函數生成相應驗證碼
			![image](https://hackmd.io/_uploads/BJ-OF3AIp.png)

		- 故使用repeater
			![image](https://hackmd.io/_uploads/B1t_FhAIa.png)

	- 先將驗證碼改成正確的再發送
		- 回應  ``username or password is not exist ~``
		![image](https://hackmd.io/_uploads/HyNtYhRLT.png)

	- 嘗試改username和password 傳送
		- 皆傳回``username or password is not exist ~`` ，都沒有回傳驗證碼錯誤
		- 可以發現驗證碼並沒有被驗證
		- ---> 發現驗證碼不過期漏洞
	- 開始爆破
		- send to intruder
		- 將參數設定在username和password上
		- Attack Type選擇Cluster Bomb
		  id:: 652a5cc8-b255-47ad-82e1-91993768a074
		- 設定字典
			- 第一個參數username
				![image](https://hackmd.io/_uploads/HJh5Yn0UT.png)

			- 第二個參數password
				- 使用numbers
				![image](https://hackmd.io/_uploads/BJrjYnCIT.png)
			- (optional)設定查看有無輸出``username or password is not exist ~``
				- 也可直接查看長度來爆破
				- 選擇 options
					- Grep - Match
						- 在grep-match中刪除原有字符串,添加username or password is not exists, burp就會將所有含有此字符串的數據包flag出來。沒有被flag出的數據包則是我們破解成功的數據包
						![image](https://hackmd.io/_uploads/ByQ3Kh0LT.png)

					- Grep - Extract
						- 搜尋``username or password is not exist ~``
						
						![image](https://hackmd.io/_uploads/BJls2thCL6.png)
	- 結果
		![image](https://hackmd.io/_uploads/SkvRtnCIa.png)
        
		- 點擊username or password is not exists進行排序,沒有勾選的則表明破解成功,有勾選的則表明破解失敗。
			
		![image](https://hackmd.io/_uploads/Bklk5nRUa.png)

- [pikachu靶场通关之暴力破解](https://developer.aliyun.com/article/1044330)
- [Pikachu靶场通关秘籍---暴力破解---验证码绕过（On Server）](https://www.cnblogs.com/redHskb/p/16799610.html)]