关于RDPY
RDPY是一款功能强大的RDP远程桌面协议实现工具,该工具基于纯Python开发,并提供了完整的客户端和服务器端应用程序。
RDPY基于事件驱动的网络引擎Twisted构建,RDPY支持标准RDP安全层、RDP over SSL和NLA认证(通过ntlmv2认证协议)。
RDPY提供了下列RDP和VNC代码:
1、RDP中间人代理(用于记录会话);
2、RDP蜜罐;
3、RDP截图工具;
4、RDP客户端;
5、VNC客户端;
6、VNC截图工具;
7、RSS Player;
工具下载
由于该工具基于Python开发,因此我们首先需要在本地设备上安装并配置好Python环境。
接下来,广大研究人员可以使用下列命令将该项目源码克隆至本地:
git clone https://github.com/citronneur/rdpy.git
需要注意的是,该工具所实现的bitmap解压缩算法考虑到性能问题,所以使用了C代码实现。
代码构建
该工具所使用的pyqt4需要用到下列依赖组件:
rdpy-rdpclient
rdpy-rdpscreenshot
rdpy-vncclient
rdpy-vncscreenshot
rdpy-rssplayer
Linux:
sudo apt-get install python-qt4
macOS:
$ brew install qt sip pyqt
Windows:
构建命令如下:
$ git clone https://github.com/citronneur/rdpy.git rdpy
$ pip install twisted pyopenssl qt4reactor service_identity rsa pyasn1
$ python rdpy/setup.py install
或使用pip命令构建:
$ pip install rdpy
如需使用Virtualenv,你还需要链接qt4库:
$ ln -s /usr/lib/python2.7/dist-packages/PyQt4/ $VIRTUAL_ENV/lib/python2.7/site-packages/
$ ln -s /usr/lib/python2.7/dist-packages/sip.so $VIRTUAL_ENV/lib/python2.7/site-packages/
工具使用
RDPY提供了一些非常有用的代码库,这些代码库适用于Linux和Windows操作系统。
rdpy-rdpclient
rdpy-rdpclient是一个简单的RDP Qt4客户端:
$ rdpy-rdpclient.py [-u username] [-p password] [-d domain] [-r rss_ouput_file] [...] XXX.XXX.XXX.XXX[:3389]
rdpy-vncclient
rdpy-vncclient是一个VNC Qt4客户端:
$ rdpy-vncclient.py [-p password] XXX.XXX.XXX.XXX[:5900]
rdpy-rdpscreenshot
rdpy-rdpscreenshot可以将登录屏幕截图保存到文件中:
$ rdpy-rdpscreenshot.py [-w width] [-l height] [-o output_file_path] XXX.XXX.XXX.XXX[:3389]
rdpy-vncscreenshot
rdpy-vncscreenshot可以将第一个界面保存到文件中:
$ rdpy-vncscreenshot.py [-p password] [-o output_file_path] XXX.XXX.XXX.XXX[:5900]
rdpy-rdpmitm
rdpy-rdpmitm是一个RDP代理,允许我们针对RDP协议执行中间人攻击:
$ rdpy-rdpmitm.py -o output_dir [-l listen_port] [-k private_key_file_path] [-c certificate_file_path] [-r (for XP or server 2003 client)] target_host[:target_port]
rdpy-rdphoneypot
rdpy-rdphoneypot是一个RDP蜜罐,可以在记录会话场景(RSS)中通过RDP协议重放攻击场景:
$ rdpy-rdphoneypot.py [-l listen_port] [-k private_key_file_path] [-c certificate_file_path] rss_file_path_1 ... rss_file_path_N
rdpy-rssplayer
rdpy-rssplayer用于重放rdpy-rdpmitm或rdpy-rdpclient生成的RSS文件:
$ rdpy-rssplayer.py rss_file_path
独立RDPY库
我们还可以将该项目以一个独立协议代码库(+网络引擎Twisted)来使用。
RDP客户端
from rdpy.protocol.rdp import rdp class MyRDPFactory(rdp.ClientFactory): def clientConnectionLost(self, connector, reason): reactor.stop() def clientConnectionFailed(self, connector, reason): reactor.stop() def buildObserver(self, controller, addr): class MyObserver(rdp.RDPClientObserver): def onReady(self): """ @summary: Call when stack is ready """ #send 'r' key self._controller.sendKeyEventUnicode(ord(unicode("r".toUtf8(), encoding="UTF-8")), True) #mouse move and click at pixel 200x200 self._controller.sendPointerEvent(200, 200, 1, true) def onUpdate(self, destLeft, destTop, destRight, destBottom, width, height, bitsPerPixel, isCompress, data): """ @summary: Notify bitmap update @param destLeft: xmin position @param destTop: ymin position @param destRight: xmax position because RDP can send bitmap with padding @param destBottom: ymax position because RDP can send bitmap with padding @param width: width of bitmap @param height: height of bitmap @param bitsPerPixel: number of bit per pixel @param isCompress: use RLE compression @param data: bitmap data """ def onSessionReady(self): """ @summary: Windows session is ready """ def onClose(self): """ @summary: Call when stack is close """ return MyObserver(controller) from twisted.internet import reactor reactor.connectTCP("XXX.XXX.XXX.XXX", 3389, MyRDPFactory()) reactor.run()
RDP服务器
from rdpy.protocol.rdp import rdp class MyRDPFactory(rdp.ServerFactory): def buildObserver(self, controller, addr): class MyObserver(rdp.RDPServerObserver): def onReady(self): """ @summary: Call when server is ready to send and receive messages """ def onKeyEventScancode(self, code, isPressed): """ @summary: Event call when a keyboard event is catch in scan code format @param code: scan code of key @param isPressed: True if key is down @see: rdp.RDPServerObserver.onKeyEventScancode """ def onKeyEventUnicode(self, code, isPressed): """ @summary: Event call when a keyboard event is catch in unicode format @param code: unicode of key @param isPressed: True if key is down @see: rdp.RDPServerObserver.onKeyEventUnicode """ def onPointerEvent(self, x, y, button, isPressed): """ @summary: Event call on mouse event @param x: x position @param y: y position @param button: 1, 2, 3, 4 or 5 button @param isPressed: True if mouse button is pressed @see: rdp.RDPServerObserver.onPointerEvent """ def onClose(self): """ @summary: Call when human client close connection @see: rdp.RDPServerObserver.onClose """ return MyObserver(controller) from twisted.internet import reactor reactor.listenTCP(3389, MyRDPFactory()) reactor.run()
VNC客户端
from rdpy.protocol.rfb import rfb class MyRFBFactory(rfb.ClientFactory): def clientConnectionLost(self, connector, reason): reactor.stop() def clientConnectionFailed(self, connector, reason): reactor.stop() def buildObserver(self, controller, addr): class MyObserver(rfb.RFBClientObserver): def onReady(self): """ @summary: Event when network stack is ready to receive or send event """ def onUpdate(self, width, height, x, y, pixelFormat, encoding, data): """ @summary: Implement RFBClientObserver interface @param width: width of new image @param height: height of new image @param x: x position of new image @param y: y position of new image @param pixelFormat: pixefFormat structure in rfb.message.PixelFormat @param encoding: encoding type rfb.message.Encoding @param data: image data in accordance with pixel format and encoding """ def onCutText(self, text): """ @summary: event when server send cut text event @param text: text received """ def onBell(self): """ @summary: event when server send biiip """ def onClose(self): """ @summary: Call when stack is close """ return MyObserver(controller) from twisted.internet import reactor reactor.connectTCP("XXX.XXX.XXX.XXX", 3389, MyRFBFactory()) reactor.run()
许可证协议
本项目的开发与发布遵循GPL-3.0开源许可证协议。
项目地址
RDPY:【GitHub传送门】