Skip to content

Instantly share code, notes, and snippets.

@foregenix
Created April 1, 2021 09:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save foregenix/71a515a5503a8ea4d7fe0a0952236739 to your computer and use it in GitHub Desktop.
Save foregenix/71a515a5503a8ea4d7fe0a0952236739 to your computer and use it in GitHub Desktop.
import "pe"
rule ModPipe_Loader
{
condition:
uint16(0) == 0x5A4D and uint32(uint32(0x3C)) == 0x00004550 and
for any i in (0..pe.number_of_sections - 1): (
pe.sections[i].name == ".flat" and (
pe.sections[i].characteristics & pe.SECTION_MEM_EXECUTE and
pe.sections[i].characteristics & pe.SECTION_MEM_WRITE) and
uint32(pe.sections[i].raw_data_offset + 26) == 0xEDB88320
)
}
rule ModPipe_CredStealer
{
strings:
$hookLogin = "HookLogonDll64.dll" ascii
condition:
uint16(0) == 0x5A4D and uint32(uint32(0x3C)) == 0x00004550
and $hookLogin
}
rule ModPipe_CredStealer_OP
{
strings:
$getCaps = "NPGetCaps" ascii
$logonNotify = "NPLogonNotify" ascii
$createFile = "CreateFileA" ascii
$hvFilePref = "\\Installer\\{" ascii
$pipe = "\\\\.\\pipe\\" ascii
condition:
uint16(0) == 0x5A4D and uint32(uint32(0x3C)) == 0x00004550
and all of ($getCaps, $logonNotify, $createFile) and 1 of ( $hvFilePref, $pipe)
}
package main
import (
"bytes"
"encoding/hex"
"fmt"
"io/ioutil"
"os"
)
const defaultKey = "1F82FAEE939291E84C0A458508ADBF406F0542F6EA32B912DEB69C8F8C6766B5"
func main() {
if len(os.Args) < 2 {
usage()
os.Exit(1)
}
if os.Args[1] == "-h" || os.Args[1] == "/?" {
usage()
os.Exit(0)
}
fd, err := ioutil.ReadFile(os.Args[1])
if err != nil {
fmt.Fprint(os.Stderr, "ERROR: Could not read harvest file: "+err.Error())
os.Exit(2)
}
var bKey []byte
if len(os.Args) > 2 {
if len(os.Args[2]) != 64 {
fmt.Fprintln(os.Stderr, " [+] Extracting key from harvest DLL...")
kf, err := os.OpenFile(os.Args[2], os.O_RDONLY, 0)
if err != nil {
usage()
fmt.Fprintln(os.Stderr, "ERROR: Could not open harvest DLL file: "+err.Error())
os.Exit(3)
}
bKey = make([]byte, 32)
_, err = kf.ReadAt(bKey, 0xB08)
if err != nil {
fmt.Fprintln(os.Stderr, "ERROR: Could not extract the XOR key from the harvest DLL: "+err.Error())
os.Exit(4)
}
} else {
bKey, err = hex.DecodeString(os.Args[2])
if err != nil {
fmt.Fprintln(os.Stderr, "ERROR: Could not decode the XOR key from the command line: "+err.Error())
os.Exit(5)
}
}
} else {
bKey, _ = hex.DecodeString(defaultKey)
}
fmt.Fprintf(os.Stderr, " [+] Using key: %064X\n", bKey)
fmt.Println("Domain\tUsername\tPassword")
var dbuf bytes.Buffer
var kOff int
var cnt int
for i := 0; i < len(fd); i++ {
dbuf.WriteByte(fd[i] ^ bKey[kOff])
if fd[i]^bKey[kOff] == 0x0A {
kOff = 0
cnt++
fmt.Print(dbuf.String())
dbuf.Reset()
continue
}
kOff = (kOff + 1) % 32
}
fmt.Fprintf(os.Stderr, " [+] Decoded %d entries\n", cnt)
}
func usage() {
fmt.Fprintln(os.Stderr, `ModPipe HookLogon Harvest File Decoder
Usage: go run main.go <Harvest_File> [<Key>|<Harvest_DLL>]
<Harvest_File> - Path to the harvest file to decode
<Key> - (Optional) Hex encoded XOR key
<Harvest_DLL> - (Optional) Path to the harvest DLL may be provided instead of an XOR
key. In this case the program will atempt to extract the XOR key from
the harvest DLL.`)
}
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Mar 31 15:51:31 2021
@author: jake
"""
import argparse
import sys
def main():
parser = argparse.ArgumentParser(
description='ModPipe HookLogon Harvest File Decoder')
parser.add_argument(
'Path', help='file path to ModPipe HookLogon Harvest Data.')
parser.add_argument("--key", dest='key', help='Hex encoded XOR key.',
default='1F82FAEE939291E84C0A458508ADBF406F0542F6EA32B912DEB69C8F8C6766B5')
if len(sys.argv) < 1:
parser.print_help()
sys.exit(1)
args = parser.parse_args()
decode(getEncodedData(args.Path), bytearray.fromhex(args.key))
def decode(data, key):
decodedstr = ""
keyindex = 0
print("Domain\tUsername\tPassword")
for i in range(len(data)):
# res = ord(data[i]) ^ key[keyindex] #Python 2.x
res = data[i] ^ key[keyindex]
if res == 0x0A:
keyindex = 0
print(decodedstr)
decodedstr = ""
continue
decodedstr += chr(res)
keyindex = (keyindex+1) % 32
def getEncodedData(f):
return open(f, "rb").read()
if __name__ == '__main__':
main()
rule ModPipe_Memory_Core
{
strings:
$callModPipe = "Call ModPipe %04X sent=%d, recv=%d (%s)" ascii
$stat = "U: %s P: %d %s E: %s (%d)" ascii
$inject = "inject to %d err=%d" ascii
$ua = "Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/4.0)" ascii
$robots = "/robots.txt" ascii
condition:
3 of them
}
rule ModPipe_Memory_Installer
{
strings:
$drprov2 = "%s\\System32\\drprov2.dll" ascii
$logon = "Logon.txt" ascii
$rdpnp = "SYSTEM\\CurrentControlSet\\services\\RDPNPv2" ascii
$pipe = "PrevInstance pipe call: %s\n" ascii
condition:
all of them
}
rule ModPipe_Memory_Skimmer
{
strings:
$jhook = "JHook_CryptDecrypt" ascii
$hDirect = "HookDirect" ascii
$hExport = "HookExport" ascii
$hImport = "HookImport" ascii
$mhook = "mhook.txt" ascii
condition:
4 of them
}
rule ModPipe_Memory_PubKey
{
strings:
$key = { 06 02 00 00 00 24 00 00 52 53 41 31 00 04 00 00
01 00 01 00 4D F2 F9 CE A3 BD C1 D9 B9 6A 30 29
EE 4C 9B 6E EC 83 2B 10 12 CD 33 D7 0C A2 54 B3
DF BA 29 0E 5C 69 27 9C AD 6C EC 52 16 B8 23 86
98 57 19 06 A0 7E 8B C7 4E D5 0F CE 6A 27 1C ED
CB 60 56 73 AC 75 AC A7 CD 7F 75 58 62 02 2D 43
FB CA 10 9C 51 9F FC BF E4 DB BF 5B 72 04 34 4A
FB 4E 00 07 E1 2C A6 02 A6 7E 24 C9 8F 75 87 2D
3E 39 00 99 68 AF FF D6 6D B1 FB C3 0A 1F 55 56
9F 9D A8 E4 }
condition:
all of them
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment