The user-space iSCSI target daemon of the Linux target framework (tgt) uses an insecure random number generator to generate CHAP authentication callenges. This results in predictable challenges which an attacker capable of recording network traffic between iSCSI target and initiator can abuse to bypass CHAP authentication by replaying previous responses.
The Linux target framework (tgt) is a user space SCSI target framework that supports the iSCSI and iSER transport protocols and that supports multiple methods for accessing block storage. Tgt consists of user-space daemon and tools.
Source: https://github.com/fujita/tgt/blob/e393a80b02b8cb90709c75f9bd91542ea3a78d58/README.md
tgt
supports CHAP for authenticating initiators. As defined in the CHAP specification
the target generates a random challenge and sends it to the initiator. tgt
fails
to use a cryptographically secure random number generator for this. Instead it
simply uses the rand()
call without
setting a seed using srand()
first. Thus the default seed (equivalent to srand(1)
) will be used.
This results in a predictable sequence of numbers being returned by subsequent
calls to rand()
.
Note that even though tgt
generates a random length for each challenge,
this does not affect the predictability of challenges as these lengths will
also be generated using predictable output of rand()
.
static int chap_initiator_auth_create_challenge(struct iscsi_connection *conn)
{
char *value, *p;
char text[CHAP_CHALLENGE_MAX * 2 + 8];
static int chap_id;
int i;
[...]
/*
* FIXME: does a random challenge length provide any benefits security-
* wise, or should we rather always use the max. allowed length of
* 1024 for the (unencoded) challenge?
*/
conn->auth.chap.challenge_size = (rand() % (CHAP_CHALLENGE_MAX / 2)) + CHAP_CHALLENGE_MAX / 2;
conn->auth.chap.challenge = malloc(conn->auth.chap.challenge_size);
if (!conn->auth.chap.challenge)
return CHAP_TARGET_ERROR;
p = text;
strcpy(p, "0x");
p += 2;
for (i = 0; i < conn->auth.chap.challenge_size; i++) {
conn->auth.chap.challenge[i] = rand();
sprintf(p, "%.2hhx", conn->auth.chap.challenge[i]);
p += 2;
}
text_key_add(conn, "CHAP_C", text);
return 0;
}
Source: https://github.com/fujita/tgt/blob/v1.0.92/usr/iscsi/chap.c#L333
An attacker who is able to recording network traffic between iSCSI target and initiator can apply a replay attack to bypass the CHAP authentication. All the attacker has to do is wait for the server or the service to restart and replay with a previously record CHAP session which fits into the sequence.
Having bypassed CHAP authentication, an attacker has full user privileges and can modify the iSCSI target at will within that user privileges.
We recommend replacing the pseudo-random number generator (rand()
) with
getrandom()
as this will yield cryptographically secure pseudo-random numbers
fitting for CHAP challenges.
Version 1.0.93 contains this fix.
Publish date
07.09.2024
Category
security
Authors
Richard Weinberger
David Gstir
+43 5 9980 400 00 (email preferred)
sigma star gmbh
Eduard-Bodem-Gasse 6, 1st floor
6020 Innsbruck | Austria