Metadata-Version: 2.5
Name: hexshellonrepr
Version: 0.0.3
Summary: Object that starts hex encoded shell from repr function.
Project-URL: Homepage, https://github.com/sudo-gera/hexshellonrepr
Project-URL: Issues, https://github.com/sudo-gera/hexshellonrepr/issues
Author: Gera
License-Expression: MIT
License-File: LICENSE
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Description-Content-Type: text/markdown

# hexshellonrepr

Interactive shell for executing hex-encoded commands via object `repr()`.

A Python object whose `repr()` starts an interactive shell that accepts **hex-encoded shell commands** from user.

## Why?

If your keyboard is broken and punctuation characters are not available, hex can still be used to enter shell commands.

The idea is simple: **enter shell commands without directly typing shell punctuation.**

Hexadecimal input consists only of digits `0-9` and letters `a-f`, so it can be useful in environments where punctuation characters are difficult or impossible to enter.

For example:

```text
6c73202d6c
```

decodes to:

```text
ls -l
```

This is primarily a small Python experiment and a demonstration of how `__repr__()` interacts with the interactive interpreter.

## Usage:

Note: during installation process we do not enter any punctuation characters!

1. Install the package:

```console
$ pip install hexshellonrepr
```

2. Start Python interactive shell:

```console
$ python
>>>
```

3. type into Python interactive shell:

```python
>>> from hexshellonrepr import hexshellonrepr
>>> hexshellonrepr
(hex)$
```

4. You can now enter commands as hexadecimal strings:

```console
(hex)$ 6c73202d6c207c2068656164
Executing 'ls -l | head'? (y/n): y
/home/user
(hex)$
```

Blob `6c73202d6c207c2068656164` is hex-encoded command `ls -l | head`.

To stop the shell, interrupt the Python process, for example with `Ctrl-C`.

## How does it work?

`hexshellonrepr` is an instance of `HexShellOnRepr`.

When the Python REPL evaluates the expression `hexshellonrepr`, it displays the resulting object's representation.

Displaying that representation invokes `hexshellonrepr.__repr__()`, which starts the interactive shell.

This implementation deliberately uses `__repr__()` as the entry point for the shell:

1. Reads a line of hexadecimal input.
2. Decodes it with `bytes.fromhex()`.
3. Decodes the resulting bytes as `UTF-8`.
4. Displays the decoded command.
5. Asks for explicit confirmation.
6. Executes the command with `subprocess.call(command, shell=True)`.
7. Prints the command's return code.
8. Repeats until the surrounding Python process is interrupted.

In other words, simply evaluating:

```python
hexshellonrepr
```

starts the shell because evaluating the expression causes Python to call `__repr__()`.

This package intentionally gives `__repr__()` a side effect. This is unusual and generally discouraged in production Python code; it is the central feature of this project.

## Why `.__repr__()`? why not adding some method, like `.shell()`?

To call method you need to type some parentheses and dots.

To call `.__repr__()` you just need to mention this object.

## Safety

**This package executes arbitrary shell commands.**

Every decoded command is displayed and requires an explicit `y` confirmation before execution. This provides a useful safeguard against accidentally executing an unknown hex string.

The confirmation prompt is a convenience and an accidental-execution safeguard, not a security boundary.

A confirmed command can do anything the current operating-system user is permitted to do, including:

* read or modify files;
* start other programs;
* make network connections;
* delete data;
* change system configuration.

For example, hexadecimal encoding does **not** make a command safe.

For example:

```text
6563686f202428726d20e280937266202f746d702f736f6d657468696e6729
```

is just an encoded shell command `echo $(rm –rf /tmp/something)`.

It might look like harmless command that would `echo` something nice.

But actually it uses shell injection `$()` to start subshell.

The subshell tries to wipe your system!

*Do not paste untrusted hexadecimal strings into the shell without decoding and inspecting them first!*

The package itself does not download payloads or establish network connections. Commands entered by the user can do so.

Hex encoding is only an input format. It provides no security or sandboxing.

## Notes

* Invalid hexadecimal input is rejected without executing anything.
* Commands that are not confirmed with `y` are not executed.
* Hex-encoding does not mean sanitization. Shell injections are possible.

## Punctuation-free installation

One motivation for this project is environments where punctuation cannot easily be entered.

The exact installation process depends on the Python installation and operating system.

Some Linux distributions prevent `pip` from installing packages into the system Python environment. Usually it happens if your default `pip` package is of `python3.12` or newer. In those environments you may need a virtual environment or another installation mechanism, which can require punctuation characters during setup.

#### If your default `pip` is blocked

###### If you have already installed this library you can use it without entering punctuation.

###### If you have shell where virtual environment is already activated, you can type `pip` commands from *Usage* block.

###### If you have already created virtual env but it is not activated, try these commands:

Assuming you have virtual environment at `path/to/venv` and your activate script is at `path/to/venv/bin/activate`.

1. Change to the `path/to/venv/bin`

```
cd path
cd to
cd venv
cd bin
```

We are using multiple `cd` commands because typing `path/to` requires entering `/`.

You might need to perform `cd` beforehand, because running `cd ..` might not be possible. This command would change directory to your home directory.

2. activete virtual environment:

```
source activate
```

3. Perform steps from *Usage* block as usual.

## supported versions:

#### `python<3.12`

Fully compatible.

#### `python>=3.12`

Partially compatible.

Python 3.12 may prevent installing packages directly into the system Python environment on some Linux distributions. In those environments, you may need to use a virtual environment or an installation option that explicitly allows system-wide package installation. Both of these ways require punctuation characters at some point.

You can actually use library if you are lucky to have shell with already activated venv or if you have installed this library beforehand.

## Programmatic API

The package also exposes the class:

```python
from hexshellonrepr import HexShellOnRepr

shell = HexShellOnRepr()
```

The primary intended interface is the `repr()` behavior:

```python
repr(shell)
```

which starts the interactive shell.

## Limitations

### Shell compatibility

Commands are executed through:

```python
subprocess.call(command, shell=True)
```

so behavior depends on the shell and operating system available to Python.

Shell syntax is therefore not guaranteed to behave identically across platforms.

### Encoding

Input is interpreted as hexadecimal bytes and then decoded as UTF-8.

Invalid hexadecimal input or invalid UTF-8 is rejected without executing a command.

### Python versions

The package supports Python 3.

Python 3.12+ environments may impose restrictions on installing packages into the system interpreter, particularly on some Linux distributions. Use a virtual environment or another appropriate installation method when necessary.

## Development

Clone the repository and install it in editable mode with development dependencies:

```console
pip install -e "."
```

The project uses [Hatch](https://hatch.pypa.io/) as its build backend.

## License

MIT License. See `LICENSE`.
