Unresolved Shell Code

Source status

imspr/.ini.php declares reusable command-execution, streaming, inbound bind-listener, and outbound back-connect helpers. The definitions are present, but no separate caller, registration, route, dispatch, or lifecycle boundary was established for either network helper. Their reachability and runtime success are therefore unresolved.

[!WARNING] Treat these as source-defined capabilities, not as evidence of an exposed or reachable service. Both network paths can connect socket data directly to an interactive cmd.exe or /bin/sh -i process, and the inspected code establishes no sandbox, chroot, privilege drop, or other process-isolation boundary.

Ordered command execution

is_callable_shell_func returns false when a named function is unavailable or listed in PHP's configured disable_functions; otherwise it returns true. execute_command_with_fallback($command) then evaluates these backends in order:

1. proc_open | Passes the supplied command to proc_open with stdin, stdout, and stderr pipes. The working directory is $_SESSION['terminal_cwd'] when set, otherwise getcwd(). When a process resource is obtained, stdout and stderr are concatenated and returned.
2. popen | If the proc_open path does not return, appends 2>&1, reads the popen handle in 8192-byte chunks, and returns the collected output when the handle is valid.
3. shell_exec | Passes the redirected command to shell_exec and returns the result when it is not null.
4. system | Passes the redirected command to system, captures buffered output, and returns that output without exposing a separate status result.
5. passthru | Passes the redirected command to passthru, captures buffered output, and returns that output.
6. exec | Passes the redirected command to exec, joins the collected output entries with newline characters, and returns the resulting string.
7. Terminal failure | If no backend returns earlier, returns "[Error] All command execution backends (proc_open, popen, shell_exec, system, passthru, exec) are disabled or failed."

stream_command($command) configures a plain-text response and first attempts proc_open using $_SESSION['terminal_cwd']. When that process is created, it records the process PID in $_SESSION['running_process_pid'] when available and streams nonempty stdout and stderr while the process reports as running. Its fallback is popen; if that path does not return, it emits the result of execute_command_with_fallback($command).

Archive command handoffs

Within the same file, archive helpers construct commands before passing them to execute_command_with_fallback:

  • tar -xf uses escapeshellarg for both the source path and the destination path.
  • unrar x -o+ uses escapeshellarg for the source path and the destination directory.
  • 7z x uses escapeshellarg for the source path and destination option, followed by -y.

These quoting steps apply to the shown archive command construction; they do not establish a general validation boundary for every possible $command value.

Inbound bind-listener flow

The source-defined network_start_port_bind path is:

flowchart TD
    b1["network_start_port_bind($port, $password)"] --> b2["stream_socket_server tcp://0.0.0.0:$port"]
    b2 --> b3["stream_socket_accept 60s"]
    b3 --> b4["Password input"]
    b4 --> b5{"$recv_pass === $password"}
    b5 -- "equal" --> b6["proc_open cmd.exe or /bin/sh -i"]
    b6 --> b7["Client and shell pipes"]
    b7 --> b8["Bidirectional relay"]
    b5 -- "not equal" --> b9["Access denied"]
    b3 -- "no client" --> b10["Listener closes"]

The listener constructs a wildcard 0.0.0.0 address with the caller-supplied $port. If the server resource is created, it waits up to 60 seconds for one client. The client receives a password prompt, and input is read until a newline or carriage return or until the 10-second password-input timeout expires. The received input is then trimmed with trim($recv_pass), and the shell branch requires an exact equality check against $password.

On that equality branch, the definition selects cmd.exe on Windows or /bin/sh -i otherwise, opens the process with stdin, stdout, and stderr pipes, and relays client input to shell stdin. Nonempty shell stdout is written to the client; nonempty stderr is written with a STDERR: prefix. A missing or failed proc_open path produces a source-defined failure message instead of an established shell session.

The definition returns an output buffer for bind errors, password timeouts, client disconnects, process failures, and listener closure. Failed authentication also places an escaped representation of the received password in that buffer. These messages are source-defined outcomes, not evidence that the listener was invoked or that a shell process successfully ran.

Outbound back-connect flow

The separate network_start_back_connect definition uses an outbound socket and has no password comparison in its shell setup:

flowchart TD
    c1["network_start_back_connect($ip, $port)"] --> c2["fsockopen caller-supplied $ip and $port"]
    c2 --> c3["Outbound socket"]
    c3 --> c4["proc_open cmd.exe or /bin/sh -i"]
    c4 --> c5["Socket and shell pipes"]
    c5 --> c6["Bidirectional relay"]
    c2 -- "connection failure" --> c7["Error buffer returned"]

The connection attempt uses a 30-second timeout. After fsockopen returns a socket, the source-defined flow selects the platform shell and attempts proc_open when that function is available. The relay begins only when proc_open returns an is_resource($process); if the call does not return a process resource, the helper records a proc_open failure, and if the function is unavailable, it records the unavailable message. In either case it closes the socket and returns the output buffer. When the resource guard succeeds, the flow writes socket input to shell stdin and sends nonempty stdout and stderr back over the socket, prefixing stderr with STDERR: . It returns an error buffer when the connection fails and records process or socket termination messages in its output buffer.

Assessment boundary

[!CAUTION] The bind helper uses an unchecked caller-supplied port and provides no established client-IP allowlist, port-range validation, attempt throttling, or lockout. The back-connect helper passes caller-supplied $ip and $port directly to fsockopen without an established peer-authentication or network-allowlist boundary; no source-level connection throttling or lockout is established for this helper. Neither path establishes a fallback-secret provenance or process-isolation control.

No successful or failed runtime execution record was found in the inspected source. Confirming whether either helper is reachable requires evidence outside these function definitions.

Updated