Skip to main content

Omniserver

PyPI

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

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.

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.

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:

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.

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.

# 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

Metadata

Release files for omniserver 1.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for omniserver 1.1.0
File Size Uploaded Provenance
omniserver-1.1.0.tar.gz 22.3 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for omniserver 1.1.0
File Interpreter ABI Platform
omniserver-1.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 45.3 kB

Release files / omniserver-1.1.0.tar.gz

Download URL omniserver-1.1.0.tar.gz
Size 22.3 kB
Tags Source
SHA-256 checksum
How to use checksums
45844da29d0a50f480803cf24e90718fa203876bd0405d27ce3a034dcf13f2df
BLAKE2b-256 checksum
How to use checksums
65e7177679d2505da33febbbcc295be38b3eeb33dfd294afa93f015cf679a243
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.11.1

Release files / omniserver-1.1.0-py3-none-any.whl

Download URL omniserver-1.1.0-py3-none-any.whl
Size 23.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7f5d1cb2853ae9b3593597028790c34cea075dcf283dac1985f035d05ec8a6f3
BLAKE2b-256 checksum
How to use checksums
5e1ec8ed894cdece04c0774d00203a8a71f9418703819cb1cd1fb831a92da1e4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.11.1

Security for omniserver 1.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

1.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page