TOOL^:Tools

rlwrap, sshpass, ntpdate & faketime

Improve raw-shell editing, automate SSH password prompts, and diagnose Kerberos time skew without confusing timezone, ticket validity or remote terminal support.

beginnerupdated 2026-10-12rlwrap · sshpass · ntpdate · faketime

rlwrap, sshpass, ntpdate & faketime

Four tiny tools that aren’t the exploit but save you constant friction in AD and Linux boxes.

rlwrap — usable raw shells

Wrap a netcat listener so you get readline: arrow keys, command history, line editing in an otherwise dumb reverse shell.

# the standard listener for a Windows reverse shell
rlwrap -cAr nc -lnvp 443

# sudo when binding a low port
sudo rlwrap -cAr nc -lvnp 445
FlagMeaning
-ccomplete filenames (tab-completion)
-Aforce ANSI colour handling
-rput all seen words in the completion list

[!tip] rlwrap -cAr nc -lnvp <port> is the muscle-memory line Especially for Windows powershell/cmd reverse shells where you can’t easily upgrade the TTY. For Linux targets you’ll usually still do the python3 -c 'pty.spawn' + stty raw -echo; fg upgrade on top. See Foothold: shells & payloads.

sshpass — non-interactive SSH password

SSH/scp without the interactive password prompt — for scripting, loops, or when a password came from loot.

# ssh with an inline password
sshpass -p 'Passw0rd!' ssh user@10.10.10.5

# from a file (safer; keeps it out of ps/history)
sshpass -f pass.txt ssh user@10.10.10.5

# scp a tool over
sshpass -p 'Passw0rd!' scp ./GodPotato.exe user@10.10.10.5:/programdata/gp.exe

# trust a new lab host key on first connect; changed keys still fail
sshpass -p 'Passw0rd!' ssh -o StrictHostKeyChecking=accept-new user@10.10.10.5
FlagMeaning
-p PASSpassword inline (visible in ps — least safe)
-f FILEread password from a file
-eread password from $SSHPASS env var
-d Nread from file descriptor N

[!warning] -p leaks into ps/shell history On a shared/monitored box prefer -f file or -e (SSHPASS=... sshpass -e ssh ...). sshpass also only works for password auth — it does not unlock a private-key passphrase or implement a general multi-factor login flow.

ntpdate / faketime — beat Kerberos clock skew

Kerberos rejects tickets when your clock differs from the DC by more than ~5 min (KRB_AP_ERR_SKEW). Fix it before any -k / ticket operation.

# sync your clock to the DC (simplest; needs root)
sudo ntpdate dc.domain.htb
sudo ntpdate 10.10.10.5

# can't/won't change system time? run just one command at the DC's time:
# Example only: use a measured offset, not a guessed timezone difference
faketime -f '+300s' getST.py 'domain.htb/user' -spn cifs/dc01.domain.htb

[!tip] When to reach for which ntpdate is the default — one command, done. Use faketime when you can’t change system time (shared VM, breaks other tooling) and only need one Kerberos command to run at the DC’s clock. Rare but handy when the DC’s time is deliberately offset.

[!warning] ntpdate side effects ntpdate yanks your whole system clock to the DC’s — fine on a throwaway attack VM, annoying if you juggle several targets with different offsets (re-sync per box). First inspect your active time service. Enabling NTP only helps when the configured server provides the required time; it does not automatically synchronize against the target DC.

Check what each helper actually changes

# Display UTC and query the DC without changing the machine clock
date -u
ntpdate -q dc01.domain.htb

# Keep rlwrap's shell-command history out of the default persistent file
rlwrap -H /dev/null -cAr nc -lvnp 4444

# Avoid an inline SSH password; protect the password file locally
chmod 600 pass.txt
sshpass -f pass.txt ssh -o StrictHostKeyChecking=accept-new user@10.10.10.5

rlwrap provides local editing, not a remote PTY, job control or terminal resizing. A password file avoids exposing the password as a command argument, but the file remains a secret. accept-new is first-use trust; verify the fingerprint when you have an authoritative one.

Kerberos compares time instants, not displayed timezone names. Measure skew, inspect the ticket’s start/end times with klist, and check DNS/SPNs before blaming the clock. faketime changes the local process’s view of time; it neither changes the remote clock nor refreshes an expired ticket.

Success: editing works, SSH accepts the intended account, or the same Kerberos operation succeeds after a measured time correction. Record which dependency changed instead of treating a helper invocation as proof.

rlwrap completion is local, not remote

-c completes filenames on the listener machine. It does not enumerate the Windows/Linux target’s filesystem. -r remembers words seen in output for completion; it is not a remote command discovery mechanism. In this rlwrap build, -A enables ANSI-colour-aware prompt handling; it does not provide full terminal emulation.

# Avoid saving command history for this session
rlwrap -H /dev/null nc -lvnp 4444

If backspace prints escape sequences, check the remote shell and terminal handling separately. Full-screen editors, job control and Ctrl-C signal behaviour need a suitable remote PTY; adding more readline switches cannot supply one.

Feed sshpass through a descriptor

In Bash, prompt once and provide the password through a temporary descriptor:

read -r -s -p 'SSH password: ' lab_ssh_password
printf '\n'
sshpass -d 3 ssh -o StrictHostKeyChecking=yes labuser@host.example.test \
  3< <(printf '%s\n' "$lab_ssh_password")
unset lab_ssh_password

This example assumes the host key is already known and verified. Process substitution is Bash syntax; use the earlier protected-file method on shells without it. A descriptor removes the password from the command argument list, while the process still handles a secret in memory.

Exit/resultNext check
Password rejectedCorrect account, authentication method and password
Unknown/changed host keyVerify the expected fingerprint and known-hosts entry
Hangs at another promptMFA, key passphrase or nonstandard prompt unsupported by the invocation
SSH works manually but automation failsWhich prompt sshpass is matching and actual SSH stderr

Measure clock offset before correcting it

date -u '+%Y-%m-%dT%H:%M:%SZ'
timedatectl status
ntpdate -q dc01.example.test
klist

ntpdate -q queries without changing the clock. The server might not provide NTP, and UDP/123 may not cross a TCP-only pivot. Compare with an independently known DC UTC timestamp rather than guessing an offset from displayed local time.

Apply an offset to a process consistently

# Example measured correction: local clock is 90 seconds behind the DC
FAKETIME_DONT_FAKE_MONOTONIC=1 faketime -f '+90s' date -u
FAKETIME_DONT_FAKE_MONOTONIC=1 faketime -f '+90s' \
  getTGT.py -dc-ip 192.0.2.10 'example.test/labuser'

Verify that the first command shows the intended UTC instant. Use the same measured correction when consuming the new ticket. Runtime/static-binary behaviour can bypass libfaketime; a changed date output does not guarantee every application uses that clock. See the libfaketime documentation for compatibility details.

If your system time service immediately undoes a manual adjustment, investigate its configured source. Restore the original time-service state after the lab; do not leave a workstation synchronising to an unrelated DC.

See Also

Sources

On this page

☧ CPTS · ordered posts

Locked

Unlock with your Main_Key through local GPG.

Start the local GPG helper

In your cheatsheet checkout, run:

npm run unlock:helper

Open the link it prints, or paste its pairing code below. Keep the terminal open until GPG finishes.

Import an index you already decrypted

Download the encrypted index, then decrypt with GPG:

gpg --output report-index.json --decrypt report-index.gpg

Your private key stays in GPG. The decrypted index is saved in this browser so you can reopen it after navigation, refreshes and restarts. Lock this browser or clear this site's browser data to remove the saved index. Nothing is uploaded.