Palantir is a Lua scriptable, portable, tiny reverse shell, using a human readable protocol written in C and Lua.
$ palantir [-dhlv] [-a TOKEN] HOST PORT
d
Start as serverh
Shows the usagel
Shows the licensev
Shows the versiona
Authentication token
-- exit
Exits the client-- halt
Halts the server
All input will be evaluated and execute as Lua commands. The internal function
os.shell
will execute system commands by using the users default shell and
return the results where strerr
will be mapped to stdout
.
- Ctrl+n inserts a new line
- Ctrl+x termintates the shell
- Tab autocompletes keywords, functions, globals and commands
Only available if compiled with
readline
support.
The user profile ~/.profile.lua
will be loaded at the start. The macro
$ <command>
is defined as a shortcut for os.shell()
calls by default.
Add-on packages will be searched with-in the default Lua package.path
.
New global constants and functions will be defined which contain all shell specific extensions.
SERVER
The command line optiond
TOKEN
The command line argumenta
HOST
The command line argumentHOST
PORT
The command line argumentPORT
FILE
The stated file name and pathHOME
The stated user home directoryBUILD
The compiled build informationDEBUG
The compiled debug flagVERSION
The compiled version number
The network functions share one socket and are not meant to be re-opened:
net.server(host, port)
net.client(host, port)
net.connect(host, port)
net.listen(host, port)
net.accept()
net.recv()
net.send(command, param)
The operating system functions will extend the Lua build-in os
library:
os.path(path)
os.prompt(prompt)
os.shell(command)
os.sleep(milliseconds)
The default shell functionality can be extended by creating custom event callbacks. There are three different event sources:
server_<command>(param)
Called when the server receives a<command>
client_<command>(param)
Called when the client receives a<command>
client_prompt(line)
Called when the client processes a prompt
All callbacks must return a boolean
. In case true
is returned, all further
processing will be prevented.
The <command>
names will be converted to lowercase.
Here is an example on how to implement a simple Echo Server:
function client_prompt(line)
net.send('ECHO', line)
return true
end
function server_echo(param)
net.send('ECHO', param)
return true
end
function client_echo(param)
io.write(param .. '\n')
return true
end
The Palantir protocol consists of two layers:
- Network Layer (transportation handled by
C
) - Command Layer (interpretation handled by
Lua
)
A network frame is build according to the following format:
CHECKSUM (4 bytes) | SIZE (4 bytes) | DATA (n bytes)
The CHECKSUM
is a bitwise CRC-32 over the DATA
field only.
If an authentication TOKEN
is provided, the network frames checksum will be
pre-feed with the CRC-32 of the token before calculation.
A command is build according to the following format:
COMMAND (4 bytes) | BLANK (1 byte) | PARAM (n bytes)
Each command consists of a 5
byte command header followed by 0
to n
bytes of param
. A command header will end with a single blank
character
for better readability.
If an unknown command is received, no error will be raised, instead it will be ignored by the client and server.
HELO <user>@<host>:<path>
TEXT <text>
EXEC <command>
PATH <path>
HALT
Server: HELO root@localhost:/
Client: PATH var
Server: HELO root@localhost:/var
Client: EXEC return os.shell('echo hello')
Server: TEXT hello
Server: HELO root@localhost:/var
Client: HALT
$ cmake [-DDEBUG=ON] . && make
Required minimum versions:
Suppored minimum versions:
Licensed under the terms of the MIT License.