
Протокол удаленного рабочего стола в Twisted Python

Протокол удаленного рабочего стола на Twisted Python.
RDPY — это чистая реализация протокола Microsoft RDP (Remote Desktop Protocol) на Python (клиентская и серверная части). RDPY построен на основе событийно-ориентированного сетевого движка Twisted. RDPY поддерживает стандартный уровень безопасности RDP, RDP поверх SSL и аутентификацию NLA (через протокол аутентификации ntlmv2).
RDPY предоставляет следующие исполняемые файлы для RDP и VNC:
RDPY полностью реализован на Python, за исключением алгоритма декомпрессии растровых изображений, который реализован на C для повышения производительности.
Зависимости требуются только для исполняемых файлов на PyQt4:
Пример для систем на базе Debian:
sudo apt-get install python-qt4
Пример для OS X по установке PyQt с помощью Homebrew:
$ brew install qt sip pyqt
| x86 | x86_64 |
|---|---|
| PyQt4 | PyQt4 |
| PyWin32 | PyWin32 |
$ 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 — это простой RDP-клиент на Qt4.
$ rdpy-rdpclient.py [-u username] [-p password] [-d domain] [-r rss_ouput_file] [...] XXX.XXX.XXX.XXX[:3389]
Вы можете использовать rdpy-rdpclient в сценарии записи сеанса (Recorder Session Scenario), который применяется в rdpy-rdphoneypot.
rdpy-vncclient — это простой VNC-клиент на Qt4.
$ rdpy-vncclient.py [-p password] XXX.XXX.XXX.XXX[:5900]
rdpy-rdpscreenshot сохраняет экран входа в файл.
$ rdpy-rdpscreenshot.py [-w width] [-l height] [-o output_file_path] XXX.XXX.XXX.XXX[:3389]
rdpy-vncscreenshot сохраняет первое обновление экрана в файл.
$ rdpy-vncscreenshot.py [-p password] [-o output_file_path] XXX.XXX.XXX.XXX[:5900]
rdpy-rdpmitm — это RDP-прокси, который позволяет выполнять атаку «человек посередине» (Man In The Middle) на протокол RDP. Записывает сценарий сеанса (Record Session Scenario) в файл rss, который можно воспроизвести с помощью rdpy-rssplayer.
$ rdpy-rdpmitm.py -o output_dir [-l listen_port] [-k private_key_file_path] [-c certificate_file_path] [-r (для клиентов XP или Server 2003)] target_host[:target_port]
Выходной каталог используется для сохранения файла rss в следующем формате (YYYYMMDDHHMMSS_ip_index.rss). Файл закрытого ключа и файл сертификата — это стандартные криптографические файлы для SSL-соединений. Протокол RDP может согласовывать свой собственный уровень безопасности. Если один из этих параметров опущен, сервер использует стандартный RDP в качестве уровня безопасности.
rdpy-rdphoneypot — это RDP-ловушка (honeypot). Использует записанный сценарий сеанса (Recorded Session Scenario) для воспроизведения сценария через протокол RDP.
$ rdpy-rdphoneypot.py [-l listen_port] [-k private_key_file_path] [-c certificate_file_path] rss_file_path_1 ... rss_file_path_N
Файл закрытого ключа и файл сертификата — это стандартные криптографические файлы для SSL-соединений. Протокол RDP может согласовывать свой собственный уровень безопасности. Если один из этих параметров опущен, сервер использует стандартный RDP в качестве уровня безопасности. Вы можете указать несколько файлов, чтобы соответствовать более распространенным размерам экрана.
rdpy-rssplayer используется для воспроизведения файлов сценариев записи сеанса (rss), созданных исполняемыми файлами rdpy-rdpmitm или rdpy-rdpclient.
$ rdpy-rssplayer.py rss_file_path
RDPY также может использоваться как виджет Qt через класс rdpy.ui.qt4.QRemoteDesktop. Его можно встроить в ваше собственное приложение Qt. В вашем приложении необходимо использовать qt4reactor для совместной работы Twisted и Qt. Более подробную информацию см. в исходных кодах rdpy-rdpclient.
Вкратце, RDPY можно использовать как библиотеку протоколов с движком Twisted.
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()
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
"""