├── LICENSE
├── README.md
├── bridge.jpg
├── contrib
├── nginx.add.conf
├── openssl.cnf
├── proxywars.md
└── pw.jpg
├── logo.jpg
└── src
├── Makefile
├── Makefile.android
├── Makefile.android.aarch64
├── config.cc
├── config.h
├── crashc.cc
├── crashd.cc
├── csession.cc
├── dh.cc
├── dh2048.cc
├── disguise.cc
├── disguise.h
├── global.cc
├── global.h
├── iobox.cc
├── iobox.h
├── log.cc
├── log.h
├── misc.cc
├── misc.h
├── missing.cc
├── missing.h
├── net.cc
├── net.h
├── newdh
├── pty.cc
├── pty.h
├── pty98.cc
├── server.cc
├── server.h
├── session.cc
├── session.h
└── ssession.cc
/LICENSE:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2009-2025 Sebastian Krahmer.
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions
7 | * are met:
8 | * 1. Redistributions of source code must retain the above copyright
9 | * notice, this list of conditions and the following disclaimer.
10 | * 2. Redistributions in binary form must reproduce the above copyright
11 | * notice, this list of conditions and the following disclaimer in the
12 | * documentation and/or other materials provided with the distribution.
13 | * 3. All advertising materials mentioning features or use of this software
14 | * must display the following acknowledgement:
15 | * This product includes software developed by Sebastian Krahmer.
16 | * 4. The name Sebastian Krahmer may not be used to endorse or promote
17 | * products derived from this software without specific prior written
18 | * permission.
19 | *
20 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
21 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
24 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 | * SUCH DAMAGE.
31 | */
32 |
33 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | CRypted Admin SHell
2 | ===================
3 |
4 |
5 |
6 |
7 |
8 | An SSH alternative featuring:
9 |
10 | * IPv6 ready
11 | * lightweight, straight forward and extensible protocol using TLS 1.3
12 | or optionally DTLS 1.2 or QUIC as transport layer
13 | * man-in-the-middle safe due to its authentication mechanism
14 | which involves the servers host key into the auth process
15 | * built-in traffic blinding against timing and packet-size info-leak attacks
16 | * not relying on any system auth frameworks such as PAM
17 | * can be entirely run as user, no need to setup config files
18 | * passive/active connects on both ends with most flexible
19 | local/remote address+port binding possibilities
20 | * built-in SOCKS5 client side support when doing active connects
21 | * easy to port to embedded systems such as routers
22 | * quiet/hidden mode for secret administration and take-back
23 | functionality for owned boxes
24 | * trigger-mode via syslog, mail or other files if requested
25 | * emergency mode to extract all necessary key files from the running binary
26 | * may be started as a CGI with all above functionality, command
27 | switches passed via query-string
28 | * integrated tcp-wrapper-like D/DoS protection
29 | * intentionally not passing local $ENV to remote to avoid info leaks
30 | * supports Perfect Forward Secrecy via DH Kex
31 | * can forward TCP *and* UDP sockets to remote
32 | * SOCKS4 and SOCKS5 support to forward browser sessions to remote
33 | * messenger proxy support
34 | * proxying based on SNI
35 | * SNI hiding mode
36 | * Disguise Filters to mask as different kind of software to global observers
37 | * can use UDP transport mode with DTLS and added reliability and flow-control
38 | layer
39 | * transparent roaming support with DTLS client sessions
40 | * suspend/resume support with DTLS client sessions
41 |
42 |
43 | If you came here for censorship circumvention - once everything is done and working - go to
44 | [proxywars contrib](https://github.com/stealth/crash/blob/master/contrib/proxywars.md)
45 | to learn about how to create WA/TG messenger proxy setups in censorship environments.
46 |
47 |
48 | Build
49 | -----
50 |
51 | Build requires *OpenSSL* version >= `1.1` or `3.0` or compatible *LibreSSL* (`3.6.1` tested).
52 | Inside the cloned git repo:
53 |
54 | ```
55 | $ make -C src
56 | ```
57 |
58 | On BSD systems you need to install *GNU make* and type `gmake` instead.
59 |
60 | If you have a particular *OpenSSL* or *LibreSSL* setup, check the `Makefile` and
61 | set the appropriate `$SSL` variable. *crash* builds also nicely with *LibreSSL* and *BoringSSL*.
62 |
63 | For Android, edit the `Makefile.android` or `Makefile.android.aarch64` to reflect
64 | your NDK and *BoringSSL* install and use these. The build was tested with `android-ndk-r17b`.
65 |
66 | On OSX you want to install *OpenSSL* via `brew install openssl@1.1` or by hand before `make`.
67 |
68 | On Windows you need to install [cygwin](https://cygwin.com/install.html) and select
69 | the appropriate `gcc, gcc-g++, perl, openssl (1.1.1), libssl (1.1.1), libssl-devel (1.1.1), make`
70 | and `git` packages before the build in order to clone and `make` this repo. Make sure
71 | your openssl versions for the tool itself, the runtime libs and devel package are all
72 | the same.
73 |
74 | *crash* was successfully tested on *Linux, FreeBSD, NetBSD, OpenSolaris, OSX and Android*.
75 |
76 | After that, to generate the required server and authentication keys:
77 |
78 | ```
79 | $ make -C src keys
80 | ```
81 |
82 | or see further instructions in this document. If you want to use _ephemeral keying_
83 | (aka [PFS](https://en.wikipedia.org/wiki/Perfect_Forward_Secrecy)), invoke
84 |
85 | ```
86 | $ cd src; ./newdh
87 | ```
88 |
89 | before `make` in order to generate DH parameters before the build. Thats not strictly necessary
90 | as of TLS 1.3, since the Kex will most likely chose one of the ECDH variants, but if you customize
91 | your setup, it is recommended to generate your own DH params.
92 |
93 | If you want to use the experimental QUIC transport mode, you need to install `OpenSSL >= 3.5.0-beta1`
94 | and adjust the `Makefile` to `HAVE_QUIC` and the *OpenSSL* install path, similar to that which
95 | is commented out. You possibly also need to adjust the path of the openssl binary inside `newdh`
96 | if you were not using *OpenSSL3* already, and invoke `newdh` before the build.
97 |
98 |
99 | Legacy builds
100 | -------------
101 |
102 | If `make` detects that TLSv1.3 is not available on the system or `TLS_COMPAT_DOWNGRADE` is
103 | defined, the binaries are built with TLSv1.2 only. This is to allow using it on legacy
104 | systems when no other options are available. Obviosuly, the built binaries are not
105 | compatible to normal builds, but include full support of all other features.
106 |
107 |
108 | OpenSSL3 builds
109 | ---------------
110 |
111 | The *OpenSSL 3* API is quite different from the *OpenSSL-1.1* API. In order to make
112 | use of *OpenSSL 3*, you have to edit `Makefile` and `newdh` to reflect your path setup
113 | for your *OpenSSL* install. Invoking `newdh` is mandatory, unlike for the 1.1 builds. After
114 | that you just do `make` and everything should be the same as with 1.1.
115 |
116 | *proudly sponsored by:*
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 | Run
125 | ---
126 |
127 | *crash* does not need any config or option files to run. Its easy and
128 | straight forward to use. Anything can be enabled/disabled by
129 | runtime switches:
130 |
131 | ```
132 | stealth@linux ~> ./crashd -h
133 |
134 | crypted admin shell (C) 2024 Sebastian Krahmer https://github.com/stealth/crash
135 |
136 |
137 | Usage: ./crashd [-U] [-q] [-a] [-6] [-D] [-H host] [-p port] [-A auth keys]
138 | [-k server key-file] [-c server X509 cert] [-L [ip]:port] [-S SNI]
139 | [-t trigger-file] [-m trigger message] [-e] [-g good IPs] [-N] [-R]
140 | [-x socks5://[ip]:port] [-G method:prefix:action] [-w]
141 |
142 | -a -- always login if authenticated, despite false/nologin shells
143 | -U -- run as user (e.g. turn off setuid() calls) if invoked as such
144 | -e -- extract key and certfile from the binary itself (no -k/-c needed)
145 | -q -- quiet mode, turns off logging and utmp entries
146 | -6 -- use IPv6 rather than IPv4
147 | -w -- setproctitle to `[kthreadd]` (must be last arg!)
148 | -H -- host to connect to; if omitted: passive connect (default)
149 | -p -- port to connect to when active connect; default is 2222
150 | -L -- local [ip]:port used for binding ([0.0.0.0]:2222)
151 | -g -- file containing list of good IP/IP6's in D/DoS case (default off)
152 | -A -- authorized-key file for users if starts with '/'; folder inside ~
153 | containing authorized_keys file otherwise; 'self' means to use
154 | blob-extraction (see -e); default is .crash
155 | -k -- servers key file; default is ./serverkey.priv
156 | -c -- X509 certificate-file that belongs to serverkey (-k);
157 | default is ./serverkey.pub
158 | -t -- watch triggerfile for certain message (-m) before connect/listen
159 | -m -- wait with connect/listen until message in file (-t) is seen
160 | -N -- disable TCP/UDP port forwarding
161 | -D -- use DTLS transport (requires -S)
162 | -x -- use this SOCKS5 proxy when using active connect
163 | -R -- allow clients to roam sessions
164 | -G -- Traffic Disguise Filters, check docu
165 | -S -- SNI to hide behind
166 |
167 | ```
168 |
169 | Most of it is pretty self-explaining. *crashd* can run as user. `-U` lets *crashd*
170 | skip `setuid()` calls, effectively being able to run as user. In this case, it only accepts
171 | logins to that user then by checking login name's `uid` against current `euid`.
172 | Both, *crashc* and *crashd* can use active and passive connects. Whenever
173 | a host-argument `-H` is given, it uses active connect to this host
174 | and the belonging port `-p`. It also accepts `-L` which specifies the local address and port it has
175 | to bind to, either before doing active connect (`-H`) or passively (no `-H` given).
176 | This way - from TCP point view - client and server role may be reversed, while still having
177 | *crashd* as the shell server.
178 | If `-w` is used it forks itself as **[kthreadd]** and tries to wrap around its
179 | `pid` to be somewhere around the system daemons. As `-w` is overwriting main()'s `argv` array,
180 | it must appear last in the option list, otherwise option processing will not work
181 | correctly. You can set the process name as `TITLE` def inside the `Makefile`.
182 |
183 | For testing, when you did `make keys` (next section), you can just run
184 |
185 | ```
186 | src $ ./crashd -U -L [127.0.0.1]:2222
187 | ```
188 | (or omit `-L` paramater to bind to the default port on any address) and
189 |
190 | ```
191 | src $ ./crashc -v -K none -i authkey.priv -H 127.0.0.1 -p 2222 -l $USER
192 | ```
193 |
194 |
195 | Key setup
196 | ---------
197 |
198 | Unless you want to use SNI-hiding (see section below), you can type straight ahead:
199 |
200 | ```
201 | $ make -C src keys
202 | ```
203 |
204 | But you can also do it by hand. To generate a X509 certificate containing the server key:
205 |
206 | ```
207 | $ umask 066
208 | $ openssl genrsa -out serverkey.priv 4096
209 | $ openssl req -new -x509 -nodes -sha1 -key serverkey.priv -out serverkey.pub
210 | ```
211 |
212 | To extract the public key in a form *crashc* can use it as a hostkey for comparison:
213 |
214 | ```
215 | $ openssl x509 -in serverkey.pub -pubkey -noout > HK_127.0.0.1
216 | ```
217 |
218 | So you have `HK_127.0.0.1` as the known-hosts keyfile for this host.
219 | As an alternative, you can use *crashc* with `-v` upon connect to
220 | extract the pubkey. But note that this might already be a key presented to
221 | you during an attack. So only do that if you know that the connection is
222 | not tampered with (e.g. single user on localhost).
223 |
224 | Unless you use SNI hiding (see section below), the values you enter for *Country-Name,
225 | Email, CN* etc. do not matter since *crashc* is not validating the X509. It just
226 | compares the public key value it obtained from the server with the key it has in its
227 | local key-store belonging to that server (similar to *SSH*).
228 | The server key is not encrypted since *crashd* is usually started
229 | via init scripts. Instead, the key file must have proper permissions
230 | so only appropriate users can read it (mode 0600). You can, if you like,
231 | also encrypt the server key but then you have to enter a pass-phrase
232 | whenever *crashd* is started.
233 |
234 | To generate a public/private RSA keypair for your authentication:
235 |
236 | ```
237 | $ openssl genrsa -out authkey.priv -aes256 4096
238 | $ openssl rsa -in authkey.priv -pubout -out authkey.pub
239 | ```
240 |
241 | Copy `authkey.pub` to `~/.crash/authorized_keys` on the remote box, and
242 | use `authkey.priv` for the `crashc -i` argument. Note, that upon authentication
243 | you will be asked for the pass-phrase to unlock your private key that is
244 | stored locally. The pass-phrase will not travel the network.
245 |
246 | Auth-Key sizes larger than *7500 bit* must not be used;
247 | the tokens do not fit into the auth handshake otherwise.
248 |
249 | *crashc* is using the `.crash/` subdir by default to check for
250 | already seen server keys. If you connect to a host via `-H $host -p $port`,
251 | a keyfile of form `.crash/HK_$host:$port` is looked up unless you specify an
252 | absolute path to a known keyfile.
253 |
254 | Hostkeys
255 | --------
256 |
257 | By default, *crashc* will compare server hostkeys to the local key cache
258 | that is found inside the `.crash/` subdir of CWD. You may override the path of the cache
259 | folder by using the `-K` switch. For example by using `-K ~/.crash/`, you use the folder
260 | inside your home directory. If the pathname does not end with a slash, it is treated as
261 | a filename instead of a directory. If a cache directory is used instead of an
262 | filename, each hostkey is expected to be found inside the folder as of the name `HK_$HOST:$PORT`
263 | where `$HOST` is the `-H` argument and `$PORT` the `-p` argument. If using `-v`
264 | the server hostkey will be printed on `stderr` and may be pasted to the cache folder
265 | into the `HK_$HOST:$PORT` file.
266 |
267 | Hostkey checking may be suppressed by using `-K none`.
268 |
269 | The crash auth protocol incorporates the server host key when signing authentication
270 | requests. This way its not strictly necessary to check server host keys as
271 | you know it from SSH password authentication. Two things have to be considered
272 | if host-key checks are suppressed with `-K none ` though:
273 |
274 | * The user-name will potentially leak to a MiM server
275 |
276 | This is not an issue if you use a system user-name such as `root`.
277 |
278 | * The MiM could sort of phish you, by showing you a fake-shell where
279 | you think it belongs to your real server. This could be used to
280 | wait for `su` and similar commands and to record sensitive information
281 | as you type on the MiM shell.
282 |
283 | To conquer this, you have to make sure you are indeed on your real shell
284 | when you see the prompt. This can be achieved by echoing a secret token
285 | to the tty upon login, for example via one of the `.profile` or `.bashrc`
286 | files. As the MiM cannot know this token, you can be sure you have a
287 | confidential and untampered session when you see this token upon login;
288 | even if you omit the host-key check.
289 |
290 |
291 | Term setup
292 | ----------
293 |
294 | As *crashc* is not transfering env vars to the remote side for a reason, keep in mind
295 | that certain stuff is unset, such as `$TERM`. I.e. if you want to run an editor on the remote
296 | shell and started *crashc* from within an xterm, you have to `TERM=xterm vi file` in order
297 | to have a useful editing session. Likewise for other programs that you expect to work and
298 | require specific environment setup.
299 |
300 | CGI
301 | ---
302 |
303 | *crashd* automatically detects whether it has been invoked as a CGI by
304 | a web-server by checking `QUERY_STRING` environment variable. It parses
305 | and converts the query-string into arguments it understands. It
306 | does not translate `%2F` etc characters! They should not be needed,
307 | since spaces, '(' and other weird characters do not make sense when
308 | calling crashd. Arguments that don't have a parameter such as `-U`
309 | have to be given `=1` argument to enable it, such as in:
310 |
311 | ```
312 | http://127.0.0.1/cgi-bin/crashd?-K=/path/to/serverkey.pem& \
313 | -C=/path/to/pubkey.x509&-p=1234&-A=/tmp/.crash/authorized_keys&-U=1&-a=1
314 | ```
315 |
316 | which invokes *crashd* on the host 127.0.0.1 as user (probably "wwwrun" or whatever
317 | the web-server is running as).
318 |
319 | For pen-testing or for emergency case, *crashd* has the `-e` option.
320 | If `-e` is used, it extracts the server key-file and the X509 certificate
321 | from the ELF binary file, which have to be appended before using `-e`:
322 |
323 | ```
324 | $ cat serverkey.priv>>crashd
325 | $ cat serverkey.pub>>crashd
326 | $ cat authkey.pub>>crashd
327 | ```
328 |
329 | The order of appended keys is important.
330 |
331 | If you give `-A self` instead of a valid authentication directory or file,
332 | *crashd* also extracts the user-key used for authentication from its binary.
333 | The keys are extracted from the binary at runtime and stored in temp files
334 | of pattern `/tmp/sshXXXXXX` (`/data/local/tmp/sshXXXXXX` on Android).
335 | Make sure to erase them securely upon last login, since they contain private keying
336 | material.
337 |
338 | This is useful in pen-tests where you cannot upload arbitrary amount of files
339 | or you do not know the exact pathname of the upload storage:
340 |
341 | ```
342 | $ curl 'http://127.0.0.1/cgi-bin/crashd?-A=self&-U=1&-e=1&-a=1'
343 | ```
344 |
345 | `-a` is needed since most likely the *wwwrun* user has a `/bin/false` shell,
346 | which `-a` ignores.
347 | *crashd* is using `mkstemp()` to store the key files temporarily (just see above), with
348 | mode 0444 (world readable) since it needs to access authentication
349 | files as user. So be warned that, if you have users, they may read
350 | the private key used during SSL handshake. After all, its just an
351 | emergency mode. Stripping the *crashd* binary is not possible after
352 | appending the keys, or they will get lost.
353 | Back-connect etc. also work in CGI mode as well.
354 | If using that, client should use `-K` switch to tell client which key to use
355 | to authenticate the server.
356 |
357 |
358 | TCP and UDP port forward
359 | ------------------------
360 |
361 | *crash* uses the same network engine as [psc](https://github.com/stealth/psc). Therefore
362 | you may use the same `-U` and `-T` parameters as known from *psc* and which are similar
363 | to those of *OpenSSH's* `-L` parameter. It will bind to `lport` and will forward connections
364 | to `[ip]:rport`, initiating the connection from the remote host. The same works for UDP
365 | packets, which is not possible with SSH.
366 |
367 | If you are interested in messenger proxy setups in copland countries, you can check `contrib`
368 | folder.
369 |
370 |
371 | SOCKS4 and SOCKS5 support
372 | -------------------------
373 |
374 | *crash* also supports forwarding of TCP connections via *SOCKS4* (`-4 port`) and *SOCKS5*
375 | (`-5 port`). This sets up *port* as SOCKS port for TCP connections, so for instance you
376 | can browse remote networks via *crashc* sessions without the need to open any other
377 | connection during a pentest. If you pass `-N` to *crashc*, it enables DNS name resolution
378 | on the remote side, so you can also use chrome with it. But be warned: There is a privacy
379 | problem with browsers that try to resolve a sequence of DNS names upon startup that
380 | is not under your control. Also, if your remote side has a broken DNS setup, your typing
381 | shell may block for several seconds if DNS reply packets are missing. There are no good
382 | async resolver functions which are embeddable and portable so I had to rely on
383 | `getaddrinfo()` in the single thread at the price of possible blockings for several seconds
384 | if DNS problems exist. Thats why name resolving has to be enabled explicitly. *crashd*
385 | tries to minimize this potential problem with DNS lookup caches though, so in most
386 | situation it should just work painlessly.
387 | If you pass `-X IP-address` (must come before any other proxy argument), you can bind your local proxy
388 | to an address different from `127.0.0.1`, so you can share the proxy in your local network.
389 |
390 | There is also a client side SOCKS5 support available when using *crashc* with `-x`.
391 |
392 |
393 | Proxying based on SNI
394 | ---------------------
395 |
396 | In some circumstances you might want to change the endpoint of the proxy session based
397 | on a SNI that you receive in the TLS `ClientHello`. For convenience, *crashc* integrates
398 | support for that by using `-Y lport:SNI:[ip]:rport` which listens on `lport` and forwards the
399 | given `SNI` to `ip:rport`. A fallback of `default` SNI can be given so that any non-matches or
400 | missing SNIs will be forwarded to that destination.
401 |
402 |
403 | DTLS transport
404 | --------------
405 |
406 | *crash* allows to use all of its trickery above also on a DTLS 1.2 transport layer based
407 | on UDP. I have added basic flow control and reliability, so you can even xfer files and use
408 | port forwarding as with TLS 1.3. The reason for adding DTLS is that some countries have
409 | TCP egress filters that only allow incoming connections. It is harder for censors to tell
410 | which UDP packets establish an outgoing connection, as there is nothing like a "connection"
411 | with UDP. With DTLS sessions, which are established by the `-D` switch on both sides, a SNI
412 | is mandatory.
413 | When forwarding UDP ports on DTLS sessions, make sure you will not send UDP payloads larger than
414 | 1320 bytes across the sockets, as it is necessary in UDP case to keep enough room for headers
415 | and record layer without the need to fragment the packet, as DTLS honors packet boundaries
416 | (there is nothing like a stream as in TCP, just datagrams).
417 | DTLS mode is still experimental (although working stable) and will switch to DTLS 1.3 as soon
418 | as it is implemented widely (DTLS 1.3 RFC was just finished 2022).
419 |
420 |
421 | Suspend/Resume/Roaming
422 | ----------------------
423 |
424 | This is an experimental feature, although working stable.
425 |
426 | When using DTLS sessions and *crashd* is started with `-R`, you will get the following:
427 |
428 | * transparent roaming of the client sessions - including existing SOCKS connections - which
429 | allows to switch underlying physical layer, VPN, Interface, NAT or IP address without
430 | even noticing it
431 | * *crashc* may be terminated via `SIGTERM`, so it will dump the session to a ticket
432 | file (`-t`) which can later be resumed from by passing the correct dst IP:port and ticket
433 | but w/o the need to authenticate again (no `-i`) - with full roaming support
434 |
435 | In the 2nd case, **the ticket file will not be encrypted**, so make sure you never leak it.
436 | This allows you to switch off your laptop and continue working from elsewhere or even
437 | share the ticket to another admin who then continues your session.
438 |
439 | One thing is special with regards to bound server ports when using roaming: Due to
440 | UDP internals, the next open session for a followup "connect" will be on the next
441 | free port in the range of `[port, port + 1000]` and not on the same port as when using TCP.
442 | This needs to be as with roaming we cannot actually call `connect()` to virtually create a
443 | connected tuple, as the next session packet can arrive from anywhere - not just from the
444 | originating IP as happens with TCP. So when you start the server with `-p 2222` and one
445 | roaming session already exists, the next one needs to "connect" to port `2223`. If the
446 | session at port `2222` is finished (not suspended, but really finished), port `2222`
447 | will become available again to the next client.
448 |
449 | Suspend/Resume does not work yet with *LibreSSL* builds, but roaming does.
450 |
451 |
452 | Mitigating traffic analysis
453 | ---------------------------
454 |
455 | Traffic analysis mitigation has differant goals:
456 |
457 | * make it hard to find out actual typing sequences and potential info leaks about whats being typed
458 | * make it hard for a global observer to track connection streams across packet mixes or hubs
459 | * make it hard for censors to identify/distinguish crash sessions from a set of "legit" connections
460 |
461 | It is not possible to reach all three goals at the same time, e.g. you want randomized packet sizes
462 | to make it hard for observers to know you are using a *crash* session, but this will also make
463 | your packet stream unique across mixes.
464 |
465 | Completely mitigating traffic analysis for a capable (global) observer is very hard.
466 | It would require many crash users so to sink all individual packets in a swarm and
467 | make it impossible to find patterns that could be used to track individual users across
468 | packet mixes. It would also require a fixed packet size for *all* packets as well as a
469 | constant delay between the sends to make all connections look equal. Even then, there's
470 | still the problem of the overall amount of traffic sent that may be measured and used
471 | to track individuals. As having constant size and delays would make the connection
472 | feel slow or even unusable, *crash* lets you choose between traffic policies which are
473 | controlled by `-R ` at client side. *Level* is an integer with the following meaning:
474 |
475 | * 0: disable all padding of payloads and do not inject random traffic
476 |
477 | * 1: pad payload to rand size up to 1320 byte boundary, no injects
478 | * 2: pad payload to rand size up to 1320 byte boundary, random injects client side
479 | * 3: pad payload to rand size up to 1320 byte boundary, random injects with server responses
480 |
481 | * 4: pad payload to the next 256, 512, 1024 or 1320 byte boundary, no injects (default)
482 | * 5: pad payload to the next 256, 512, 1024 or 1320 byte boundary, random injects client side
483 | * 6: pad payload to the next 256, 512, 1024 or 1320 byte boundary, random injects with server
484 | responses
485 |
486 | * 7: pad payload to 1320 byte boundary, no injects
487 | * 8: pad payload to 1320 byte boundary, random injects client side
488 | * 9: pad payload to 1320 byte boundary, random injects with server responses
489 |
490 | *Factor* is a multiply factor `1..100` that adds as many NOP packets per real packet in order
491 | to make it harder to match amount of input traffic to output traffic on proxy hosts.
492 |
493 | 1320 is crashds internally used MSS. The values were chosen in a way so that sent data fits most
494 | likely into a single packet. Note however that these are the packet sizes (plus the TLS record size)
495 | as it is passed to the TCP stack. TCP will decide itself how it will send the segments. There is
496 | no way to enforce 'TCP packet sizes', but this does not matter as the deps to the actual payload
497 | size is already blurred.
498 |
499 | A higher *Level* does not automatically mean a better analysis mitigation. You have to chose the best
500 | `-R ` depending on your personal needs.
501 |
502 | In DTLS mode there are always ping packets in order to implement synchronization and flow control.
503 |
504 | If you live in a country with restrictive egress filtering, it may be helpful to test how long
505 | connections can survive. Note that due to `-4` and `-U` which allows to proxy TCP *and* UDP (DNS)
506 | to a remote site, *crash* may be used as a [shadowsocks](https://shadowsocks.org) alternative that requires
507 | basically no setup and just needs a user-shell behind egress.
508 |
509 | If you think that all of this is paranoia, go get some product sheets for devices that
510 | detect and classify SSH traffic by behavioral analysis.
511 |
512 |
513 | Hiding by SNI
514 | -------------
515 |
516 | By default, the *crashd* will show a banner upon connect to tell the peer major and minor version
517 | numbers. Censorship countries might block addresses which show banners they dislike. To combat this,
518 | *crash* allows for a TLS-only mode that is indistinguishable from a HTTPS session. Just start
519 | *crashd* with `-S` and give a semi-secret name (Server Name Indicator, SNI). Only clients that also
520 | use the correct `-S` parameter will reach the gate for authentication at all. Other TLS sessions
521 | will just be rejected. *Note that the SNI travels the network in plain-text and that `-S` is not meant
522 | for authentication.* The only reason for SNI hiding is to hide the *crash* banner from probing/crawling.
523 | You may also use SNI proxies such as [sshttp](https://github.com/stealth/sshttp) to hide *crash* even
524 | deeper and to forward all non-correct SNI connects to some web-site. This way you may hide your server
525 | behind neutral web-sites from aggressively probing/blocking censors.
526 |
527 | In order for probing to not reveal that you are running *crash* by checking the X509 certificate
528 | details, you should use reasonable values for *Country Name*, *City* etc. when asked for it during
529 | the `make keys` process. For instance it would make no sense to setup a pro-regime web-site
530 | to hide behind and enter anti-regime values for the X509 specific naming.
531 |
532 | Inside the `contrib` folder you will find a nginx config file that you can integrate into
533 | your setup along with comments how you would create a connect from outside to your nginx server
534 | in order to have a *crash* session based on a SNI that you chose.
535 |
536 |
537 | Disguise Filters
538 | ----------------
539 |
540 | Taking the feature of SNI hiding one step further. Some countries use network data gathered at
541 | their border routers to scan destination machines and check whether the content or software there
542 | could pose a threat to their leaders. It is therefore not good to always tell anyone openly
543 | that a *crashd* is running on a certain port, even if the peer shows up with the right SNI,
544 | as the SNI could have been sniffed by a global observer. Entering *Disguise Filters*.
545 |
546 | Upon connect, you have to show up with a correct (pre-)secret in order to start a *crash* session.
547 | This can't be known by an observer as its hidden inside the TLS stream (unlike the SNI). If
548 | the secret is not correct, *crashd* disguises as another - innocent looking - software.
549 |
550 | Currently, there is only one Disguise Filter, `redirect1`, which masks as a web server
551 | sending a redirect of your choice. Disguise Filters always also require `-S`:
552 |
553 |
554 | ```
555 | $ ./crashd -L [0.0.0.0]:4433 -c serverkey.pub -k serverkey.priv \
556 | -G redirect1:mydirtysecret:https://www.ccc.de -S localhost
557 | ```
558 |
559 | So only those who know can start a shell session:
560 |
561 | ```
562 | $ ./crashc -H 127.0.0.1 -p 4433 -l stealth -i authkey.priv -S localhost -G mydirtysecret
563 | ```
564 |
565 | All others, e.g. `curl https://localhost:4433 -k -v -L` will be redirected to `https://www.ccc.de`.
566 |
567 | (where `localhost` was just chosen for testing to make curl have the right SNI)
568 | When a Disguise Filter is triggered, you will see it in the logs. This also allows admins to
569 | have shell servers reachable from outside which just map to the legit web server when not
570 | prompted with the correct (pre-) secret.
571 | For sure; for a disguise to work against censors with a large dick, your story has to be
572 | perfect, i.e. the CNs etc. of the certificate have to look legit, even better signed by
573 | a legit CA and the redirect has to look reasonable.
574 |
575 |
576 | File up/download
577 | ----------------
578 |
579 | Although there is nothing like `sftp` for *crash*, it may be used for file up/downloads.
580 |
581 | In order to upload a file:
582 | ```
583 | ~ $ crashc -H host -i authkey.priv -l root -c 'dd of=/path/on/remote status=progress' < local.file
584 | ```
585 |
586 | Or to download a file:
587 | ```
588 | ~ $ crashc -H host -i authkey.priv -l root -c 'dd if=/path/on/remote status=progress' > local.file
589 | ```
590 |
591 | Note that in the download case you must not specify the `-v` switch since this would add
592 | the verbose output to the `local.file`. For `-c` commands, *crash* will forward `stdout` and
593 | `stderr` separated to the local tty's fd 1 and 2, so above commands add a nice progress bar
594 | during the xfer.
595 |
596 |
597 | MTU/MSS
598 | -------
599 |
600 | *crash* is assuming a MTU of 1500 and using a MSS of 1320, so that TLS record layer and some other
601 | meta data fits into this MTU and even into network devices with smaller MTU ~1400, which should fit with most
602 | VPN setups etc.. If you are using DTLS mode (that is UDP) and a VPN or whatever with a much smaller MTU,
603 | you might want to compile *crash* with lower values which you can change in `misc.h`. If you are using TCP,
604 | i.e. not using the `-D` switch, these values do not matter for you.
605 |
606 |
607 | DoS mitigation
608 | --------------
609 |
610 | *crashd* includes some sort of D/DoS protection. Only one connection per second
611 | is allowed per IP, except if the IP is listed (or the network it belongs to)
612 | in a good-IP file given with -g at startup.
613 | Per default no good IPs are assigned. Network-address-goodness only works with
614 | IPv4 yet. A simple good-IP file may look like this:
615 |
616 |
617 | # sample good-IP file
618 | 192.168.3.1
619 | 192.168.2.0
620 | 10.0.0.0
621 | fe80:216::1234
622 | # end of file
623 |
624 | Together with the interval timer for hanging un-authenticated
625 | connections this allows to have no more than 12 'hanging'
626 | crashd's at the same time, still allowing you to login
627 | if you are listed in good-IPs and your underlying TCP/IP stack
628 | is not already trashed.
629 |
630 |
631 |
632 |
633 |
634 |
635 |
636 |
637 |
--------------------------------------------------------------------------------
/bridge.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stealth/crash/338cc70f445997e2c408d6ae8ee0543fa1d8f6e3/bridge.jpg
--------------------------------------------------------------------------------
/contrib/nginx.add.conf:
--------------------------------------------------------------------------------
1 | #
2 | # Add this to your nginx.conf and restart.
3 | #
4 | # It will forward the crashc TLS session non-terminating to crashd
5 | # running on localhost, if you connect from outside to your nginx server
6 | # at port 4433 with SNI `good.sni.example.com` (change SNI as needed to bypass
7 | # censorship devices).
8 | #
9 | # It requires nginx to be built with SNI and stream support (nginx -V), but thats
10 | # mostly the case for distro packages.
11 | #
12 | # Change nginx port and certificates etc. as needed to integrate with your legit
13 | # looking pro-regime website to serve a standard innocent web-page when
14 | # web clients connect.
15 | #
16 | # credit goes to: https://gist.github.com/kekru/c09dbab5e78bf76402966b13fa72b9d2
17 | #
18 |
19 | stream {
20 |
21 | map $ssl_preread_server_name $targetBackend {
22 | good.sni.example.com 127.0.0.1:2222;
23 | # other.sni.example.com 127.0.0.1:2223;
24 | }
25 |
26 | server {
27 | listen 4433;
28 |
29 | proxy_connect_timeout 1s;
30 | proxy_timeout 100000s;
31 | resolver 1.1.1.1;
32 |
33 | proxy_pass $targetBackend;
34 | ssl_preread on;
35 | }
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/contrib/openssl.cnf:
--------------------------------------------------------------------------------
1 | HOME = .
2 | RANDFILE = $ENV::HOME/.rnd
3 |
4 |
5 | ####################################################################
6 | [ req ]
7 | default_bits = 4096
8 | default_keyfile = privkey.pem
9 | distinguished_name = req_distinguished_name
10 | attributes = req_attributes
11 |
12 | [ req_distinguished_name ]
13 | countryName = Country Name (2 letter code)
14 | countryName_default = DE
15 | countryName_min = 2
16 | countryName_max = 2
17 |
18 | stateOrProvinceName = Province
19 | stateOrProvinceName_default = JWD
20 |
21 | localityName = City
22 | localityName_default = Karl Marx Stadt
23 |
24 | 0.organizationName = Organization
25 | 0.organizationName_default = crash users
26 |
27 | organizationalUnitName = Unit name
28 | organizationalUnitName_default = Steelworker
29 |
30 | commonName = Common Name
31 | commonName_default = noname
32 | commonName_max = 64
33 |
34 | emailAddress = Mail
35 | emailAddress_default = nomail
36 | emailAddress_max = 64
37 |
38 | [ req_attributes ]
39 | challengePassword = A challenge password
40 | challengePassword_min = 4
41 | challengePassword_max = 20
42 |
43 | unstructuredName = An optional company name
44 |
45 |
46 |
--------------------------------------------------------------------------------
/contrib/proxywars.md:
--------------------------------------------------------------------------------
1 | # WA / Telegram proxy setup
2 |
3 |
4 |
5 |
6 |
7 | How to get messenger connectivity if your Internet is dead in copland. This covers
8 | *Telegram* and *Whatsapp* messengers to connect from this **Inside** filtered network.
9 |
10 | ## Outside
11 |
12 | All methods described here require a VPS or server instance running **Outside** the censored network.
13 | In the ideal case this has been setup before blocking rules were tightened. It may also require
14 | help from Outside by volunteers. If only the target IP space of your messenger provider, e.g.
15 | the Meta network is blocked, you can directly jump to the `Proxy setup` section. If there is
16 | more blocking, the next sections describe techniques to bypass these.
17 |
18 | ## TCP blocking
19 |
20 | If just outgoing TCP connections are blocked, try using `-D` for DTLS that runs on UDP. You can also
21 | try reverse connect by *crash* server from outside into the censored network by setting up cron scripts
22 | or similar on the VPS that periodically connects to you. This is the case that works for Iran.
23 |
24 | ## SNI blocking
25 |
26 | Some censorship white-list connections to regime websites by checking the SNI of the outgoing
27 | connection. You can use [sniprobe](https://github.com/c-skills/sniprobe) to find out which.
28 | Then you can try connecting to your VPS by setting up your instances and using `-S` with that SNI.
29 |
30 | You can go one step further as to setup a regime friendly website that praises the leader to
31 | fool them to have connections from Inside allowed to this outside host. On this innocent looking
32 | website you run a SNI proxy such as [sshttp](https://github.com/stealth/sshttp) that multiplexes
33 | another SNI of your choice to a *crash* instance running behind the https port of that website.
34 | Censorship equipment sees all connections looking like a https session to a pro regime website.
35 |
36 | You can read more on the SNI case by [our THC friends](https://blog.thc.org/the-iran-firewall-a-preliminary-report).
37 |
38 | ## ICMP or DNS tunneling
39 |
40 | If nothing of above works, you may try to resolve DNS or ping your VPS. If that works, you can setup
41 | a ICMP or DNS tunnel via [fraud-bridge](https://github.com/stealth/fraud-bridge). You can reach
42 | your VPS via `1.2.3.5` then.
43 |
44 |
45 | # Proxy setup
46 |
47 | ## Whatsapp
48 |
49 | There is an [official WA docu](https://github.com/WhatsApp/proxy) that uses a bit overblown docker setup with `haproxy`.
50 | To boil it down - if you read all the configs - the messenger app is just expecting a simple port forward from the proxy
51 | to `g.whatsapp.net:5222`. Meta seems to use DNS based load balancing so you may get different addresses
52 | than me, but for me it resolves to `185.60.217.54` or `2a03:2880:f276:d0:face:b00c:0:7260` in IPv6 case.
53 | Thats for the `Chat port`. For `Media port` they are using `mmg.whatsapp.net:443` which resolves to
54 | `57.144.111.32` or `2a03:2880:f32e:122:face:b00c:0:167`.
55 |
56 | Given that you manage to establish a connection to your VPS in the steps before, you do:
57 |
58 | ```
59 | $ crashc -X 192.168.0.123 -S yourSNI -D -H $VPS -T 1235:[185.60.217.54]:5222 \
60 | -T 1236:[57.144.111.32]:443 -l user -i authkey.priv -v
61 | ```
62 |
63 | or
64 |
65 | ```
66 | $ crashc -X 192.168.0.123 -S yourSNI -D -H $VPS -T 1235:[2a03:2880:f276:d0:face:b00c:0:7260]:5222 \
67 | -T 1236:[2a03:2880:f32e:122:face:b00c:0:167]:443 -l user -i authkey.priv -v
68 |
69 | ```
70 |
71 | (using DTLS in this example and WA's IPv6 endpoint in the 2nd case)
72 |
73 | In your WA messenger, go to `Settings` -> `Storage and data` -> `Proxy settings` and set it to:
74 |
75 | * Proxy host: `192.168.0.123`
76 | * Chat port: `1235` and leave the `Use TLS` box unchecked. No worries - you will still get encrypted comms.
77 | * Media port: `1236`
78 |
79 | It assumes that your phone is connected via Wifi and using the same `192.168.0.0` network
80 | as your *crashc* session which runs on the machine that has a LAN (wired or Wifi) IP of `192.168.0.123`.
81 |
82 | ## Telegram
83 |
84 | With *Telegram* it is similar as easy. Will just use
85 |
86 | ```
87 | $ crashc -X 192.168.0.123 -S yourSNI -D -H $VPS -5 1235 -l user -i authkey.priv -v
88 | ```
89 |
90 | To setup a SOCKS5 proxy and configure it in the app as `Settings` -> `Data and Storage` -> `Proxy Settings` -> `Add Proxy`
91 | as SOCKS5 with `192.168.0.123` and port `1235`.
92 |
93 | ## Signal
94 |
95 | There is a [docu for Signal](https://github.com/signalapp/Signal-TLS-Proxy), using `nginx`.
96 |
97 | Unfortunately *Signal* is using TLS-in-TLS tunneling with SNI proxying in the inner tunnel which
98 | requires sort of more complex setup that can't be handled by *crash* alone.
99 |
100 | ## DNS
101 |
102 | If DNS is blocked or filtered, you can forward DNS lookups via `-X 192.168.0.123 -U 53:[8.8.8.8]:53`
103 | and configure `192.168.0.123` as your DNS resolver. It requires to run *crashc* as root, since it needs
104 | to bind to the privileged port 53. DNS forwarding is usually not needed for the messenger proxy case,
105 | since the proxy is configured as an IP address. Sometimes though, external resources need to be accessed/resolved.
106 |
107 | ## Public Access
108 |
109 | If you are a volunteer from Outside and want to donate public *crash* endpoints on your VPS without actually
110 | giving shell access to strangers, you can setup a dedicated user and set his shell to `/bin/cat` (manually
111 | editing `/etc/passwd` or via `chsh` but in this case you need to add `/bin/cat` to `/etc/shells`).
112 |
113 | You can then setup the *crash* keys as normal and distribute them to people Inside and asking them
114 | at which IP they want to have your active *crashd* connections terminated if they can't connect themselfes to
115 | Outside, or tell them how they can connect to your VPS.
116 |
117 | To avoid abuse, you might want to apply firewalling rules of that country's netrange and also filter outgoing
118 | connections to be only possible to the messenger service' networks/ports.
119 |
120 |
--------------------------------------------------------------------------------
/contrib/pw.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stealth/crash/338cc70f445997e2c408d6ae8ee0543fa1d8f6e3/contrib/pw.jpg
--------------------------------------------------------------------------------
/logo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stealth/crash/338cc70f445997e2c408d6ae8ee0543fa1d8f6e3/logo.jpg
--------------------------------------------------------------------------------
/src/Makefile:
--------------------------------------------------------------------------------
1 | #
2 | #
3 | #
4 |
5 |
6 | INC=
7 | LIBS=
8 | CXXFLAGS=
9 | DEFS=-DTITLE="\"[kthreadd]\""
10 |
11 | POSIX=-D_POSIX_C_SOURCE=200112L -D_XOPEN_SOURCE=600
12 |
13 | # comment in if you want to have server and client support TLS 1.2 in order
14 | # to use aged systems that have no TLS 1.3 libcrypto support, which is otherwise
15 | # the minimum TLS version
16 | #DEFS+=-DTLS_COMPAT_DOWNGRADE
17 |
18 | # Do not enable. !For debugging only!
19 | # -DUSE_CCIPHERS="\"NULL@SECLEVEL=0\"" -DUSE_SCIPHERS="\"NULL@SECLEVEL=0\""
20 |
21 | # comment out if you want DTLSv1_listen() "DoS protection" for OpenSSL-3 or LibreSSL-3
22 | # do not comment out if you want suspend/resume
23 | DEFS+=-DNO_DTLS_LISTEN
24 |
25 | # enable experimental QUIC transport
26 | #DEFS+=-DHAVE_QUIC
27 |
28 | #SSL=/opt/ssl/openssl-3.5.0-beta1
29 |
30 | ifeq ($(shell uname), Linux)
31 | LIBS+=-lssl -lcrypto -Wl,--rpath=$(SSL)/lib -Wl,--rpath=$(SSL)/lib64
32 | DEFS+=-DHAVE_UNIX98
33 | DEFS+=$(POSIX)
34 | else ifeq ($(shell uname), Solaris)
35 | LIBS+=-lssl -lcrypto -lsocket -lnsl
36 | else ifeq ($(shell uname), Darwin)
37 | SSL=/usr/local/opt/openssl\@1.1
38 | LIBS+=-lssl -lcrypto
39 | DEFS+=-DHAVE_UNIX98
40 | else ifeq ($(shell uname), OpenBSD)
41 | LIBS+=-lssl -lcrypto -lutil
42 | else ifeq ($(shell uname), NetBSD)
43 | LIBS+=-lssl -lcrypto -lutil
44 | else ifeq ($(shell uname), FreeBSD)
45 | LIBS+=-lssl -lcrypto -lutil
46 | # Cygwin
47 | else
48 | LIBS+=-lssl -lcrypto -lutil
49 | DEFS+=$(POSIX)
50 | endif
51 |
52 |
53 | CXX?=c++
54 | CXXSTD?=c++11
55 | INC+=-I$(SSL)/include
56 | CXXFLAGS+=-Wall -O2 -std=$(CXXSTD) -pedantic $(INC) $(DEFS)
57 |
58 | LIBS+=-L$(SSL)/lib -L$(SSL)/lib64
59 | LDFLAGS=-lpthread
60 | LD=$(CXX)
61 | STRIP=strip
62 |
63 | CNF=../contrib/openssl.cnf
64 |
65 | all: crashd crashc
66 |
67 | clean:
68 | rm -rf *.o
69 |
70 | keys:
71 | umask 066
72 | @echo "***** Generating Keys ****"
73 | @echo
74 | @echo "Whatever you enter for Country/Organization etc is not important (press enter)."
75 | @echo "Just the passphrase is important"
76 | @echo
77 | @echo "**************************"
78 | sleep 3
79 | OPENSSL_CONF=$(CNF) openssl genrsa -out serverkey.priv 4096
80 | OPENSSL_CONF=$(CNF) openssl req -new -x509 -nodes -sha1 -key serverkey.priv -out serverkey.pub
81 | OPENSSL_CONF=$(CNF) openssl x509 -in serverkey.pub -pubkey -noout > HK_127.0.0.1
82 | OPENSSL_CONF=$(CNF) openssl genrsa -out authkey.priv -aes256 4096
83 | OPENSSL_CONF=$(CNF) openssl rsa -in authkey.priv -pubout -out authkey.pub
84 | @echo
85 | @echo
86 | @echo "Your serverkey is in serverkey.{priv,pub} and authentication (user-) key in"
87 | @echo "authkey.{priv,pub}. Copy authkey.pub to ~/.crash/authorized_keys on remote"
88 | @echo "server and use '-i authkey.priv' on the client to connect to it"
89 | @echo
90 | @echo "Your known-host key which belongs to serverkey.priv is in HK_127.0.0.1"
91 | @echo "and you can use it with '-K HK_127.0.0.1' on the client (127.0.0.1 as example)"
92 | @echo
93 | @echo "For example you can start './crashd' as root on localhost and use"
94 | @echo "'./crashc -K ./HK_127.0.0.1 -H 127.0.0.1 -l user -i authkey.priv'"
95 | @echo "to login."
96 | @echo
97 |
98 | crashc: net.o misc.o crashc.o config.o session.o csession.o global.o missing.o
99 | $(LD) net.o misc.o crashc.o config.o pty.o global.o pty98.o session.o csession.o missing.o $(LIBS) $(LDFLAGS) -o crashc
100 | $(STRIP) crashc
101 |
102 | crashd: server.o session.o ssession.o net.o misc.o crashd.o config.o pty.o pty98.o global.o log.o dh.o iobox.o missing.o disguise.o
103 | $(LD) server.o session.o ssession.o net.o misc.o crashd.o config.o pty.o pty98.o global.o log.o dh.o iobox.o missing.o disguise.o $(LIBS) $(LDFLAGS) -o crashd
104 | $(STRIP) crashd
105 |
106 | missing.o: missing.cc
107 | $(CXX) $(CXXFLAGS) -c missing.cc
108 |
109 | iobox.o: iobox.cc
110 | $(CXX) $(CXXFLAGS) -c iobox.cc
111 |
112 | disguise.o: disguise.cc
113 | $(CXX) $(CXXFLAGS) -c disguise.cc
114 |
115 | server.o: server.cc
116 | $(CXX) $(CXXFLAGS) -c server.cc
117 |
118 | session.o: session.cc
119 | $(CXX) $(CXXFLAGS) -c session.cc
120 |
121 | ssession.o: ssession.cc
122 | $(CXX) $(CXXFLAGS) -c ssession.cc
123 |
124 | csession.o: csession.cc
125 | $(CXX) $(CXXFLAGS) -c csession.cc
126 |
127 | net.o: net.cc
128 | $(CXX) $(CXXFLAGS) -c net.cc
129 |
130 | misc.o: misc.cc
131 | $(CXX) $(CXXFLAGS) -c misc.cc
132 |
133 | config.o: config.cc
134 | $(CXX) $(CXXFLAGS) -c config.cc
135 |
136 | pty.o: pty.cc
137 | $(CXX) $(CXXFLAGS) -c pty.cc
138 |
139 | pty98.o: pty98.cc
140 | $(CXX) $(CXXFLAGS) -c pty98.cc
141 |
142 | global.o: global.cc
143 | $(CXX) $(CXXFLAGS) -c global.cc
144 |
145 | log.o: log.cc
146 | $(CXX) $(CXXFLAGS) -c log.cc
147 |
148 | crashd.o: crashd.cc
149 | $(CXX) $(CXXFLAGS) -c crashd.cc
150 |
151 | crashc.o: crashc.cc
152 | $(CXX) $(CXXFLAGS) -c crashc.cc
153 |
154 | dh.o: dh.cc dh2048.cc
155 | $(CXX) $(CXXFLAGS) -c dh.cc
156 |
157 |
--------------------------------------------------------------------------------
/src/Makefile.android:
--------------------------------------------------------------------------------
1 | # setup your build environment to build for Android:
2 | # 1. Install NDK and clone boringssl git
3 | # 2. inside boringssl git, checkout the android version that you are using on your phone
4 | # 3. set path to your NDK and SSL path you are using as well as your $PLATFORM
5 | # 4. copy phones or emulators libssl.so and libcrypto.so to .
6 |
7 | PLATFORM=android-24
8 | NDK=/opt/android-ndk
9 |
10 | SSL=/tmp/boringssl
11 |
12 | PREFIX=$(NDK)/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-
13 | SYSROOT=--sysroot=$(NDK)/platforms/$(PLATFORM)/arch-arm
14 | SYSROOT+=-isysroot $(NDK)/sysroot
15 |
16 | INC=-isystem $(NDK)/sysroot/usr/include/arm-linux-androideabi\
17 | -I$(NDK)/sources/cxx-stl/gnu-libstdc++/include\
18 | -I$(NDK)/sources/cxx-stl/gnu-libstdc++/4.9/include/\
19 | -I$(NDK)/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi-v7a/include\
20 | -I$(SSL)/include
21 |
22 | LIB=-Wl,$(NDK)/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi-v7a/libgnustl_static.a
23 | LIB+=-L . -lssl -lcrypto
24 |
25 | DEFS=-DANDROID
26 |
27 | CXX=$(PREFIX)gcc -fPIC -O2 -Wall -pedantic -std=c++11 $(SYSROOT) $(INC) $(DEFS)
28 | LD=$(PREFIX)gcc -pie $(SYSROOT)
29 |
30 | STRIP=$(PREFIX)strip
31 |
32 |
33 | all: crashd crashc
34 |
35 | clean:
36 | rm -rf *.o
37 |
38 | crashc: net.o misc.o crashc.o config.o global.o
39 | $(LD) net.o misc.o crashc.o config.o pty.o global.o pty98.o $(LIB) -o crashc
40 | $(STRIP) crashc
41 |
42 | crashd: server.o session.o net.o misc.o crashd.o config.o pty.o pty98.o global.o log.o dh.o iobox.o
43 | $(LD) server.o session.o net.o misc.o crashd.o config.o pty.o pty98.o global.o log.o dh.o iobox.o $(LIB) -o crashd
44 | $(STRIP) crashd
45 |
46 | iobox.o: iobox.cc
47 | $(CXX) $(CXXFLAGS) -c iobox.cc
48 |
49 | server.o: server.cc
50 | $(CXX) $(CXXFLAGS) -c server.cc
51 |
52 | session.o: session.cc
53 | $(CXX) $(CXXFLAGS) -c session.cc
54 |
55 | net.o: net.cc
56 | $(CXX) $(CXXFLAGS) -c net.cc
57 |
58 | misc.o: misc.cc
59 | $(CXX) $(CXXFLAGS) -c misc.cc
60 |
61 | config.o: config.cc
62 | $(CXX) $(CXXFLAGS) -c config.cc
63 |
64 | pty.o: pty.cc
65 | $(CXX) $(CXXFLAGS) -c pty.cc
66 |
67 | pty98.o: pty98.cc
68 | $(CXX) $(CXXFLAGS) -c pty98.cc
69 |
70 | global.o: global.cc
71 | $(CXX) $(CXXFLAGS) -c global.cc
72 |
73 | log.o: log.cc
74 | $(CXX) $(CXXFLAGS) -c log.cc
75 |
76 | crashd.o: crashd.cc
77 | $(CXX) $(CXXFLAGS) -c crashd.cc
78 |
79 | crashc.o: crashc.cc
80 | $(CXX) $(CXXFLAGS) -c crashc.cc
81 |
82 | dh.o: dh.cc dh2048.cc
83 | $(CXX) $(CXXFLAGS) -c dh.cc
84 |
85 |
--------------------------------------------------------------------------------
/src/Makefile.android.aarch64:
--------------------------------------------------------------------------------
1 | #
2 | # setup your build environment to build for Android:
3 | # 1. Install NDK and clone boringssl git
4 | # 2. inside boringssl git, checkout the android version that you are using on your phone
5 | # 3. set path to your NDK and SSL path you are using as well as your $PLATFORM
6 | # 4. copy phones or emulators libssl.so and libcrypto.so to .
7 |
8 | PLATFORM=android-24
9 | NDK=/opt/android-ndk
10 |
11 | SSL=/tmp/boringssl
12 |
13 | PREFIX=$(NDK)/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-
14 | SYSROOT=--sysroot=$(NDK)/platforms/$(PLATFORM)/arch-arm64/
15 | SYSROOT+=-isysroot $(NDK)/sysroot
16 |
17 | INC=-isystem $(NDK)/sysroot/usr/include/aarch64-linux-android\
18 | -I$(NDK)/sources/cxx-stl/gnu-libstdc++/include\
19 | -I$(NDK)/sources/cxx-stl/gnu-libstdc++/4.9/include/\
20 | -I$(NDK)/sources/cxx-stl/gnu-libstdc++/4.9/libs/arm64-v8a/include\
21 | -I$(SSL)/include
22 |
23 | LIB=-Wl,$(ROOT)/$(NDK)/sources/cxx-stl/gnu-libstdc++/4.9/libs/arm64-v8a/libgnustl_static.a
24 | LIB+=-L . -lssl -lcrypto
25 |
26 | DEFS=-DANDROID
27 |
28 | CXX=$(PREFIX)gcc -fPIC -O2 -Wall -pedantic -std=c++11 $(SYSROOT) $(INC) $(DEFS)
29 | LD=$(PREFIX)gcc -pie $(SYSROOT)
30 |
31 | STRIP=$(PREFIX)strip
32 |
33 |
34 | all: crashd crashc
35 |
36 | clean:
37 | rm -rf *.o
38 |
39 | crashc: net.o misc.o crashc.o config.o global.o
40 | $(LD) net.o misc.o crashc.o config.o pty.o global.o pty98.o $(LIB) -o crashc
41 | $(STRIP) crashc
42 |
43 | crashd: server.o session.o net.o misc.o crashd.o config.o pty.o pty98.o global.o log.o dh.o iobox.o
44 | $(LD) server.o session.o net.o misc.o crashd.o config.o pty.o pty98.o global.o log.o dh.o iobox.o $(LIB) -o crashd
45 | $(STRIP) crashd
46 |
47 | iobox.o: iobox.cc
48 | $(CXX) $(CXXFLAGS) -c iobox.cc
49 |
50 | server.o: server.cc
51 | $(CXX) $(CXXFLAGS) -c server.cc
52 |
53 | session.o: session.cc
54 | $(CXX) $(CXXFLAGS) -c session.cc
55 |
56 | net.o: net.cc
57 | $(CXX) $(CXXFLAGS) -c net.cc
58 |
59 | misc.o: misc.cc
60 | $(CXX) $(CXXFLAGS) -c misc.cc
61 |
62 | config.o: config.cc
63 | $(CXX) $(CXXFLAGS) -c config.cc
64 |
65 | pty.o: pty.cc
66 | $(CXX) $(CXXFLAGS) -c pty.cc
67 |
68 | pty98.o: pty98.cc
69 | $(CXX) $(CXXFLAGS) -c pty98.cc
70 |
71 | global.o: global.cc
72 | $(CXX) $(CXXFLAGS) -c global.cc
73 |
74 | log.o: log.cc
75 | $(CXX) $(CXXFLAGS) -c log.cc
76 |
77 | crashd.o: crashd.cc
78 | $(CXX) $(CXXFLAGS) -c crashd.cc
79 |
80 | crashc.o: crashc.cc
81 | $(CXX) $(CXXFLAGS) -c crashc.cc
82 |
83 | dh.o: dh.cc dh2048.cc
84 | $(CXX) $(CXXFLAGS) -c dh.cc
85 |
86 |
--------------------------------------------------------------------------------
/src/config.cc:
--------------------------------------------------------------------------------
1 | #include