0

I have a Java App running, which prints out messages into STDOUT and also has an active interactive console (also accepts STDIN), when the server has started up.

How do I securely give access to an external person (outside the network) to the console and nothing else?

I was figuring using ncat --ssl -e java filenamehere

And setting a firewall rule for the port used to only allow packets from one origin:

iptables -I INPUT \! --src 1.2.3.4 -m tcp -p tcp --dport 777 -j DROP # if it's not 1.2.3.4, drop it

But is that secure?

In theory, IP spoofing can be used or are modern mitigation methods built into the OS? I tried setting nospoof on in the host.conf file but it seems that it's obsolete.

I was thinking of giving reverse-shell but that probably is a bit too much and insecure in my opinion. What is your opinion?

schroeder
  • 123,438
  • 55
  • 284
  • 319
Sir Muffington
  • 1,447
  • 2
  • 9
  • 22
  • IP spoofing can be used to send packets, but it will not work to receive packets or complete a handshake ... – schroeder May 17 '20 at 12:45
  • `host.conf` doesn't apply ... – schroeder May 17 '20 at 12:48
  • why do you think reverse shell is insecure? – schroeder May 17 '20 at 12:49
  • Authentication is the way to provide connections and ensure that only authorised users can connect... Network-level controls have limitations. IP whitelisting suffers from the problem of IPs changing. – schroeder May 17 '20 at 12:50
  • @schroeder so IP spoofing can't be used to do a TLS handshake? I think reverse shell is insecure because arbitrary code could get executed on the server. How do I provide authentication then? Maybe something along the lines of nginx proxy basic auth, but then I would need to host it as a web page.. – Sir Muffington May 17 '20 at 12:58
  • no, you cannot complete a handshake when spoofing - how on earth can you get the server response? – schroeder May 17 '20 at 13:18
  • or add authentication to your app ... – schroeder May 17 '20 at 13:19
  • There are lots of proxy options that do not require that the target be a webpage. – schroeder May 17 '20 at 13:20
  • I am apparently not that experienced with using nginx as a proxy or any proxy at all. Could you give me a reference on how to do that? AFAIK, the user would still need to put up the browser for auth. Perfectly, it would be better off without a browser. – Sir Muffington May 17 '20 at 13:34

1 Answers1

1

Since IP addresses really aren't suitable for authentication, you should implement something else to do the job. A simple example in your scenario would be to write a wrapper script (executed by netcat or socat) that prompts for credentials. If the credentials are correct, it can then exec your Java program. This could be done in a few lines with a Bash script, e.g.:

#!/bin/bash

CORRECT_PASSWORD='h7a0&7;ngIl1+'
MYPROG="java filenamehere"
echo -n "Enter password: "
read -s pass

if [[ "$pass" == "$CORRECT_PASSWORD" ]]; then
    exec "$MYPROG"
else 
    echo Password incorrect
fi

You could run this in an endless loop with:

socat openssl-l:1234,reuseaddr,fork,certificate=cert.pem,keyfile=key.pem exec:/usr/local/bin/myscript

You do not need to worry about IP spoofing when using TCP in most cases, so whitelisting allowed addresses can be part of a defense-in-depth solution for your application.

Now, this is all assuming you fully trust the other person to use your application and your application is otherwise sufficiently locked down.

multithr3at3d
  • 12,355
  • 3
  • 29
  • 42
  • The problem is that the bash script running the app is a bit complicated and includes restart functionality (if the server crashes), backups etc. Also, could you explain the architecture a bit more? I am a bit confused about it. Could you give an example in bash then? – Sir Muffington May 17 '20 at 15:49
  • Maybe executing my script with auth included (not sure how I do that with bash maybe with expect?) with websocketd is a good solution? – Sir Muffington May 17 '20 at 15:51
  • @SirMuffington not sure what existing script you are talking about, but I added a very simple example – multithr3at3d May 17 '20 at 18:17
  • I guess I can exec the script instead of directly executing `java etc`. The script contains the `java filename parameters etc` in a bash function. It would also be awesome if you could explain the socat comma-separated parameters. – Sir Muffington May 17 '20 at 19:39
  • Also, does socat work across the internet? – Sir Muffington May 17 '20 at 19:41
  • @SirMuffington there are a lot of options, so I'd suggest viewing the manpage. But, fork will keep the socket running and fork off your program each time a connection is made, reuseaddr is a socket option that effectively makes it quicker to restart, the rest of the options point to cert & keys for TLS. The second part with exec that script every time it's connected to – multithr3at3d May 17 '20 at 19:56
  • @SirMuffington yes, barring any firewalls, it is reachable like any network daemon – multithr3at3d May 17 '20 at 19:56
  • Thank you. One question does remain though: how do you connect to this interface? – Sir Muffington May 17 '20 at 21:39
  • @SirMuffington same way you'd connect to a netcat listener; netcat is one way to do it – multithr3at3d May 18 '20 at 14:00
  • Isn't the bash script vulnerable to side-channel attacks (timing attack to be precise)? – Sir Muffington May 18 '20 at 20:01
  • @SirMuffington what makes you say that? – multithr3at3d May 18 '20 at 22:02
  • Doesn't bash have different timing according to the amount of correctly or incorrectly typed in characters? – Sir Muffington May 18 '20 at 22:43
  • @SirMuffington interesting, haven't heard of that. You could always hash and compare against a hashed password instead. – multithr3at3d May 18 '20 at 23:23
  • I'm guessing the hashing has to be async as well for it to be not vulnerable against timing attacks. Which doesn't truly exist in Bash AFAIK... or does adding a & at the end of the command make it async and safe enough? – Sir Muffington May 19 '20 at 07:51