Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NTLM support in Android #32680

Closed
steveisok opened this issue Feb 21, 2020 · 46 comments
Closed

NTLM support in Android #32680

steveisok opened this issue Feb 21, 2020 · 46 comments
Assignees
Labels
area-System.Net enhancement Product code improvement that does NOT require public API changes/additions os-android
Milestone

Comments

@steveisok
Copy link
Member

Some time ago in mono's corefx fork, we switched to SocketsHttpHandler and discovered that NTLM auth stopped working on Android. Originally, we thought it was just a configuration miss on our part, but it ended up turning out to be that kerberos is not available on Android and thus neither is libkrb-5.

We have been able to suggest a workaround by having customers use our old http handler, but w/ .NET 5 I believe we are going to need to work this out. I'm opening this issue to start a discussion / gather ideas.

@Dotnet-GitSync-Bot Dotnet-GitSync-Bot added the untriaged New issue has not been triaged by the area owner label Feb 21, 2020
@jkotas
Copy link
Member

jkotas commented Feb 22, 2020

What makes the NTLM auth work in the old http handler?

@am11
Copy link
Member

am11 commented Feb 22, 2020

Previously termux krb5 package was used from their main set to compile corefx: https://github.com/termux/termux-packages/tree/master/packages/krb5. Current android build scripts are little out of sync (mainly they haven't been modernized with others), but I think if termux is an option in your build process, that package should work.

@filipnavara
Copy link
Member

What makes the NTLM auth work in the old http handler?

If I had to guess it's the fact that MonoWebRequestHandler (the old handler) wraps HttpWebRequest. On Mono the implementation of HttpWebRequest is totally different from the CoreFX one and it implements NTLM in managed code. The NTLM implementation is limited to password-based credentials but it's still better than nothing.

@karelz karelz added os-android runtime-mono specific to the Mono runtime labels Feb 24, 2020
@marek-safar marek-safar changed the title Discussion: Libkrb-5 is not supported on Android Libkrb-5 is required for Android support of NTLM Feb 26, 2020
@marek-safar marek-safar removed the runtime-mono specific to the Mono runtime label Feb 26, 2020
@marek-safar
Copy link
Contributor

marek-safar commented Feb 26, 2020

@karelz we need a decision on how we can support NTLM on Android. The proposed solution is to include a fork of krb5 package in dotnet/ org so we can reference it as part of dotnet/runtime build and package it for Android where this library is not available. Is this something your team can take on or do you have another idea?

@am11
Copy link
Member

am11 commented Feb 26, 2020

re: libkrb5 - took this as a motivation and renewed the android support; with #32800 and accompanying PRs, we were able to build libraries with kerberos support. I have not tested SocketsHttpHandler on the device but the compilation finds gssapi headers and links with library.

Packages containing libkrb5.so: arm and aarch64.

after the arm64 compilation:

$ readelf -d  artifacts/obj/native/Linux-arm64-Debug/System.Net.Security.Native/System.Net.Security.Native.so  | grep NEEDED
 0x0000000000000001 (NEEDED)             Shared library: [libgssapi_krb5.so.2]
 0x0000000000000001 (NEEDED)             Shared library: [libm.so]
 0x0000000000000001 (NEEDED)             Shared library: [libdl.so]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so]

$ readelf -d .tools/android-rootfs/android-ndk-r21/sysroot/usr/lib/libgssapi_krb5.so.2 | grep NEEDED
 0x0000000000000001 (NEEDED)             Shared library: [libkrb5.so.3]
 0x0000000000000001 (NEEDED)             Shared library: [libk5crypto.so.3]
 0x0000000000000001 (NEEDED)             Shared library: [libcom_err.so.3]
 0x0000000000000001 (NEEDED)             Shared library: [libkrb5support.so.0]
 0x0000000000000001 (NEEDED)             Shared library: [libandroid-glob.so]
 0x0000000000000001 (NEEDED)             Shared library: [liblog.so]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so]
 0x0000000000000001 (NEEDED)             Shared library: [libandroid-support.so]
 0x0000000000000001 (NEEDED)             Shared library: [libdl.so]

$ find .tools/ -name libkrb5*
.tools/android-rootfs/tmp/aarch64/data/data/com.termux/files/usr/lib/libkrb5support.so
.tools/android-rootfs/tmp/aarch64/data/data/com.termux/files/usr/lib/libkrb5.so.3.3
.tools/android-rootfs/tmp/aarch64/data/data/com.termux/files/usr/lib/libkrb5.so
.tools/android-rootfs/tmp/aarch64/data/data/com.termux/files/usr/lib/libkrb5support.so.0
.tools/android-rootfs/tmp/aarch64/data/data/com.termux/files/usr/lib/libkrb5.so.3
.tools/android-rootfs/tmp/aarch64/data/data/com.termux/files/usr/lib/libkrb5support.so.0.1
.tools/android-rootfs/android-ndk-r21/sysroot/usr/lib/libkrb5support.so
.tools/android-rootfs/android-ndk-r21/sysroot/usr/lib/libkrb5.so.3.3
.tools/android-rootfs/android-ndk-r21/sysroot/usr/lib/libkrb5.so
.tools/android-rootfs/android-ndk-r21/sysroot/usr/lib/libkrb5support.so.0
.tools/android-rootfs/android-ndk-r21/sysroot/usr/lib/libkrb5.so.3
.tools/android-rootfs/android-ndk-r21/sysroot/usr/lib/libkrb5support.so.0.1

@karelz
Copy link
Member

karelz commented Feb 26, 2020

@marek-safar we intentionally reimplemented NTLM in C# for SocketsHttpHandler to avoid adding more dependencies. Overall we are trying to limit the number of dependencies as much as possible.
Is there a reason why Android cannot take the same approach and reuse the simple NTLM implementation?

UPDATE: Sorry, I was wrong, we do not have it in C# :(

@wfurt @davidsh may have more thoughts on general authentication and Kerberos integration into SocketsHttpHandler.

@davidsh
Copy link
Contributor

davidsh commented Feb 26, 2020

@wfurt @davidsh may have more thoughts on general authentication and Kerberos integration into SocketsHttpHandler.

Strictly speaking 'libkrb5' doesn't support NTLM; either raw NTLM nor 'Negotiate' protocol where Kerberos falls back to NTLM. On Linux that requires a separate 'gss-ntlmssp' package to be installed which is a plug in to the GSS-API that 'libkrb5' generally supports on Linux. On MacOS, it turns out that their 'libkrb5' bundle includes NTLM support. But that is also because MacOS ships the Heimdal implementation of the GSS-API and not the MIT Kerberos implementation that Linux distros support.

@karelz we need a decision on how we can support NTLM on Android. The proposed solution is to include a fork of krb5 package in dotnet/ org so we can reference it as part of dotnet/runtime build and package it for Android where this library is not available. Is this something your team can take on or do you have another idea?

I think we need to discuss this further. I'm currently not a fan of .NET Libraries owning a forked copy of 'libkrb5'.

@marek-safar
Copy link
Contributor

@davidsh Android is not really Linux and this is not the only area where we'll hit the difference (just FYI). How would you like to discuss this further? Are you fine to come up with a proposal how you would like to solve it?

@wfurt
Copy link
Member

wfurt commented Feb 26, 2020

Also old curl handler had it's own implementation. If anything that may be a better path than maintaining Kerberos fork. (unless we need Kerberos as well)

@davidsh
Copy link
Contributor

davidsh commented Feb 26, 2020

Also old curl handler had it's own implementation.

The managed CurlHandler didn't have any implementation. But the native 'libcurl' library did bundle an implementation of raw NTLM as well as 'Negotiate' (Kerberos ONLY, no fallback to NTLM) support. I don't see any advantage of using 'libcurl' for this.

@wfurt
Copy link
Member

wfurt commented Feb 26, 2020

I was not proposing to use libcurl but more to take maybe a similar approach. e.g. code NTLM support instead of depending on Kerberos/GSSAPI. That can be optional on platforms where Kerberos is not available or does not work (like OSX)

@marek-safar marek-safar added this to the 5.0 milestone Feb 28, 2020
@karelz
Copy link
Member

karelz commented Mar 5, 2020

Triage: @steveisok @marek-safar we need clarification if this is targeted at Android native handler or SocketsHttpHandler.
Is this just about the NTLM protocol, or also about Negotiate/Kerberos?

Overall, it would be best if you can provide proposal what you plan to do.

@karelz karelz added needs more info and removed untriaged New issue has not been triaged by the area owner labels Mar 5, 2020
@steveisok
Copy link
Member Author

In this instance it's for SocketsHttpHandler. NTLM would be the bare minimum as Xamarin had a custom implementation.

Ideally, this would be about both NTLM & Negotiate/Kerb if we can get it. Apparently, libkrb5 has a dependency on openssl, so this is likely going to be wrapped up in a larger discussion.

@wfurt
Copy link
Member

wfurt commented Mar 6, 2020

if packaging native krb bits would be an option, we would also need https://packages.ubuntu.com/bionic/gss-ntlmssp @am11.

@karelz
Copy link
Member

karelz commented Mar 6, 2020

Personally, it seems to me like a big hammer to package for NTLM support in SocketsHttpHandler, which is not even the default handler.
Who is expected to use it in which situations?
Is all the pain and size increase of Android apps worth the value?

@marek-safar
Copy link
Contributor

marek-safar commented Mar 6, 2020

There have been several customers reporting this as regression when we drop the support for it in the non-default handler (see https://developercommunity.visualstudio.com/content/problem/756697/last-visual-studio-update-brakes-ntlm-authenticati.html).

The default handler is not ".net compatible" handler and there could be legit reasons why some developers prefer it over the native one.

/cc @karelz

@am11
Copy link
Member

am11 commented Mar 6, 2020

@wfurt, I built their master branch on Debian: https://pagure.io/gssntlmssp. The BUILD.txt file only lists few dependencies from Fedora's viewpoint. Here is what was required to build it on Debian:

apt install build-essential automake autoconf pkgconf libssl-dev \
  libunistring-dev libxslt1-dev libwbclient-dev gettext xsltproc xml-core \
  docbook docbook-xsl libxml2-utils libtool libz-dev libkrb5-dev

then to build: autoreconf -fi && ./configure && make

full dependency tree is available here: https://paste2.org/YgwHM5L3. Haven't tried on Android yet, but I am anticipating some challenges in dependency acquisition from termux. IMHO, this package should be ported to termux (with upstream patches later on) rather than an isolated fork, mainly to DRY the effort and avoid extra work of keeping up with upstream etc.

@akoeplinger
Copy link
Member

This doesn't only affect Http but also SqlClient where we had multiple customers reporting problems:

@am11
Copy link
Member

am11 commented Mar 16, 2020

Tried building gssntlmssp in Android rootfs and hit the first blocker; looks like we would need to port Samba's libwbclient (+its dependencies https://gitlab.com/samba-team/samba/-/blob/master/nsswitch/libwbclient/wscript), which is a required dependency of gssntlmssp and missing from termux: termux/termux-packages#4517.
created a standalone script by stitching together parts of existing rootfs and adapting to autoconf project system:

# on Ubuntu / Debian

git clone https://pagure.io/gssntlmssp.git
cd gssntlmssp
curl -sSLO https://raw.githubusercontent.com/am11/runtime/feature/gssntlmssp-build/tmp/build.sh
chmod +x build.sh
./build.sh # takes about 1.5 to 2 minutes to setup the rootfs (idempotently)

currently failing in ./configure step, when trying to locate libwbclient.

@karelz karelz added enhancement Product code improvement that does NOT require public API changes/additions and removed needs more info labels Jan 15, 2021
@wfurt
Copy link
Member

wfurt commented Jan 28, 2021

I have managed implementation of NTLMv2. SPNEGO will need little bit more work but it looks pretty simple. I'll move forward unless we come up with better plan.

It assumes that platform can do md4 as that is not available as managed API.

@wfurt wfurt self-assigned this Jan 28, 2021
@akoeplinger
Copy link
Member

@wfurt is that a typo or do you really mean MD4 instead of 5? The former is not available on Android.

@filipnavara
Copy link
Member

Yes, NTLM uses MD4 and RC4 (iirc).

@SteveSyfuhs
Copy link

(This is one of the reasons why I said...)

I'd invest more time and energy trying to get customers to ditch NTLM altogether and switch to Kerberos.

@akoeplinger
Copy link
Member

akoeplinger commented Jan 28, 2021

@SteveSyfuhs it'd be nice if just Kerberos/Negotiate were enough for these customers, but the scenarios I've seen revolve mostly about in-house usage where people have an app that needs to communicate with an MSSQL server or an IIS website that they secured with "Windows" authentication.

I doubt (but don't know for sure) that these devices have access to the KDC in all cases, so NTLM is kinda the only option for them.

Given how broken MD4 already is, including an internal managed implementation might be doable since it's not really a "security" API anymore 😄

Btw. I don't think this issue means we should only implement NTLM, if we can get Kerberos to work that'd be awesome.

@wfurt
Copy link
Member

wfurt commented Jan 29, 2021

the algorithm uses md4(password) instead of password directly. I guess that provides predictable length and gives fixed bit set. I don't think this would be major weakness for typical password. On MacOS I use crypto directly (ressl/openssl)

        [DllImport("libcrypto", EntryPoint = "MD4_Init")]
        private static extern unsafe int MD4_Init(void* ctx);

This could be hidden somewhere in PAL IMHO. e.g. C implementation with good license would be sufficient.

There is no need for rc4 in v2. It uses md5_Hmac for the actual authentication part. And there is public API for it already.

While I agree with @SteveSyfuhs 's arguments, it still comes as platform gap on macOS (#887).
KDC is difficult to deploy over internet and I wanted to support development environments. (like me so HttpClient works on Mac same way as it does on Windows)
So I started this as personal project to learn more about authentication and got to working state without too much effort. As minimum, I learned lot about the protocol it self. I would like to also put in some more diagnostic and that means we cannot treat it as opaque blob any more at our layer.

@SteveSyfuhs
Copy link

IIS website that they secured with "Windows" authentication.

Just to be clear "Windows" authentication supports Kerberos.

I doubt (but don't know for sure) that these devices have access to the KDC in all cases, so NTLM is kinda the only option for them.

Before introducing a seriously insecure authentication protocol, it might be wise for folks to have something to back up this claim. I recognize line of sight issues can be serious, but also let's apply some reality to the situation before adding awful protocols that shouldn't exist anymore. :)

@akoeplinger
Copy link
Member

akoeplinger commented Jan 29, 2021

@wfurt MD5 is available so it sounds like NTLMv2 would work :)

@SteveSyfuhs I hear you and I think we should definitely advise people to use Kerberos wherever possible but the reaction we got when we accidentally broke NTLM on Android last time was quite substantial: https://developercommunity.visualstudio.com/content/problem/756697/last-visual-studio-update-brakes-ntlm-authenticati.html

@karelz
Copy link
Member

karelz commented Jul 19, 2021

Moving it to 7.0.

@karelz karelz modified the milestones: 6.0.0, 7.0.0 Jul 19, 2021
@dotMorten
Copy link

dotMorten commented Oct 8, 2021

I would REALLY like to see IWA support on Android. So far I haven't found any way to make this work. For iOS I can use the NSUrlSessionHandler, but if SocketsHttpHandler got this support, it would make the story simpler. Below are my results from testing various handlers and various platforms. The inconsistencies across platforms are pretty glaring, and makes writing x-plat code really hard.
We are getting a lot of grief from customers not being able to support their IWA-secured servers when accessing from Android.

UWP:

-HttpClientHandler: 200 OK

Xamarin.iOS:

  • HttpClientHandler: 401 Unauthorized
  • SocketsHttpHandler: 401 Unauthorized
  • NSUrlSessionHandler: 200 OK

Xamarin.Android:

  • HttpClientHandler: ERROR: The SSL connection could not be established, see inner exception: (Mono.Btls.MonoBtlsException: "Authentication failed, see inner exception."}
  • SocketsHttpHandler: ERROR: The SSL connection could not be established, see inner exception: (Mono.Btls.MonoBtlsException: "Authentication failed, see inner exception." (Inner shows 401)
  • AndroidClientHandler: 401 Unauthorized
  • MonoWebRequestHandler: ERROR: An error occurred while sending the request
  • ModernHttpClient: 401 Unauthorized

.net6-android

  • HttpClientHandler: 401 Unauthorized
  • SocketsHttpHandler: 401 Unauthorized
  • AndroidClientHandler: 401 Unauthorized
  • MonoWebRequestHandler: N/A

.NET 5 Console (Windows):

  • HttpClientHandler: 200 OK
  • SocketsHttpHandler: 200 OK

Test code used:

using System;
using System.Net;
using System.Net.Http;
using System.Reflection;
using System.Threading.Tasks;

namespace IwaTests
{
    static class Tests
    {
        private const string serverUri = "myserver";
        private const string username = "username";
        private const string password = "password";
        private const string domain = "domain";
        private static NetworkCredential credential = new NetworkCredential(username, password, domain);

        public static void Log(string message, Exception err = null)
        {
            System.Diagnostics.Debug.Write("****** " + message);
            if (err != null)
                System.Diagnostics.Debug.Write(" ERROR: " + err.Message);
            System.Diagnostics.Debug.WriteLine(string.Empty);
        }
        public static async void TestAll()
        {
            Log("Testing HttpClientHandler");
            try { await TestIwaHttpClientHandler(); }
            catch(Exception ex) { Log("HttpClientHandler: ", ex); }

#if NETCOREAPP || __IOS__ || __ANDROID__
            Log("Testing SocketsHttpHandler");
            try { await TestIwaSocketsHttpHandler(); }
            catch(Exception ex) { Log("SocketsHttpHandler: ", ex); }
#endif

#if __ANDROID__
            Log("Testing AndroidClientHandler");
            try { await TestIwaAndroidClientHandler(); }
            catch (Exception ex) { Log("AndroidClientHandler: ", ex); }

            Log("Testing MonoWebRequestHandler");
            try { await TestIwaMonoWebRequestHandler(); }
            catch (Exception ex) { Log("MonoWebRequestHandler: ", ex); }

#if !NETCOREAPP
            Log("Testing ModernHttpClient");
            try { await TestIwaModernHttpHandler(); }
            catch (Exception ex) { Log("ModernHttpClient: ", ex); }
#endif
#endif
#if __IOS__
            Log("Testing NSUrlSessionHandler");
            try { await TestIwaNSUrlSessionHandler(); }
            catch (Exception ex) { Log("NSUrlSessionHandler: ", ex); }
#endif
        }

        public static Task<HttpResponseMessage> TestIwaHttpClientHandler()
        {
            var handler = new HttpClientHandler();
            handler.Credentials = credential;
            var client= new HttpClient(handler);
            return TestIwa(handler);
        }
#if __IOS__
        public static Task<HttpResponseMessage> TestIwaNSUrlSessionHandler()
        {
            var handler = new NSUrlSessionHandler();
            handler.Credentials = credential;
            return TestIwa(handler);
        }
#endif
#if __ANDROID__
        public static Task<HttpResponseMessage> TestIwaAndroidClientHandler()
        {
            var handler = new Xamarin.Android.Net.AndroidClientHandler();
            handler.Credentials = credential;
            return TestIwa(handler);
        }
        public static Task<HttpResponseMessage> TestIwaMonoWebRequestHandler()
        {
            // Based on https://github.com/EgorBo/NtlmHttpHandler/blob/master/NtlmHttpHandlerFactory.cs
            Type monoHandlerType = Type.GetType("System.Net.Http.MonoWebRequestHandler, System.Net.Http");
            ConstructorInfo[] internalMonoHandlerCtors = monoHandlerType.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
            object internalMonoHandler = internalMonoHandlerCtors[0].Invoke(null);
             ConstructorInfo[] httpClientHandlerCtors =
                typeof(HttpClientHandler).GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance);
            var handler = (HttpClientHandler)httpClientHandlerCtors[0].Invoke(new[] { internalMonoHandler });
            handler.Credentials = credential;
            return TestIwa(handler);
        }
#if !NETCOREAPP
        public static Task<HttpResponseMessage> TestIwaModernHttpHandler()
        {
            var handler = new ModernHttpClient.NativeMessageHandler();
            handler.Credentials = credential;
            return TestIwa(handler);
        }
#endif
#endif
#if NETCOREAPP || __IOS__ || __ANDROID__
        public static Task<HttpResponseMessage> TestIwaSocketsHttpHandler()
        {
            var handler = new HttpClientHandler();
            handler.Credentials = credential;
            return TestIwa(handler);
        }
#endif

        public static async Task<HttpResponseMessage> TestIwa(HttpMessageHandler handler)
        {
            var msg = new HttpRequestMessage(HttpMethod.Get, new Uri(serverUri));
            using (var client = new HttpClient(handler, true))
            {
                var response = await client.SendAsync(msg);
                Log("Got status code: " + response.StatusCode);
                response = response.EnsureSuccessStatusCode(); // Should not throw
                Log("Test OK");
                return response;
            }
        }
    }
}

@steveisok steveisok changed the title Libkrb-5 is required for Android support of NTLM NTLM support in Android Nov 2, 2021
@MaximLipnin
Copy link
Contributor

To sum up things, is the viable suggestion to add some NTLMv2 implementation to SocketsHttpHandler ?
If I'm not mistaken, @wfurt already has some woking prototype for that, right?

@steveisok
Copy link
Member Author

To sum up things, is the viable suggestion to add some NTLMv2 implementation to SocketsHttpHandler ? If I'm not mistaken, @wfurt already has some woking prototype for that, right?

It's going to be a little more complicated than that unfortunately. SocketsHttpHandler is not the default handler in Android. It's actually https://github.com/xamarin/xamarin-android/blob/main/src/Mono.Android/Xamarin.Android.Net/AndroidMessageHandler.cs. In order to use sockets, you have to set a property.

Ideally, I'd like NTLM support in both. @wfurt can we meet with you and get an understanding of what you were originally thinking?

@wfurt
Copy link
Member

wfurt commented Nov 19, 2021

sure. My experience with Android is minimal but I can outline possible obstacles. I think it should be simple to set up a prototype at this point.

@dotMorten
Copy link

to be a little more complicated than that unfortunately. SocketsHttpHandler is not the default handler in Android

Sure but at least there is a way to enable NTLM support by changing the default. Today the is no option on Android AFAIK.

@wfurt
Copy link
Member

wfurt commented Nov 19, 2021

You can give it try if you want to @dotMorten. https://github.com/wfurt/Ntlm is simple wrapper around any handler. It reads and adds headers as needed (if (response.StatusCode == HttpStatusCode.Unauthorized) {...) and few other users got it successfully working (on macOS).
I think the biggest challenge would be support for old algorithms. https://github.com/JeroenBer/Ntlm/tree/main/NtlmHttp has clone with managed md4 and https://github.com/filipnavara/runtime/tree/md4 has rc4 as well.

I simply run out of time for 6.0 focusing on support for Quic and HTTP/3. While NTLM has many caveats and it is deemed weak I can understand that it is useful for legacy compact. As @SteveSyfuhs mentioned, we should probably also look into getting Kerberos working as more secure alternative.

@steveisok
Copy link
Member Author

Closing in favor of #62264

@dotMorten
Copy link

@wfurt Thanks. I haven't been able to get it to authenticate successfully though. I ended up using the MD4 implementation referenced in the 62264 issue, and pulling in ASN1 from the runtime repo just to completely avoid dependencies, but I still end up with 401. Negotiate etc does seem to run fine, but never succeeds.

@wfurt
Copy link
Member

wfurt commented Dec 10, 2021

Can you try pure ntlm @dotMorten? It is essentially the same but just less layers and perhaps little bit easier to debug. You can send me packet capture and I can take a look. I was planning to set up some emulator for testing but I did not get to it yet.
Also if you can run the code on Linux/Mac I can also take a look - I would expect it would give same results since there is no OS dependency.

@dotMorten
Copy link

@wfurt Pure ntlm? How do I set the client up for that? I can share my code, but you can't access any of my IWA servers. Do you know of any publicly accessible ones?

Here's what I see in the output (with diag turned on). I truncated the auth strings, albeit it's just a test account on a test server:

https://mysite can do NTLM authentication
https://mysite can do Negotiate authentication
Method: GET, RequestUri: 'https://mysite', Version: 2.0, Content: <null>, Headers:
{
  Authorization: NTLM TlRM[Truncated]AA==
}
NTLM challenge: TlRMTV[Truncated]AA
Get challenge from 'DOMAINNAME' with 0x02898205 (NegotiateUnicode, TargetName, NegotiateNtlm, NegotiateAlwaysSign, TargetTypeDomain, NegotiateNtlm2, NegotiateTargetInfo) flags
Got ID 2 with 14 len
Got ID 1 with 14 len
Got ID 4 with 16 len
Got ID 3 with 32 len
Got ID 5 with 22 len
Got ID 7 with 8 len
Got ID 0 with 0 len
EOF on AV PAIRS reached!
Method: GET, RequestUri: 'https://mysite', Version: 2.0, Content: <null>, Headers:
{
  Authorization: NTLM TlRMTV[Truncated]QA
}
StatusCode: 401, ReasonPhrase: 'Unauthorized', Version: 1.1, Content: System.Net.Http.HttpConnection+HttpConnectionResponseContent, Headers:
{
  Server: Microsoft-IIS/10.0
  WWW-Authenticate: Negotiate
  WWW-Authenticate: NTLM
  X-Powered-By: ASP.NET
  Date: Thu, 09 Dec 2021 23:46:35 GMT
  Content-Type: text/html
  Content-Length: 1293
}
Method: GET, RequestUri: 'https://mysite', Version: 2.0, Content: <null>, Headers:
{
  Authorization: Negotiate YEgG[Truncated]AA=
}
Negotiate challenege: oYHoM[Truncated]AA== - 1.3.6.1.4.1.311.2.2.10 in AcceptIncomplete
Get challenge from 'DOMAINNAME' with 0x02898205 (NegotiateUnicode, TargetName, NegotiateNtlm, NegotiateAlwaysSign, TargetTypeDomain, NegotiateNtlm2, NegotiateTargetInfo) flags
Got ID 2 with 14 len
Got ID 1 with 14 len
Got ID 4 with 16 len
Got ID 3 with 32 len
Got ID 5 with 22 len
Got ID 7 with 8 len
Got ID 0 with 0 len
EOF on AV PAIRS reached!
Method: GET, RequestUri: 'https://mysite', Version: 2.0, Content: <null>, Headers:
{
  Authorization: Negotiate oYIBVjCCAV[Truncated]AA==
}
StatusCode: 401, ReasonPhrase: 'Unauthorized', Version: 1.1, Content: System.Net.Http.HttpConnection+HttpConnectionResponseContent, Headers:
{
  Server: Microsoft-IIS/10.0
  WWW-Authenticate: Negotiate
  WWW-Authenticate: NTLM
  X-Powered-By: ASP.NET
  Date: Thu, 09 Dec 2021 23:46:38 GMT
  Content-Type: text/html
  Content-Length: 1293
}

@wfurt
Copy link
Member

wfurt commented Dec 10, 2021

It is the first option from the post @dotMorten e.g. 'Authorization: NTLM' vs 'Authorization: Negotiate`. The first option does not need any ASN and has raw NTLM data (base64). Can you try it agains simple IIS server? If so, then I would likely be able to reproduce it with your code anywhere. If IIS works, then we would need to figure out what is special about your internal servers. We would probably need the full exchange details (you can send it to my GH email if you don't want to post it publicly here)

@ghost ghost locked as resolved and limited conversation to collaborators Jan 9, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.Net enhancement Product code improvement that does NOT require public API changes/additions os-android
Projects
None yet
Development

No branches or pull requests