omniserver


Nameomniserver JSON
Version 1.1.0 PyPI version JSON
download
home_pagehttps://github.com/LLCZ00/Omniserver
SummaryModule for network testing and prototyping
upload_time2023-01-23 01:59:42
maintainer
docs_urlNone
authorLLCZ00
requires_python>=3.8
licenseApache 2.0
keywords malware analysis networking
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Omniserver
![PyPI](https://img.shields.io/pypi/v/omniserver)
### _Connections for all occasions_
*Omniserver* is a Python module designed for quickly creating highly customizable server/client objects, and to provide maximum flexibility using as little boilerplate code as possible. Common uses include prototyping/replicating malicious network communication methods, intercepting/controlling the traffic of "Command and Control"-type malware, or simply being a shortcut for general networking activities.

At its core, *omniserver* is essentially just a wrapper around Python's built-in *socketserver* module (which itself is just a wrapper around *socket*). The goal of *omniserver* is to extend *socketserver* by providing a wider variety of functions, and perhaps a simpler API. All of *omniserver*'s RequestHandler and Server objects are compatible with *socketserver*, and can basically be used in the same way as described in their documentation.
## Basic Usage
See [*documentation*](https://omniserver.readthedocs.io/en/latest/)

The *omniserver* module can be used to initiate and control client and server objects. Current varieties include TCP, UDP, HTTP, and DNS (TCP or UDP). TLS/SSL can also be enabled on any TCP-based client or server object.
### Clients
Connections can be established with remote servers using *client* objects. After succesfully connecting to a server using the *connect()* or *beacon()* methods, TCP and UDP communications are primarily controlled using the *send()* and *recv()* methods. Additionally, DNS and HTTP clients provide the *query()* and *get()* methods (respectively), which handle both the sending and recieving of their more specialized data structures.
```py
import omniserver as omni

with omni.udp_client(("192.168.1.40", 7896)) as udp_client: # 'with' keyword calls connect() and close()
	udp_client.send("Akon")
	udp_client.recv()
	udp_client.send("All on the floor")
	
tcp_client = omni.tcp_client(("192.168.1.40", 6547))
if tcp_client.beacon(freq=3, tries=5): # Try to connect 5 times, 3 seconds apart, before quiting 
	tcp_client.send("whoami")
	tcp_client.recv()
	tcp_client.send("dir")
	tcp_client.recv()
	tcp_client.close() # Good practice, but not necessarily required
	
ip = omni.dns_client(("10.10.10.100", 53)).query("fraggle-rock.com") # query() returns the resolved IP as a string
with omni.http_client((ip, 8181)) as http_client:
    http_client.get("/test.txt")
```
### Servers
Connections from remote clients can be accepted on a listening socket using *server* objects. They are threaded by default, and can be run all at once or indivdually. All *server* objects provide the same methods as their *socketserver* counterparts, with the addition of *start()*, *wait()*, and *stop()* methods. *Omniserver* also provides the *start_all()*, *wait_all()*, and *stop_all()* functions, which affect all the currently initialized servers objects at once. Server processes/threads can be exited with CTRL-C.
```py
omni.tcp_server(7896)
omni.udp_server(3214)
omni.http_server(8181) # Works basically the same as http.server
omni.dns_server(default_ip="192.168.1.40") # Will respond to all IPv4 queries with default IP
omni.servers.start_all()

tcp = omni.tcp_server.start() # Non-blocking
omni.udp_server().serve_forever() # Random high port, blocking
tcp.stop() # Shutdown tcp server after udp_server exits
```
### Customizing Request Handler Classes
*Client* and *server* handler classes can be subclassed the same way as described in *socketserver*'s documentation. All data which flows through *omniserver* objects is passed through the *incoming()* and *outgoing()* methods, so overriding them provides a convenient way to deal with encypted communications, as shown in the following example:
```py
import dynabyte

class C2Handler(omni.TCPHandler):
    def incoming(self, data): 
        return Array(data).XOR("Secret_key").ADD(0xA1).ROR(5) # The encryption scheme, backwords
        
    def outgoing(self, resp): # Encode response
        return bytes(Array(resp).ROL(5).SUB(0xA1).XOR("Secret_key")) # ROL/SUB/XOR'ing all sent data
        
    def response(self, data):
        if data == "name":
            return "Don Cheadle"
        elif data == "real name":
            return "Tiger Woods"
        else:
            return "default"

class C2Client(omni.TCPClient):
    def incoming(self, data): # incoming() and outgoing() are called within recv() and send(), respectively
        return Array(data).XOR("Secret_key").ADD(0xA1).ROR(5)

    def outgoing(self, data): # Called whenever send() is
        return bytes(Array(data).ROL(5).SUB(0xA1).XOR("Secret_key"))
		
# Start server
omni.tcp_server(6547, RequestHandler=C2Handler).start()

with omni.tcp_client(("10.10.10.100", 6547), Handler=C2Client) as tcp:
    tcp.send("name")
    tcp.recv()
    tcp.send("real name")
    tcp.recv()
    tcp.send("didgeridoo")
    tcp.recv()
```
Request handler classes operate basically the same way as their socketserver counterparts, handle(), setup(), finish() etc. can be overriden as you see fit.
### TLS/SSL
TCP-based servers and clients are TLS/SSL compatible. *Omniserver* provides functions for generating SSL certs, but they are currently only available when used on Linux.
```py
cert, key = omni.certs.create_cert_key(CN="booberry.edu") # Returns absolute path to CA cert and private key
context = omni.certs.create_server_context(certfile=cert, keyfile=key)
omni.tcp_server(6547, sslcontext=context).start().wait()
```
On the client side, you'll need the CA of the server you plan to connect to, or cert checking can simply be disabled.
```py
# No cert required
with omni.tcp_client(("10.10.10.50", 6547)) as client:
    client.enable_ssl(cert_required=False)
    client.send("Secret TLS message (didn't check the cert)")
    client.recv()
	
# Cert required
client = omni.tcp_client(("10.10.10.50", 6547), hostname="booberry.edu")
client.enable_ssl(omni.certs.create_client_context(ca_cert="./cert.crt"))
if client.connect():
    client.send("Secret TLS message")
    client.recv()
    client.close()
```
## Installation
Install from PyPI
```
pip install omniserver
```
## Known Issues & TODO
- Currently cannot easily create SSL certificates on Windows
	- Generating the cert/key with OpenSSL on Linux and moving them over works, if you truly need the TLS/SSL server on Windows
- Add function for signing certificates with CA
- HTTP server and client arn't very fleshed out, it's kinda just easier to use requests
- DNS over TCP is in there, but I haven't tested it extensively 
- TCP servers sometimes do a weird retransmission of FIN, ACK packet
- **kwargs in client.enable_ssl(), for creating context
- Finish documentation


            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/LLCZ00/Omniserver",
    "name": "omniserver",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": "",
    "keywords": "malware analysis networking",
    "author": "LLCZ00",
    "author_email": "",
    "download_url": "https://files.pythonhosted.org/packages/65/e7/177679d2505da33febbbcc295be38b3eeb33dfd294afa93f015cf679a243/omniserver-1.1.0.tar.gz",
    "platform": null,
    "description": "# Omniserver\r\n![PyPI](https://img.shields.io/pypi/v/omniserver)\r\n### _Connections for all occasions_\r\n*Omniserver* is a Python module designed for quickly creating highly customizable server/client objects, and to provide maximum flexibility using as little boilerplate code as possible. Common uses include prototyping/replicating malicious network communication methods, intercepting/controlling the traffic of \"Command and Control\"-type malware, or simply being a shortcut for general networking activities.\r\n\r\nAt its core, *omniserver* is essentially just a wrapper around Python's built-in *socketserver* module (which itself is just a wrapper around *socket*). The goal of *omniserver* is to extend *socketserver* by providing a wider variety of functions, and perhaps a simpler API. All of *omniserver*'s RequestHandler and Server objects are compatible with *socketserver*, and can basically be used in the same way as described in their documentation.\r\n## Basic Usage\r\nSee [*documentation*](https://omniserver.readthedocs.io/en/latest/)\r\n\r\nThe *omniserver* module can be used to initiate and control client and server objects. Current varieties include TCP, UDP, HTTP, and DNS (TCP or UDP). TLS/SSL can also be enabled on any TCP-based client or server object.\r\n### Clients\r\nConnections can be established with remote servers using *client* objects. After succesfully connecting to a server using the *connect()* or *beacon()* methods, TCP and UDP communications are primarily controlled using the *send()* and *recv()* methods. Additionally, DNS and HTTP clients provide the *query()* and *get()* methods (respectively), which handle both the sending and recieving of their more specialized data structures.\r\n```py\r\nimport omniserver as omni\r\n\r\nwith omni.udp_client((\"192.168.1.40\", 7896)) as udp_client: # 'with' keyword calls connect() and close()\r\n\tudp_client.send(\"Akon\")\r\n\tudp_client.recv()\r\n\tudp_client.send(\"All on the floor\")\r\n\t\r\ntcp_client = omni.tcp_client((\"192.168.1.40\", 6547))\r\nif tcp_client.beacon(freq=3, tries=5): # Try to connect 5 times, 3 seconds apart, before quiting \r\n\ttcp_client.send(\"whoami\")\r\n\ttcp_client.recv()\r\n\ttcp_client.send(\"dir\")\r\n\ttcp_client.recv()\r\n\ttcp_client.close() # Good practice, but not necessarily required\r\n\t\r\nip = omni.dns_client((\"10.10.10.100\", 53)).query(\"fraggle-rock.com\") # query() returns the resolved IP as a string\r\nwith omni.http_client((ip, 8181)) as http_client:\r\n    http_client.get(\"/test.txt\")\r\n```\r\n### Servers\r\nConnections from remote clients can be accepted on a listening socket using *server* objects. They are threaded by default, and can be run all at once or indivdually. All *server* objects provide the same methods as their *socketserver* counterparts, with the addition of *start()*, *wait()*, and *stop()* methods. *Omniserver* also provides the *start_all()*, *wait_all()*, and *stop_all()* functions, which affect all the currently initialized servers objects at once. Server processes/threads can be exited with CTRL-C.\r\n```py\r\nomni.tcp_server(7896)\r\nomni.udp_server(3214)\r\nomni.http_server(8181) # Works basically the same as http.server\r\nomni.dns_server(default_ip=\"192.168.1.40\") # Will respond to all IPv4 queries with default IP\r\nomni.servers.start_all()\r\n\r\ntcp = omni.tcp_server.start() # Non-blocking\r\nomni.udp_server().serve_forever() # Random high port, blocking\r\ntcp.stop() # Shutdown tcp server after udp_server exits\r\n```\r\n### Customizing Request Handler Classes\r\n*Client* and *server* handler classes can be subclassed the same way as described in *socketserver*'s documentation. All data which flows through *omniserver* objects is passed through the *incoming()* and *outgoing()* methods, so overriding them provides a convenient way to deal with encypted communications, as shown in the following example:\r\n```py\r\nimport dynabyte\r\n\r\nclass C2Handler(omni.TCPHandler):\r\n    def incoming(self, data): \r\n        return Array(data).XOR(\"Secret_key\").ADD(0xA1).ROR(5) # The encryption scheme, backwords\r\n        \r\n    def outgoing(self, resp): # Encode response\r\n        return bytes(Array(resp).ROL(5).SUB(0xA1).XOR(\"Secret_key\")) # ROL/SUB/XOR'ing all sent data\r\n        \r\n    def response(self, data):\r\n        if data == \"name\":\r\n            return \"Don Cheadle\"\r\n        elif data == \"real name\":\r\n            return \"Tiger Woods\"\r\n        else:\r\n            return \"default\"\r\n\r\nclass C2Client(omni.TCPClient):\r\n    def incoming(self, data): # incoming() and outgoing() are called within recv() and send(), respectively\r\n        return Array(data).XOR(\"Secret_key\").ADD(0xA1).ROR(5)\r\n\r\n    def outgoing(self, data): # Called whenever send() is\r\n        return bytes(Array(data).ROL(5).SUB(0xA1).XOR(\"Secret_key\"))\r\n\t\t\r\n# Start server\r\nomni.tcp_server(6547, RequestHandler=C2Handler).start()\r\n\r\nwith omni.tcp_client((\"10.10.10.100\", 6547), Handler=C2Client) as tcp:\r\n    tcp.send(\"name\")\r\n    tcp.recv()\r\n    tcp.send(\"real name\")\r\n    tcp.recv()\r\n    tcp.send(\"didgeridoo\")\r\n    tcp.recv()\r\n```\r\nRequest handler classes operate basically the same way as their socketserver counterparts, handle(), setup(), finish() etc. can be overriden as you see fit.\r\n### TLS/SSL\r\nTCP-based servers and clients are TLS/SSL compatible. *Omniserver* provides functions for generating SSL certs, but they are currently only available when used on Linux.\r\n```py\r\ncert, key = omni.certs.create_cert_key(CN=\"booberry.edu\") # Returns absolute path to CA cert and private key\r\ncontext = omni.certs.create_server_context(certfile=cert, keyfile=key)\r\nomni.tcp_server(6547, sslcontext=context).start().wait()\r\n```\r\nOn the client side, you'll need the CA of the server you plan to connect to, or cert checking can simply be disabled.\r\n```py\r\n# No cert required\r\nwith omni.tcp_client((\"10.10.10.50\", 6547)) as client:\r\n    client.enable_ssl(cert_required=False)\r\n    client.send(\"Secret TLS message (didn't check the cert)\")\r\n    client.recv()\r\n\t\r\n# Cert required\r\nclient = omni.tcp_client((\"10.10.10.50\", 6547), hostname=\"booberry.edu\")\r\nclient.enable_ssl(omni.certs.create_client_context(ca_cert=\"./cert.crt\"))\r\nif client.connect():\r\n    client.send(\"Secret TLS message\")\r\n    client.recv()\r\n    client.close()\r\n```\r\n## Installation\r\nInstall from PyPI\r\n```\r\npip install omniserver\r\n```\r\n## Known Issues & TODO\r\n- Currently cannot easily create SSL certificates on Windows\r\n\t- Generating the cert/key with OpenSSL on Linux and moving them over works, if you truly need the TLS/SSL server on Windows\r\n- Add function for signing certificates with CA\r\n- HTTP server and client arn't very fleshed out, it's kinda just easier to use requests\r\n- DNS over TCP is in there, but I haven't tested it extensively \r\n- TCP servers sometimes do a weird retransmission of FIN, ACK packet\r\n- **kwargs in client.enable_ssl(), for creating context\r\n- Finish documentation\r\n\r\n",
    "bugtrack_url": null,
    "license": "Apache 2.0",
    "summary": "Module for network testing and prototyping",
    "version": "1.1.0",
    "split_keywords": [
        "malware",
        "analysis",
        "networking"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "5e1ec8ed894cdece04c0774d00203a8a71f9418703819cb1cd1fb831a92da1e4",
                "md5": "5d2fcef0eb7b1a7f8f98762fae057189",
                "sha256": "7f5d1cb2853ae9b3593597028790c34cea075dcf283dac1985f035d05ec8a6f3"
            },
            "downloads": -1,
            "filename": "omniserver-1.1.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "5d2fcef0eb7b1a7f8f98762fae057189",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 22964,
            "upload_time": "2023-01-23T01:59:40",
            "upload_time_iso_8601": "2023-01-23T01:59:40.673577Z",
            "url": "https://files.pythonhosted.org/packages/5e/1e/c8ed894cdece04c0774d00203a8a71f9418703819cb1cd1fb831a92da1e4/omniserver-1.1.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "65e7177679d2505da33febbbcc295be38b3eeb33dfd294afa93f015cf679a243",
                "md5": "8ea9f826eaa384c222a3ae9d1195386f",
                "sha256": "45844da29d0a50f480803cf24e90718fa203876bd0405d27ce3a034dcf13f2df"
            },
            "downloads": -1,
            "filename": "omniserver-1.1.0.tar.gz",
            "has_sig": false,
            "md5_digest": "8ea9f826eaa384c222a3ae9d1195386f",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 22333,
            "upload_time": "2023-01-23T01:59:42",
            "upload_time_iso_8601": "2023-01-23T01:59:42.512046Z",
            "url": "https://files.pythonhosted.org/packages/65/e7/177679d2505da33febbbcc295be38b3eeb33dfd294afa93f015cf679a243/omniserver-1.1.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-01-23 01:59:42",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "github_user": "LLCZ00",
    "github_project": "Omniserver",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "omniserver"
}
        
Elapsed time: 0.03371s