{"id":13338000,"url":"https://github.com/stealth/crash","last_synced_at":"2025-04-08T03:21:03.867Z","repository":{"id":14755091,"uuid":"17476340","full_name":"stealth/crash","owner":"stealth","description":"crypted admin shell: SSH-like strong crypto remote admin shell for Linux, BSD, Android, Solaris and OSX","archived":false,"fork":false,"pushed_at":"2024-09-27T11:47:51.000Z","size":493,"stargazers_count":194,"open_issues_count":0,"forks_count":28,"subscribers_count":13,"default_branch":"master","last_synced_at":"2025-03-28T15:06:27.748Z","etag":null,"topics":["anti-censorship","censorship-circumvention","censorship-resistance","dtls","encryption","privacy","pty","socks","socks-proxy","socks5-proxy","ssh","tls"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/stealth.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-03-06T12:04:50.000Z","updated_at":"2025-03-04T12:49:06.000Z","dependencies_parsed_at":"2023-01-11T18:53:35.895Z","dependency_job_id":"f14067d6-f2a0-440a-814f-4e520fbb9b4e","html_url":"https://github.com/stealth/crash","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stealth%2Fcrash","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stealth%2Fcrash/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stealth%2Fcrash/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stealth%2Fcrash/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stealth","download_url":"https://codeload.github.com/stealth/crash/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247767403,"owners_count":20992586,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["anti-censorship","censorship-circumvention","censorship-resistance","dtls","encryption","privacy","pty","socks","socks-proxy","socks5-proxy","ssh","tls"],"created_at":"2024-07-29T19:15:16.859Z","updated_at":"2025-04-08T03:21:03.838Z","avatar_url":"https://github.com/stealth.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"CRypted Admin SHell\n===================\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"https://github.com/stealth/crash/blob/master/logo.jpg\" /\u003e\n\u003c/p\u003e\n\nAn SSH alternative featuring:\n\n* IPv6 ready\n* lightweight, straight forward and extensible protocol using TLS 1.3\n  or optionally DTLS 1.2 as transport layer\n* man-in-the-middle safe due to its authentication mechanism\n  which involves the servers host key into the auth process\n* built-in traffic blinding against timing and packet-size info-leak attacks\n* not relying on any system auth frameworks such as PAM\n* can be entirely run as user, no need to setup config files\n* passive/active connects on both ends with most flexible\n  local/remote address+port binding possibilities\n* built-in SOCKS5 client side support when doing active connects\n* easy to port to embedded systems such as routers\n* quiet/hidden mode for secret administration and take-back\n  functionality for owned boxes\n* trigger-mode via syslog, mail or other files if requested\n* emergency mode to extract all necessary key files from the running binary\n* may be started as a CGI with all above functionality, command\n  switches passed via query-string\n* integrated tcp-wrapper-like D/DoS protection\n* intentionally not passing local $ENV to remote to avoid info leaks\n* supports Perfect Forward Secrecy via DH Kex\n* can forward TCP *and* UDP sockets to remote\n* SOCKS4 and SOCKS5 support to forward browser sessions to remote\n* messenger proxy support\n* proxying based on SNI\n* SNI hiding mode\n* Disguise Filters to mask as different kind of software to global observers\n* can use UDP transport mode with DTLS and added reliability and flow-control\n  layer\n* transparent roaming support with DTLS client sessions\n* suspend/resume support with DTLS client sessions\n\n\nIf you came here for censorship circumvention - once everything is done and working - go to\n[proxywars contrib](https://github.com/stealth/crash/blob/master/contrib/proxywars.md)\nto learn about how to create WA/TG messenger proxy setups in censorship environments.\n\n\nBuild\n-----\n\nBuild requires *OpenSSL* version \u003e= `1.1` or `3.0` or compatible *LibreSSL* (`3.6.1` tested).\nInside the cloned git repo:\n\n```\n$ make -C src\n```\n\nOn BSD systems you need to install *GNU make* and type `gmake` instead.\n\nIf you have a particular *OpenSSL* or *LibreSSL* setup, check the `Makefile` and\nset the appropriate `$SSL` variable. *crash* builds also nicely with *LibreSSL* and *BoringSSL*.\n\nFor Android, edit the `Makefile.android` or `Makefile.android.aarch64` to reflect\nyour NDK and *BoringSSL* install and use these. The build was tested with `android-ndk-r17b`.\n\nOn OSX you want to install *OpenSSL* via `brew install openssl@1.1` or by hand before `make`.\n\nOn Windows you need to install [cygwin](https://cygwin.com/install.html) and select\nthe appropriate `gcc, gcc-g++, perl, openssl (1.1.1), libssl (1.1.1), libssl-devel (1.1.1), make`\nand `git` packages before the build in order to clone and `make` this repo. Make sure\nyour openssl versions for the tool itself, the runtime libs and devel package are all\nthe same.\n\n*crash* was successfully tested on *Linux, FreeBSD, NetBSD, OpenSolaris, OSX and Android*.\n\nAfter that, to generate the required server and authentication keys:\n\n```\n$ make -C src keys\n```\n\nor see further instructions in this document. If you want to use _ephemeral keying_\n(aka [PFS](https://en.wikipedia.org/wiki/Perfect_Forward_Secrecy)), invoke\n\n```\n$ cd src; ./newdh\n```\n\nbefore `make` in order to generate DH parameters before the build. Thats not strictly necessary\nas of TLS 1.3, since the Kex will most likely chose one of the ECDH variants, but if you customize\nyour setup, it is recommended to generate your own DH params.\n\n\nLegacy builds\n-------------\n\nIf `make` detects that TLSv1.3 is not available on the system or `TLS_COMPAT_DOWNGRADE` is\ndefined, the binaries are built with TLSv1.2 only. This is to allow using it on legacy\nsystems when no other options are available. Obviosuly, the built binaries are not\ncompatible to normal builds, but include full support of all other features.\n\n\nOpenSSL3 builds\n---------------\n\nThe *OpenSSL 3* API is quite different from the *OpenSSL-1.1* API. In order to make\nuse of *OpenSSL 3*, you have to edit `Makefile` and `newdh` to reflect your path setup\nfor your *OpenSSL* install. Invoking `newdh` is mandatory, unlike for the 1.1 builds. After\nthat you just do `make` and everything should be the same as with 1.1.\n\n*proudly sponsored by:*\n\u003cp align=\"center\"\u003e\n\u003ca href=\"https://github.com/c-skills/welcome\"\u003e\n\u003cimg src=\"https://github.com/c-skills/welcome/blob/master/logo.jpg\"/\u003e\n\u003c/a\u003e\n\u003c/p\u003e\n\n\nRun\n---\n\n*crash* does not need any config or option files to run. Its easy and\nstraight forward to use. Anything can be enabled/disabled by\nruntime switches:\n\n```\nstealth@linux ~\u003e ./crashd -h\n\ncrypted admin shell (C) 2024 Sebastian Krahmer https://github.com/stealth/crash\n\n\nUsage:  ./crashd [-U] [-q] [-a] [-6] [-D] [-H host] [-p port] [-A auth keys]\n         [-k server key-file] [-c server X509 cert] [-L [ip]:port] [-S SNI]\n         [-t trigger-file] [-m trigger message] [-e] [-g good IPs] [-N] [-R]\n         [-x socks5://[ip]:port] [-G method:prefix:action] [-w]\n\n         -a -- always login if authenticated, despite false/nologin shells\n         -U -- run as user (e.g. turn off setuid() calls) if invoked as such\n         -e -- extract key and certfile from the binary itself (no -k/-c needed)\n         -q -- quiet mode, turns off logging and utmp entries\n         -6 -- use IPv6 rather than IPv4\n         -w -- setproctitle to `[kthreadd]` (must be last arg!)\n         -H -- host to connect to; if omitted: passive connect (default)\n         -p -- port to connect to when active connect; default is 2222\n         -L -- local [ip]:port used for binding ([0.0.0.0]:2222)\n         -g -- file containing list of good IP/IP6's in D/DoS case (default off)\n         -A -- authorized-key file for users if starts with '/'; folder inside ~\n               containing authorized_keys file otherwise; 'self' means to use\n               blob-extraction (see -e); default is .crash\n         -k -- servers key file; default is ./serverkey.priv\n         -c -- X509 certificate-file that belongs to serverkey (-k);\n               default is ./serverkey.pub\n         -t -- watch triggerfile for certain message (-m) before connect/listen\n         -m -- wait with connect/listen until message in file (-t) is seen\n         -N -- disable TCP/UDP port forwarding\n         -D -- use DTLS transport (requires -S)\n         -x -- use this SOCKS5 proxy when using active connect\n         -R -- allow clients to roam sessions\n         -G -- Traffic Disguise Filters, check docu\n         -S -- SNI to hide behind\n\n```\n\nMost of it is pretty self-explaining. *crashd* can run as user. `-U` lets *crashd*\nskip `setuid()` calls, effectively being able to run as user. In this case, it only accepts\nlogins to that user then by checking login name's `uid` against current `euid`.\nBoth, *crashc* and *crashd* can use active and passive connects. Whenever\na host-argument `-H` is given, it uses active connect to this host\nand the belonging port `-p`. It also accepts `-L` which specifies the local address and port it has\nto bind to, either before doing active connect (`-H`) or passively (no `-H` given).\nThis way - from TCP point view - client and server role may be reversed, while still having\n*crashd* as the shell server.\nIf `-w` is used it forks itself as **[kthreadd]** and tries to wrap around its\n`pid` to be somewhere around the system daemons. As `-w` is overwriting main()'s `argv` array,\nit must appear last in the option list, otherwise option processing will not work\ncorrectly. You can set the process name as `TITLE` def inside the `Makefile`.\n\nFor testing, when you did `make keys` (next section), you can just run\n\n```\nsrc $ ./crashd -U -L [127.0.0.1]:2222\n```\n(or omit `-L` paramater to bind to the default port on any address) and\n\n```\nsrc $ ./crashc -v -K none -i authkey.priv -H 127.0.0.1 -p 2222 -l $USER\n```\n\n\nKey setup\n---------\n\nUnless you want to use SNI-hiding (see section below), you can type straight ahead:\n\n```\n$ make -C src keys\n```\n\nBut you can also do it by hand. To generate a X509 certificate containing the server key:\n\n```\n$ umask 066\n$ openssl genrsa -out serverkey.priv 4096\n$ openssl req -new -x509 -nodes -sha1 -key serverkey.priv -out serverkey.pub\n```\n\nTo extract the public key in a form *crashc* can use it as a hostkey for comparison:\n\n```\n$ openssl x509 -in serverkey.pub -pubkey -noout \u003e HK_127.0.0.1\n```\n\nSo you have `HK_127.0.0.1` as the known-hosts keyfile for this host.\nAs an alternative, you can use *crashc* with `-v` upon connect to\nextract the pubkey. But note that this might already be a key presented to\nyou during an attack. So only do that if you know that the connection is\nnot tampered with (e.g. single user on localhost).\n\nUnless you use SNI hiding (see section below), the values you enter for *Country-Name,\nEmail, CN* etc. do not matter since *crashc* is not validating the X509. It just\ncompares the public key value it obtained from the server with the key it has in its\nlocal key-store belonging to that server (similar to *SSH*).\nThe server key is not encrypted since *crashd* is usually started\nvia init scripts. Instead, the key file must have proper permissions\nso only appropriate users can read it (mode 0600). You can, if you like,\nalso encrypt the server key but then you have to enter a pass-phrase\nwhenever *crashd* is started.\n\nTo generate a public/private RSA keypair for your authentication:\n\n```\n$ openssl genrsa -out authkey.priv -aes256 4096\n$ openssl rsa -in authkey.priv -pubout -out authkey.pub\n```\n\nCopy `authkey.pub` to `~/.crash/authorized_keys` on the remote box, and\nuse `authkey.priv` for the `crashc -i` argument. Note, that upon authentication\nyou will be asked for the pass-phrase to unlock your private key that is\nstored locally. The pass-phrase will not travel the network.\n\nAuth-Key sizes larger than *7500 bit* must not be used;\nthe tokens do not fit into the auth handshake otherwise.\n\n*crashc* is using the `.crash/` subdir by default to check for\nalready seen server keys. If you connect to a host via `-H $host -p $port`,\na keyfile of form `.crash/HK_$host:$port` is looked up unless you specify an\nabsolute path to a known keyfile.\n\nHostkeys\n--------\n\nBy default, *crashc* will compare server hostkeys to the local key cache\nthat is found inside the `.crash/` subdir of CWD. You may override the path of the cache\nfolder by using the `-K` switch. For example by using `-K ~/.crash/`, you use the folder\ninside your home directory. If the pathname does not end with a slash, it is treated as\na filename instead of a directory. If a cache directory is used instead of an\nfilename, each hostkey is expected to be found inside the folder as of the name `HK_$HOST:$PORT`\nwhere `$HOST` is the `-H` argument and `$PORT` the `-p` argument. If using `-v`\nthe server hostkey will be printed on `stderr` and may be pasted to the cache folder\ninto the `HK_$HOST:$PORT` file.\n\nHostkey checking may be suppressed by using `-K none`.\n\nThe crash auth protocol incorporates the server host key when signing authentication\nrequests. This way its not strictly necessary to check server host keys as\nyou know it from SSH password authentication. Two things have to be considered\nif host-key checks are suppressed with `-K none ` though:\n\n* The user-name will potentially leak to a MiM server\n\nThis is not an issue if you use a system user-name such as `root`.\n\n* The MiM could sort of phish you, by showing you a fake-shell where\n  you think it belongs to your real server. This could be used to\n  wait for `su` and similar commands and to record sensitive information\n  as you type on the MiM shell.\n\nTo conquer this, you have to make sure you are indeed on your real shell\nwhen you see the prompt. This can be achieved by echoing a secret token\nto the tty upon login, for example via one of the `.profile` or `.bashrc`\nfiles. As the MiM cannot know this token, you can be sure you have a\nconfidential and untampered session when you see this token upon login;\neven if you omit the host-key check.\n\n\nTerm setup\n----------\n\nAs *crashc* is not transfering env vars to the remote side for a reason, keep in mind\nthat certain stuff is unset, such as `$TERM`. I.e. if you want to run an editor on the remote\nshell and started *crashc* from within an xterm, you have to `TERM=xterm vi file` in order\nto have a useful editing session. Likewise for other programs that you expect to work and\nrequire specific environment setup.\n\nCGI\n---\n\n*crashd* automatically detects whether it has been invoked as a CGI by\na web-server by checking `QUERY_STRING` environment variable. It parses\nand converts the query-string into arguments it understands. It\ndoes not translate `%2F` etc characters! They should not be needed,\nsince spaces, '(' and other weird characters do not make sense when\ncalling crashd. Arguments that don't have a parameter such as `-U`\nhave to be given `=1` argument to enable it, such as in:\n\n```\nhttp://127.0.0.1/cgi-bin/crashd?-K=/path/to/serverkey.pem\u0026    \\\n      -C=/path/to/pubkey.x509\u0026-p=1234\u0026-A=/tmp/.crash/authorized_keys\u0026-U=1\u0026-a=1\n```\n\nwhich invokes *crashd* on the host 127.0.0.1 as user (probably \"wwwrun\" or whatever\nthe web-server is running as).\n\nFor pen-testing or for emergency case, *crashd* has the `-e` option.\nIf `-e` is used, it extracts the server key-file and the X509 certificate\nfrom the ELF binary file, which have to be appended before using `-e`:\n\n```\n$ cat serverkey.priv\u003e\u003ecrashd\n$ cat serverkey.pub\u003e\u003ecrashd\n$ cat authkey.pub\u003e\u003ecrashd\n```\n\nThe order of appended keys is important.\n\nIf you give `-A self` instead of a valid authentication directory or file,\n*crashd* also extracts the user-key used for authentication from its binary.\nThe keys are extracted from the binary at runtime and stored in temp files\nof pattern `/tmp/sshXXXXXX` (`/data/local/tmp/sshXXXXXX` on Android).\nMake sure to erase them securely upon last login, since they contain private keying\nmaterial.\n\nThis is useful in pen-tests where you cannot upload arbitrary amount of files\nor you do not know the exact pathname of the upload storage:\n\n```\n$ curl 'http://127.0.0.1/cgi-bin/crashd?-A=self\u0026-U=1\u0026-e=1\u0026-a=1'\n```\n\n`-a` is needed since most likely the *wwwrun* user has a `/bin/false` shell,\nwhich `-a` ignores.\n*crashd* is using `mkstemp()` to store the key files temporarily (just see above), with\nmode 0444 (world readable) since it needs to access authentication\nfiles as user. So be warned that, if you have users, they may read\nthe private key used during SSL handshake. After all, its just an\nemergency mode. Stripping the *crashd* binary is not possible after\nappending the keys, or they will get lost.\nBack-connect etc. also work in CGI mode as well.\nIf using that, client should use `-K` switch to tell client which key to use\nto authenticate the server.\n\n\nTCP and UDP port forward\n------------------------\n\n*crash* uses the same network engine as [psc](https://github.com/stealth/psc). Therefore\nyou may use the same `-U` and `-T` parameters as known from *psc* and which are similar\nto those of *OpenSSH's* `-L` parameter. It will bind to `lport` and will forward connections\nto `[ip]:rport`, initiating the connection from the remote host. The same works for UDP\npackets, which is not possible with SSH.\n\nIf you are interested in messenger proxy setups in copland countries, you can check `contrib`\nfolder.\n\n\nSOCKS4 and SOCKS5 support\n-------------------------\n\n*crash* also supports forwarding of TCP connections via *SOCKS4* (`-4 port`) and *SOCKS5*\n(`-5 port`). This sets up *port* as SOCKS port for TCP connections, so for instance you\ncan browse remote networks via *crashc* sessions without the need to open any other\nconnection during a pentest. If you pass `-N` to *crashc*, it enables DNS name resolution\non the remote side, so you can also use chrome with it. But be warned: There is a privacy\nproblem with browsers that try to resolve a sequence of DNS names upon startup that\nis not under your control. Also, if your remote side has a broken DNS setup, your typing\nshell may block for several seconds if DNS reply packets are missing. There are no good\nasync resolver functions which are embeddable and portable so I had to rely on\n`getaddrinfo()` in the single thread at the price of possible blockings for several seconds\nif DNS problems exist. Thats why name resolving has to be enabled explicitly. *crashd*\ntries to minimize this potential problem with DNS lookup caches though, so in most\nsituation it should just work painlessly.\nIf you pass `-X IP-address` (must come before any other proxy argument), you can bind your local proxy\nto an address different from `127.0.0.1`, so you can share the proxy in your local network.\n\nThere is also a client side SOCKS5 support available when using *crashc* with `-x`.\n\n\nProxying based on SNI\n---------------------\n\nIn some circumstances you might want to change the endpoint of the proxy session based\non a SNI that you receive in the TLS `ClientHello`. For convenience, *crashc* integrates\nsupport for that by using `-Y lport:SNI:[ip]:rport` which listens on `lport` and forwards the\ngiven `SNI` to `ip:rport`. A fallback of `default` SNI can be given so that any non-matches or\nmissing SNIs will be forwarded to that destination.\n\n\nDTLS transport\n--------------\n\n*crash* allows to use all of its trickery above also on a DTLS 1.2 transport layer based\non UDP. I have added basic flow control and reliability, so you can even xfer files and use\nport forwarding as with TLS 1.3. The reason for adding DTLS is that some countries have\nTCP egress filters that only allow incoming connections. It is harder for censors to tell\nwhich UDP packets establish an outgoing connection, as there is nothing like a \"connection\"\nwith UDP. With DTLS sessions, which are established by the `-D` switch on both sides, a SNI\nis mandatory.\nWhen forwarding UDP ports on DTLS sessions, make sure you will not send UDP payloads larger than\n1320 bytes across the sockets, as it is necessary in UDP case to keep enough room for headers\nand record layer without the need to fragment the packet, as DTLS honors packet boundaries\n(there is nothing like a stream as in TCP, just datagrams).\nDTLS mode is still experimental (although working stable) and will switch to DTLS 1.3 as soon\nas it is implemented widely (DTLS 1.3 RFC was just finished 2022).\n\n\nSuspend/Resume/Roaming\n----------------------\n\nThis is an experimental feature, although working stable.\n\nWhen using DTLS sessions and *crashd* is started with `-R`, you will get the following:\n\n* transparent roaming of the client sessions - including existing SOCKS connections - which\n  allows to switch underlying physical layer, VPN, Interface, NAT or IP address without\n  even noticing it\n* *crashc* may be terminated via `SIGTERM`, so it will dump the session to a ticket\n  file (`-t`) which can later be resumed from by passing the correct dst IP:port and ticket\n  but w/o the need to authenticate again (no `-i`) - with full roaming support\n\nIn the 2nd case, **the ticket file will not be encrypted**, so make sure you never leak it.\nThis allows you to switch off your laptop and continue working from elsewhere or even\nshare the ticket to another admin who then continues your session.\n\nOne thing is special with regards to bound server ports when using roaming: Due to\nUDP internals, the next open session for a followup \"connect\" will be on the next\nfree port in the range of `[port, port + 1000]` and not on the same port as when using TCP.\nThis needs to be as with roaming we cannot actually call `connect()` to virtually create a\nconnected tuple, as the next session packet can arrive from anywhere - not just from the\noriginating IP as happens with TCP. So when you start the server with `-p 2222` and one\nroaming session already exists, the next one needs to \"connect\" to port `2223`. If the\nsession at port `2222` is finished (not suspended, but really finished), port `2222`\nwill become available again to the next client.\n\nSuspend/Resume does not work yet with *LibreSSL* builds, but roaming does.\n\n\nMitigating traffic analysis\n---------------------------\n\nTraffic analysis mitigation has differant goals:\n\n* make it hard to find out actual typing sequences and potential info leaks about whats being typed\n* make it hard for a global observer to track connection streams across packet mixes or hubs\n* make it hard for censors to identify/distinguish crash sessions from a set of \"legit\" connections\n\nIt is not possible to reach all three goals at the same time, e.g. you want randomized packet sizes\nto make it hard for observers to know you are using a *crash* session, but this will also make\nyour packet stream unique across mixes.\n\nCompletely mitigating traffic analysis for a capable (global) observer is very hard.\nIt would require many crash users so to sink all individual packets in a swarm and\nmake it impossible to find patterns that could be used to track individual users across\npacket mixes. It would also require a fixed packet size for *all* packets as well as a\nconstant delay between the sends to make all connections look equal. Even then, there's\nstill the problem of the overall amount of traffic sent that may be measured and used\nto track individuals. As having constant size and delays would make the connection\nfeel slow or even unusable, *crash* lets you choose between traffic policies which are\ncontrolled by `-R \u003clevel:factor\u003e` at client side. *Level* is an integer with the following meaning:\n\n* 0: disable all padding of payloads and do not inject random traffic\n\n* 1: pad payload to rand size up to 1320 byte boundary, no injects\n* 2: pad payload to rand size up to 1320 byte boundary, random injects client side\n* 3: pad payload to rand size up to 1320 byte boundary, random injects with server responses\n\n* 4: pad payload to the next 256, 512, 1024 or 1320 byte boundary, no injects (default)\n* 5: pad payload to the next 256, 512, 1024 or 1320 byte boundary, random injects client side\n* 6: pad payload to the next 256, 512, 1024 or 1320 byte boundary, random injects with server\n     responses\n\n* 7: pad payload to 1320 byte boundary, no injects\n* 8: pad payload to 1320 byte boundary, random injects client side\n* 9: pad payload to 1320 byte boundary, random injects with server responses\n\n*Factor* is a multiply factor `1..100` that adds as many NOP packets per real packet in order\nto make it harder to match amount of input traffic to output traffic on proxy hosts.\n\n1320 is crashds internally used MSS. The values were chosen in a way so that sent data fits most\nlikely into a single packet. Note however that these are the packet sizes (plus the TLS record size)\nas it is passed to the TCP stack. TCP will decide itself how it will send the segments. There is\nno way to enforce 'TCP packet sizes', but this does not matter as the deps to the actual payload\nsize is already blurred.\n\nA higher *Level* does not automatically mean a better analysis mitigation. You have to chose the best\n`-R \u003clevel:factor\u003e` depending on your personal needs.\n\nIn DTLS mode there are always ping packets in order to implement synchronization and flow control.\n\nIf you live in a country with restrictive egress filtering, it may be helpful to test how long\nconnections can survive. Note that due to `-4` and `-U` which allows to proxy TCP *and* UDP (DNS)\nto a remote site, *crash* may be used as a [shadowsocks](https://shadowsocks.org) alternative that requires\nbasically no setup and just needs a user-shell behind egress.\n\nIf you think that all of this is paranoia, go get some product sheets for devices that\ndetect and classify SSH traffic by behavioral analysis.\n\n\nHiding by SNI\n-------------\n\nBy default, the *crashd* will show a banner upon connect to tell the peer major and minor version\nnumbers. Censorship countries might block addresses which show banners they dislike. To combat this,\n*crash* allows for a TLS-only mode that is indistinguishable from a HTTPS session. Just start\n*crashd* with `-S` and give a semi-secret name (Server Name Indicator, SNI). Only clients that also\nuse the correct `-S` parameter will reach the gate for authentication at all. Other TLS sessions\nwill just be rejected. *Note that the SNI travels the network in plain-text and that `-S` is not meant\nfor authentication.* The only reason for SNI hiding is to hide the *crash* banner from probing/crawling.\nYou may also use SNI proxies such as [sshttp](https://github.com/stealth/sshttp) to hide *crash* even\ndeeper and to forward all non-correct SNI connects to some web-site. This way you may hide your server\nbehind neutral web-sites from aggressively probing/blocking censors.\n\nIn order for probing to not reveal that you are running *crash* by checking the X509 certificate\ndetails, you should use reasonable values for *Country Name*, *City* etc. when asked for it during\nthe `make keys` process. For instance it would make no sense to setup a pro-regime web-site\nto hide behind and enter anti-regime values for the X509 specific naming.\n\nInside the `contrib` folder you will find a nginx config file that you can integrate into\nyour setup along with comments how you would create a connect from outside to your nginx server\nin order to have a *crash* session based on a SNI that you chose.\n\n\nDisguise Filters\n----------------\n\nTaking the feature of SNI hiding one step further. Some countries use network data gathered at\ntheir border routers to scan destination machines and check whether the content or software there\ncould pose a threat to their leaders. It is therefore not good to always tell anyone openly\nthat a *crashd* is running on a certain port, even if the peer shows up with the right SNI,\nas the SNI could have been sniffed by a global observer. Entering *Disguise Filters*.\n\nUpon connect, you have to show up with a correct (pre-)secret in order to start a *crash* session.\nThis can't be known by an observer as its hidden inside the TLS stream (unlike the SNI). If\nthe secret is not correct, *crashd* disguises as another - innocent looking - software.\n\nCurrently, there is only one Disguise Filter, `redirect1`, which masks as a web server\nsending a redirect of your choice. Disguise Filters always also require `-S`:\n\n\n```\n$ ./crashd -L [0.0.0.0]:4433 -c serverkey.pub -k serverkey.priv \\\n   -G redirect1:mydirtysecret:https://www.ccc.de -S localhost\n```\n\nSo only those who know can start a shell session:\n\n```\n$ ./crashc -H 127.0.0.1 -p 4433 -l stealth -i authkey.priv -S localhost -G mydirtysecret\n```\n\nAll others, e.g. `curl https://localhost:4433 -k -v -L` will be redirected to `https://www.ccc.de`.\n\n(where `localhost` was just chosen for testing to make curl have the right SNI)\nWhen a Disguise Filter is triggered, you will see it in the logs. This also allows admins to\nhave shell servers reachable from outside which just map to the legit web server when not\nprompted with the correct (pre-) secret.\nFor sure; for a disguise to work against censors with a large dick, your story has to be\nperfect, i.e. the CNs etc. of the certificate have to look legit, even better signed by\na legit CA and the redirect has to look reasonable.\n\n\nFile up/download\n----------------\n\nAlthough there is nothing like `sftp` for *crash*, it may be used for file up/downloads.\n\nIn order to upload a file:\n```\n~ $ crashc -H host -i authkey.priv -l root -c 'dd of=/path/on/remote status=progress' \u003c local.file\n```\n\nOr to download a file:\n```\n~ $ crashc -H host -i authkey.priv -l root -c 'dd if=/path/on/remote status=progress' \u003e local.file\n```\n\nNote that in the download case you must not specify the `-v` switch since this would add\nthe verbose output to the `local.file`. For `-c` commands, *crash* will forward `stdout` and\n`stderr` separated to the local tty's fd 1 and 2, so above commands add a nice progress bar\nduring the xfer.\n\n\nMTU/MSS\n-------\n\n*crash* is assuming a MTU of 1500 and using a MSS of 1320, so that TLS record layer and some other\nmeta data fits into this MTU and even into network devices with smaller MTU ~1400, which should fit with most\nVPN setups etc.. If you are using DTLS mode (that is UDP) and a VPN or whatever with a much smaller MTU,\nyou might want to compile *crash* with lower values which you can change in `misc.h`. If you are using TCP,\ni.e. not using the `-D` switch, these values do not matter for you.\n\n\nDoS mitigation\n--------------\n\n*crashd* includes some sort of D/DoS protection. Only one connection per second\nis allowed per IP, except if the IP is listed (or the network it belongs to)\nin a good-IP file given with -g at startup.\nPer default no good IPs are assigned. Network-address-goodness only works with\nIPv4 yet. A simple good-IP file may look like this:\n\n\n    # sample good-IP file\n    192.168.3.1\n    192.168.2.0\n    10.0.0.0\n    fe80:216::1234\n    # end of file\n\nTogether with the interval timer for hanging un-authenticated\nconnections this allows to have no more than 12 'hanging'\ncrashd's at the same time, still allowing you to login\nif you are listed in good-IPs and your underlying TCP/IP stack\nis not already trashed.\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstealth%2Fcrash","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstealth%2Fcrash","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstealth%2Fcrash/lists"}