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
dStart as serverhShows the usagelShows the licensevShows the versionaAuthentication token
-- exitExits the client-- haltHalts 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
readlinesupport.
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.
SERVERThe command line optiondTOKENThe command line argumentaHOSTThe command line argumentHOSTPORTThe command line argumentPORTFILEThe stated file name and pathHOMEThe stated user home directoryBUILDThe compiled build informationDEBUGThe compiled debug flagVERSIONThe 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.
