Files
S4ntiagoP 12025ead0f chunk BOFs parameters
this is important because some BOFs such as
noconsolation can have an entire PE as parameter
2023-11-10 15:45:40 -03:00

302 lines
7.3 KiB
Go

package common
import (
"bufio"
"bytes"
"encoding/binary"
"fmt"
"image/png"
"time"
"io"
"math/rand"
"net"
"strconv"
"unicode/utf16"
"unicode/utf8"
"regexp"
"errors"
"strings"
"Havoc/pkg/logger"
"golang.org/x/image/bmp"
"golang.org/x/text/encoding/unicode"
)
func ParseWorkingHours(WorkingHours string) (int32, error) {
/*
* The working hours are packed in a uint32
* X: enabled or not
* A: start hour
* B: start minute
* C: end hour
* D: end minute
* XAAAAABBBBBBCCCCCDDDDDD
* 00000000010000011111100000111111
* ------------32 bits-------------
*/
var (
IntWorkingHours int32 = 0
)
if WorkingHours != "" {
match, err := regexp.MatchString("^[12]?[0-9]:[0-6][0-9]-[12]?[0-9]:[0-6][0-9]$", WorkingHours)
if err != nil || match == false {
return IntWorkingHours, errors.New("Failed to parse the WorkingHours: Invalid format for working hours, use: 8:00-17:00")
}
startAndEnd := strings.Split(WorkingHours, "-")
startHourandMinutes := strings.Split(startAndEnd[0], ":")
endHourandMinutes := strings.Split(startAndEnd[1], ":")
startHour, _ := strconv.Atoi(startHourandMinutes[0])
startMin , _ := strconv.Atoi(startHourandMinutes[1])
endHour, _ := strconv.Atoi(endHourandMinutes[0])
endMin, _ := strconv.Atoi(endHourandMinutes[1])
if startHour < 0 || startHour > 24 || endHour < 0 || endHour > 24 || startMin < 0 || startMin > 60 || endMin < 0 || endMin > 60 {
return IntWorkingHours, errors.New("Failed to parse the WorkingHours: Invalid hour or minute defined in working hours")
}
if endHour < startHour || (startHour == endHour && endMin <= startMin) {
return IntWorkingHours, errors.New("Failed to parse the WorkingHours: Then end hour can't be sooner than the start hour")
}
// set the "enabled" bit
IntWorkingHours |= 1 << 22
IntWorkingHours |= (int32(startHour) & 0b011111) << 17
IntWorkingHours |= (int32(startMin) & 0b111111) << 11
IntWorkingHours |= (int32(endHour) & 0b011111) << 6
IntWorkingHours |= (int32(endMin) & 0b111111) << 0
}
return IntWorkingHours, nil
}
func Bmp2Png(BmpBytes []byte) []byte {
var (
f io.Writer
Bytes bytes.Buffer
)
f = bufio.NewWriter(&Bytes)
Image, err := bmp.Decode(bytes.NewReader(BmpBytes))
if err != nil {
logger.Error("Failed to decode bmp: " + err.Error())
return nil
}
err = png.Encode(f, Image)
if err != nil {
logger.Error("Failed to write png file: " + err.Error())
return nil
}
return Bytes.Bytes()
}
func DecodeUTF16(b []byte) string {
var (
u16s = make([]uint16, 1)
b8buf = make([]byte, 4)
ret = &bytes.Buffer{}
)
lb := len(b)
for i := 0; i < lb; i += 2 {
u16s[0] = uint16(b[i]) + (uint16(b[i+1]) << 8)
r := utf16.Decode(u16s)
n := utf8.EncodeRune(b8buf, r[0])
ret.Write(b8buf[:n])
}
return ret.String()
}
func EncodeUTF16(s string) []byte {
var err error
// in C, strings terminate with a null-byte
if strings.HasSuffix(s, "\x00") == false {
s += "\x00"
}
uni := unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM)
encoded, err := uni.NewEncoder().String(s)
if err != nil {
logger.Error("Failed to convert UTF8 to UTF16")
return []byte("")
}
return []byte(encoded)
}
func EncodeUTF8(s string) []byte {
// in C, strings terminate with a null-byte
if strings.HasSuffix(s, "\x00") == false {
s += "\x00"
}
return []byte(s)
}
func ByteCountSI(b int64) string {
const unit = 1000
if b < unit {
return fmt.Sprintf("%d B", b)
}
div, exp := int64(unit), 0
for n := b / unit; n >= unit; n /= unit {
div *= unit
exp++
}
return fmt.Sprintf("%.2f %cB",
float64(b)/float64(div), "kMGTPE"[exp])
}
func XorCipher(input, key string) (output string) {
for i := 0; i < len(input); i++ {
output += string(input[i] ^ key[i%len(key)])
}
return output
}
func RandomString(n int) string {
var chars = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0987654321")
str := make([]rune, n)
for i := range str {
str[i] = chars[rand.Intn(len(chars))]
}
return string(str)
}
func Int32ToLittle(x uint32) uint32 {
bs := make([]byte, 4)
binary.LittleEndian.PutUint32(bs, x)
return binary.LittleEndian.Uint32(bs)
}
func StripNull(s string) string {
return string(bytes.Trim([]byte(s), "\x00"))
}
func PercentageChange(part int, total int64) float64 {
return (float64(part) * float64(100)) / float64(total)
}
func IpStringToInt32(ip string) (int, error) {
var long uint32
err := binary.Read(bytes.NewBuffer(net.ParseIP(ip).To4()), binary.LittleEndian, &long)
if err != nil {
return 0, err
}
return int(long), nil
}
func Int32ToIpString(ipInt int64) string {
// need to do two bit shifting and “0xff” masking
b0 := strconv.FormatInt((ipInt>>24)&0xff, 10)
b1 := strconv.FormatInt((ipInt>>16)&0xff, 10)
b2 := strconv.FormatInt((ipInt>>8)&0xff, 10)
b3 := strconv.FormatInt(ipInt&0xff, 10)
return b3 + "." + b2 + "." + b1 + "." + b0
}
func EpochTimeToSystemTime( EpochTime int64 ) int64 {
var (
UNIX_TIME_START int64 = 0x019DB1DED53E8000 //January 1, 1970 (start of Unix epoch) in "ticks"
TICKS_PER_SECOND int64 = 10000000 //a tick is 100ns
)
if (EpochTime == 0) {
return 0
}
return ( EpochTime * TICKS_PER_SECOND ) + UNIX_TIME_START
}
func GetRandomChar(dict string) string {
return string(dict[rand.Intn(len(dict))])
}
// generate a PipeName from a name template
func GeneratePipeName(Template string, PID int, TID int) string {
var PipeName = Template
hexdigits := "0123456789abcdef"
digits := "0123456789"
ascii_uppercase := "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
ascii_lowercase := "abcdefghijklmnopqrstuvwxyz"
rand.Seed(time.Now().UnixNano())
// add the process PID (if specified)
if PID != 0 {
PipeName = strings.Replace(PipeName, "{pid}", fmt.Sprintf("%d", PID), -1)
PipeName = strings.Replace(PipeName, "{Pid}", fmt.Sprintf("%d", PID), -1)
PipeName = strings.Replace(PipeName, "{PID}", fmt.Sprintf("%d", PID), -1)
}
// add the process TID (if specified)
if TID != 0 {
PipeName = strings.Replace(PipeName, "{tid}", fmt.Sprintf("%d", TID), -1)
PipeName = strings.Replace(PipeName, "{Tid}", fmt.Sprintf("%d", TID), -1)
PipeName = strings.Replace(PipeName, "{TID}", fmt.Sprintf("%d", TID), -1)
}
// #: hex char
for strings.Contains(PipeName, "$") {
PipeName = strings.Replace(PipeName, "$", GetRandomChar(hexdigits), 1)
}
// #: number
for strings.Contains(PipeName, "#") {
PipeName = strings.Replace(PipeName, "#", GetRandomChar(digits), 1)
}
// !: uppercase char
for strings.Contains(PipeName, "@") {
PipeName = strings.Replace(PipeName, "@", GetRandomChar(ascii_uppercase), 1)
}
// !: lowercase char
for strings.Contains(PipeName, "!") {
PipeName = strings.Replace(PipeName, "!", GetRandomChar(ascii_lowercase), 1)
}
// make sure the pipename starts with \\.\pipe\
if strings.HasPrefix(PipeName, "\\\\.\\pipe\\") == false {
PipeName = "\\\\.\\pipe\\" + PipeName
}
return PipeName
}
func GetInterfaceIpv4Addr(interfaceOrIp string) string {
var (
ief *net.Interface
addrs []net.Addr
ipv4Addr net.IP
err error
)
if ief, err = net.InterfaceByName(interfaceOrIp); err != nil { // get interface
return interfaceOrIp
}
if addrs, err = ief.Addrs(); err != nil { // get addresses
return interfaceOrIp
}
for _, addr := range addrs { // get ipv4 address
if ipv4Addr = addr.(*net.IPNet).IP.To4(); ipv4Addr != nil {
break
}
}
if ipv4Addr == nil {
return interfaceOrIp
}
return ipv4Addr.String()
}