masterzen / winrm

Command-line tool and library for Windows remote command execution in Go
Apache License 2.0
425 stars 129 forks source link

support NTLM message encryption #134

Closed CalypsoSys closed 11 months ago

CalypsoSys commented 1 year ago

based on the python code from https://pypi.org/project/pywinrm/

uses the most excellent NTLM library from https://github.com/bodgit/ntlmssp forked to github.com/CalypsoSys/bobntlmssp the modified version only differs in not outputting raw http request and response (have a PR in to accept optional output)

see https://github.com/CalypsoSys/bobwinrmntlm for usage

CalypsoSys commented 1 year ago

sounds good - some of the "un-golang" items are because I converted from python library will update PR over weekend - thx

aidanleuck commented 1 year ago

Could you test this change and verify that NTLM works properly when using HTTPS? I used the bobwinrm library when I ran into this issue. I was not able to connect over 5986. But was able to connect over 5985. Getting the same error as before http 401

CalypsoSys commented 12 months ago

@aidanleuck - I have tested against both 5985/http and 5986/https and it works - sample code below



func runExec(address string, port int, https bool, userName string, password string) {
    endpoint := winrm.NewEndpoint(address, port, https, true, nil, nil, nil, 0)

    params := winrm.DefaultParameters
    enc, _ := winrm.NewEncryption("ntlm")
    params.TransportDecorator = func() winrm.Transporter { return enc }

    client, err := winrm.NewClientWithParameters(endpoint, userName, password, params)
    if err != nil {
        fmt.Println(err)
    }

    stdOut, stdErr, exitCode, err := client.RunCmdWithContext(context.Background(), "ipconfig /all")
    fmt.Printf("%d\n%v\n%s\n%s\n", exitCode, err, stdOut, stdErr)
    if err != nil || (len(stdOut) == 0 && len(stdErr) > 0) {
        _ = exitCode
        fmt.Println(err)
    } else {
        fmt.Println("Ok")
    }
}

// http
runExec("192.168.50.10", 5985, false, "administrator", "password")
// https
runExec("192.168.50.11", 5986, true, "administrator", "password")`
CalypsoSys commented 12 months ago

@masterzen - re: "few tests around the parsing/encryption/decryption"

having a bit of a issue writing meaningful unit tests around this as the code for that lies in github.com/bodgit/ntlmssp and the member variable are private.