[Swan] Authentication with pam_url and nonces

Mirsad Goran Todorovac mirsad.todorovac at alu.unizg.hr
Mon Feb 7 09:58:57 EET 2022


Hi Paul,

On 7.2.2022. 1:56, Paul Wouters wrote:
> On Sun, 6 Feb 2022, Mirsad Goran Todorovac wrote:
>
>> The passwordless authentication over pam_url used with IKEv2 with the 
>> certificates was considered
>> a source of brute force attacks and a dangerous module to implement 
>> for it could allow everyone to
>> access the system if accidentally left as the only and sufficient 
>> module in PAM stack.
>
> You can't really brute force the certificate validation part.
>
> The pam module is just an _additional_ restriction that can restrict an
> otherwise validated certificate. It is never even called for invalid,
> bad or revoked certificates as the connection is rejected before the pam
> phase due to the failed verification.
Yes. Agreed. But: if TLS is somehow compromised (i.e. by a quantum 
computer attack), I would still want
to be able to authenticate safely. Or as safe as my hash function 
(currently being SHA-256, but nothing
prevents using a stronger one ...).

I try this by sending message digest:

H(str) = sha256sum(str);
N = H(rnd);
HMAC = H( N || username || password || clientIP || secret || N);
retHMAC = H( N || secret || N);

So, the authorization script MUST prove knowledge of the secret and my 
nonce N as a challenge
by sending retHMAC which I check.

It can only do so if knowing the nonce of the session N and the 
pre-shared secret.

The key is to generate unique nonce. I do so like this:

char *get_random_string (void)
{
         static bool _first_run = true;
         struct timespec tv, tv2;
         static struct drand48_data buffer;
         double result, result2;
         char *randomstr = NULL;

         if (clock_gettime (CLOCK_MONOTONIC, &tv) == -1)
                 return NULL;

         if (clock_gettime (CLOCK_PROCESS_CPUTIME_ID, &tv2) == -1)
                 return NULL;

         if (_first_run) {
                 _first_run = false;
                 srand48_r (tv2.tv_nsec, &buffer);
         }
         drand48_r (&buffer, &result);
         drand48_r (&buffer, &result2);
         int ret = asprintf (&randomstr, "%lf%ld%ld%ld%ld%d%lf",
                                 result, tv.tv_sec, tv.tv_nsec,
                                 tv2.tv_sec, tv2.tv_nsec, getpid(), 
result2);
         if (ret == -1)
                 return NULL;
         char * hashstr = sha256_string (randomstr);
         free (randomstr);
         return hashstr;
}

So, I am not sure that I get enough randomness i.e. if the PAM module is 
(theoretically) called for the
second time within the same nanosecond (or time resolution interval of 
the clock, which can be of lesser
quality!).

>> So, the main question appears to be if there is a smarter way of 
>> preventing brute force replay attacks
>
> IKE has build-in protection against replay attacks. Both sides you a
> nonce for different connection attempts. So it is always different and
> there is no replaying possible.
Indeed, but I do not authenticate the second stage pam_url over IKE, but 
over TLS connection instead
to a CGI-bin module. In particular, this module is vulnerable to brute 
force attacks. I defend my system
by limiting to IP address, but that is easily defeated. So I thought of 
knowing a common secret like RADIUS
protocol.

In particular, I did not want to send the secret in cleartext even over 
TLS connection, as i.e. private key
might have been compromised or brute force cracked by a quantum computer 
by yet undocumented
man-in-the-middle attack.

I defend against these like this:

$ip_address = $_SERVER['REMOTE_ADDR'];
$ip_srv_address = $_SERVER['SERVER_ADDR'];

if ( $ip_address !== $ip_srv_address )
{
         header("HTTP/1.1 403 Forbidden");
         echo "HOST NOT PERMITTED";
         exit(0);
}
else if( isset($_POST["user"]) && isset($_POST["pass"]) && 
isset($_POST["mode"]) )
{
         $ret=-1;

         $nonce = $_POST["nonce"];
         $sha256 = $_POST["hash"];
         if (($rawsecret = 
file_get_contents("/usr/local/etc/myauth/secret")) !== false) {
                 $secret = trim($rawsecret);
                 $mysha256 = hash("sha256", $nonce . $_POST["user"] . 
$_POST["pass"] . \
                                            $_POST["mode"] . 
$_POST["clientIP"] . $secret . $nonce);
                 if ($sha256 !== $mysha256) {
                         $secret = "";
                         $ret = 401;
                 } else {
                         $rethash = hash("sha256", $nonce . $secret . 
$nonce);
                         $secret = "";
                         $ret = 0;
                 }
         } else {
                 $ret = 402;
         }

         if ( $ret == 0 )
         switch($_POST["mode"])
         {
                 case "PAM_SM_AUTH";
                         // Perform authing here
                 case "PAM_SM_ACCOUNT";
                         // Perform account aging here

// .... the authorization code for the certificate ....

So, I wonder how to generate unique-enough nonce, so my authorization 
process is safe.
(Safe as SHA256(str) hash at most.)

In case of broken or compromised TLS, nothing prevents the adversary to 
record nonce and
SHA256 hash and reuse them. I defend against this by using rethash, 
which is a proof that the
authorization service is in possession of the nonce for this session 
(which must not be reused),
and in possession of the secret key (which we hope the adversary had not 
learned, for it is
never transmitted in clear like in PAP.

I thought of maintaining some serial or sequence number for the 
authorization process which
would also be protected by the SHA256 hash, incremented and never 
repeated, but I still
haven't thought of a good implementation of this feature.

I hope this explains.

I know about sequence numbers in IKE as the protection from the replay 
attacks (I don't know
this in detail though), but let me remind you that pam_url doesn't 
authenticate over IKE nor
IPsec, so if we do not trust TLS, completely we open a host of issues ...

Kind regards,
Mirsad

-- 
Mirsad Todorovac
CARNet system engineer
Faculty of Graphic Arts | Academy of Fine Arts
University of Zagreb
Republic of Croatia, the European Union
--
CARNet sistem inženjer
Grafički fakultet | Akademija likovnih umjetnosti
Sveučilište u Zagrebu



More information about the Swan mailing list