On 20/12/12 19:49, Paul Robert Marino wrote:
> Its base64 with DIGEST-MD5 hashing with no salt.
> If you don't beleave me just decode it through any base64 tool and you
> will see the entire conversation
> And if you still don't beleave me read the RFC that describes SASL its
> very clearly explained and a relativly short read as RFCs go.
I've read through RFC2831 [1] more times now, which describes the
DIGEST-MD5 protocol pretty well. And there are some details there,
which libvirt user and which makes it impossible to use any base64 tool
to extract the password, as you claim.
First, this is the dialogue I captured between client and server:
S: DIGEST-MD5
C: DIGEST-MD5
S: nonce="2VE5+WoJF+WSOHai6UpvyPUyjPV3TVdU//x25Bivx/w=",
realm="virtsrv1.local",
qop="auth-conf",cipher="rc4-56,rc4,3des",
maxbuf=65536,charset=utf-8,
algorithm=md5-sess
C: username="vmadmin",realm="virtsrv1.local",
nonce="2VE5+WoJF+WSOHai6UpvyPUyjPV3TVdU//x25Bivx/w=",
cnonce="3G5mp5dUDXKs6Z/D9pvMLHMk177+Y20DNWfXoK0iscc=",nc=00000001,
qop=auth-conf,cipher=rc4,
maxbuf=65536,
digest-uri="libvirt/172.16.21.10",
response=145b633fe038af33327d720bdb9111b0
S: rspauth=d0c38ff1236b11aa22966cafc78d67f8
This matches very well the protocol described in RFC2831. And there are
a few things to notice here.
a) qop-options
From the RFC:
"A quoted string of one or more tokens indicating the "quality of
protection" values supported by the server. The value "auth"
indicates authentication; the value "auth-int" indicates
authentication with integrity protection; the value "auth-conf"
indicates authentication with integrity protection and encryption.
This directive is optional; if not present it defaults to "auth".
The client MUST ignore unrecognized options; if the client
recognizes no option, it should abort the authentication
exchange."
The server and clients both sends: qop="auth-conf"
b) cipher-opts
From the RFC
"A list of ciphers that the server supports. This directive must be
present exactly once if "auth-conf" is offered in the
"qop-options" directive, in which case the "3des" and "des" modes
are mandatory-to-implement. The client MUST ignore unrecognized
options; if the client recognizes no option, it should abort the
authentication exchange."
The server sends cipher="rc4-56,rc4,3des" and the client responds
with cipher="rc4". Which means a 128 bit RC4 encryption was chosen.
c) response field from client
From the RFC:
"A string of 32 hex digits computed as defined below, which proves
that the user knows a password. This directive is required and
MUST be present exactly once; otherwise, authentication fails."
Further, when decoding the clients 'response', it is not
representing anything 'text readable'. You can try to base64 or hex
decode it. All you get is binary data.
This field is built up by hex-encoding a concatenation of several
fields, some which have been through a hashing round first.
The first step is to hash this string:
HASH1 = MD5($USERNAME:$REALM:$PASSWD)
And then this hash is concatenated and hashed once more like this:
HASH2 = MD5($HASH1:$NONCE:$CNONCE)
$NONCE is the nonce value from the server, and $CNONCE is the cnonce
value from the client. Both which are unique for this
authentication session. An MD5 hashing algorithm is used on this
string.
A second string is prepared as well, like this:
STR = MD5(AUTHENTICATE:$DIGESTURI:00000000000000000000000000000000)
The string 'AUTHENTICATE:' is added in front of $DIGESTURI which is
the same as the digest-uri from the client.
Then the final result is put together, using hex encoding of the
input data:
HEX( HEX($HASH2):$NONCE:$NCVALUE:$CNONCE:$QOP:HEX($STR) )
The $NONCE and $CNONCE are the same as in the previous step, but
the $NCVALUE is the nc field from the client and $QOP is the qop
field from the client.
In addition, as the client responded with 'cipher="rc4"', an
encryption performed as well, with the key based on parts of
$HASH2. But I will not go into the deep details here now.
So if you still claim that libvirt sends passwords in clear-text, just
BASE64 encoded, well, then I challenge you to expose the password in the
client/server dialogue pasted above. How I understand this, the
password has been hashed several times, with different "salts" (even
though not proper random salts). And it is being RC4 encrypted in
addition. I simply cannot find anything which looks like a BASE64
encoded password in neither the client/server dialogue nor the RFC -
when qop is set to 'auth-conf' and having 'cipher' set.
kind regards,
David Sommerseth
[1] RFC 2831 <http://www.ietf.org/rfc/rfc2831.txt>
> On Dec 20, 2012 10:16 AM, "David Sommerseth"
> <[log in to unmask]
> <mailto:[log in to unmask]>> wrote:
>
> On 19/12/12 23:45, Paul Robert Marino wrote:
> > this statement
> > " (I double checked the network traffic, and even though not using SSL
> > the password is not transferred over the network in clear-text)"
> > is wrong
> > It is clear text that has been base64 encoded unless you are using
> > gssapi with kerberos 5 or some other encrypted authentication
> > mechanism. you can mitigate this slightly by using the digest-md5 auth
> > but all you are doing then is sending the hash of the password in
> > clear text which isn't that much better
>
> I might be wrong, but I am quite confident that the data I see is
> encrypted. I've looked at the data via wireshark, and even though it
> looks like base64, it doesn't render my password.
>
> And looking further in the comments in /etc/libvirt/libvirtd.conf, there
> is this statement:
>
> # Using the TCP socket requires SASL authentication by default. Only
> # SASL mechanisms which support data encryption are allowed. This is
> # DIGEST_MD5 and GSSAPI (Kerberos5)
>
> And what I see, looks pretty much like digest-md5 with RC4 encryption.
> My libvirtd daemon tells this to my client:
>
> DIGEST-MD5 Dnonce="<BASE64_ecncoded_data>",
> realm="<DOMAIN>",qop="auth-conf",
> cipher="rc4-56,rc4,3des",
> maxbuf=65536,charset=utf-8,algorithm=md5-sess
>
> The client responds with this:
>
> DIGEST-MD5 Eusername="<USERNAME>",realm="<DOMAIN>",
> nonce="<BASE64_encoded_data>",
> cnonce="<BASE64_encoded_data_2>",
> nc=00000001,qop=auth-conf,cipher=rc4,maxbuf=65536,
> digest-uri="libvirt/1035110",
> response=1f4023d0417acb495ed187255ba80fcf
>
> And then the server responds with:
>
> rspauth=40922952d194910a08f3654b28d5485f
>
> After this response, it comes a data flow which looks more like normal
> data traffic.
>
> As far as I can interpret this, the data from the client is encrypted,
> using some shared data for a key exchange. But I haven't dug into the
> source code to verify this yet.
>
> If I'm wrong, then I need to learn more about the DIGEST-MD5 protocol.
>
>
> kind regards,
>
> David Sommerseth
>
>
> > On Wed, Dec 19, 2012 at 6:14 AM, David Sommerseth
> > <[log in to unmask]
> <mailto:[log in to unmask]>> wrote:
> >> On 19/12/12 04:38, Nico Kadel-Garcia wrote:
> >>> I'd love to be able to use sudo with virt-manager, but it simply
> >>> fails. It does work on Ubuntu, and I'd like to be able to use
> sudo for
> >>> all access to my KVM servers, rather than direct root login.
> >>>
> >>> Is anyone using sudo successfully with virt-manager on SL 6.3?
> Other X
> >>> applications work just fine.
> >>
> >> I do something similar to this, but slightly differently. I'm
> running
> >> virt-manager as my local user, but connecting to the TCP port,
> >> authenticating using the SASL feature. (I double checked the network
> >> traffic, and even though not using SSL the password is not
> transferred
> >> over the network in clear-text)
> >>
> >> * In /etc/libvirt/libvirtd.conf I set the following parameters:
> >>
> >> listen_tls=0
> >> listen_tcp=1
> >> listen_address=x.x.x.x # optional
> >> auth_tcp = "sasl"
> >>
> >>
> >> * Create the SASL database with the username/password I want to use
> >>
> >> Look up the "sasldb_path" in /etc/sasl2/libvirt.conf. In my setup
> >> it was set to /etc/libvirt/passwd.db. Then do:
> >>
> >> [root@host ~]# saslpasswd2 -f /etc/libvirt/passwd.db <USERNAME>
> >>
> >> The username can be completely virtual if you want.
> saslpasswd2 will
> >> ask for the wanted password. This username/password will only be
> >> used for libvirt.
> >>
> >> You can check the user database like this:
> >>
> >> [root@host ~]# sasldblistusers2 -f /etc/libvirt/passwd.db
> >>
> >>
> >> * Make libvirtd listen to TCP sockets
> >> Edit /etc/sysconfig/libvirtd so that LIBVIRTD_ARGS have
> "--listen" set
> >>
> >> F.ex:
> >> LIBVIRTD_ARGS="--listen"
> >>
> >>
> >> * Restart libvirtd
> >>
> >> [root@host ~]# service libvirtd restart
> >>
> >> If you want to connect to another IP than localhost, you also need to
> >> open up your firewall as well. But at this point, it should be
> possible
> >> to connect to libvirt over the network:
> >>
> >> [user@host ~]$ virsh -c qemu+tcp://localhost/system
> >> [user@host ~]$ virt-manager -c qemu+tcp://localhost/system
> >>
> >>
> >> I'm primarily using this approach to manage a couple of KVM hosts
> over a
> >> VPN connection, running virsh and virt-manager locally, connecting to
> >> the IP which is accessible over the VPN. Works pretty well, but
> I had
> >> to do some changes in the guest configs so that SPICE or VNC consoles
> >> also listened to an IP address available over the VPN. Changing
> these
> >> parameters requires cold-booting the virtual guests.
> >>
> >> I have tried to use SSL/TLS mode as well, but when managing more
> >> independent libvirt based servers, it gets quite annoying with
> how the
> >> client certificates needs to be configured. (Granted, it's a
> long time
> >> ago I tried it, so it might have changed) But I figured, as long
> as I
> >> use SASL and does this over VPN connections with strict
> firewalls, the
> >> setup is safe enough in my use cases.
> >>
> >>
> >> kind regards,
> >>
> >> David Sommerseth
>
|