Skip to content

Instantly share code, notes, and snippets.

@williballenthin
Last active July 6, 2023 10:07
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save williballenthin/ed7b3de224d5b986bc04dc882c5ee7c5 to your computer and use it in GitHub Desktop.
Save williballenthin/ed7b3de224d5b986bc04dc882c5ee7c5 to your computer and use it in GitHub Desktop.
match x86 that appears to be stack string creation
rule stack_strings
{
meta:
author = "William Ballenthin"
email = "william.ballenthin@fireeye.com"
license = "Apache 2.0"
copyright = "FireEye, Inc"
description = "Match x86 that appears to be stack string creation."
strings:
// stack string near the frame pointer.
// the compiler may choose to use a single byte offset from $bp.
// like: mov [ebp-10h], 25h
//
// regex explanation:
// 4 times:
// byte C6 (mov byte)
// byte 45 ($bp-relative, one-byte offset)
// any byte (the offset from $bp)
// printable ascii (the immediate constant)
// 1 times:
// byte C6 (mov byte)
// byte 45 ($bp-relative, one-byte offset)
// any byte (the offset from $bp)
// byte 00 (the immediate constant, null terminator)
$ss_small_bp = /(\xC6\x45.[a-zA-Z0-9 -~]){4,}\xC6\x45.\x00/
// dword stack string near the frame pointer.
// the compiler may choose to use a single byte offset from $bp.
// it may move four bytes at a time onto the stack.
// like: mov [ebp-10h], 680073h ; "sh"
//
// regex explanation:
// 2 times:
// byte C7 (mov dword)
// byte 45 ($bp-relative, one-byte offset)
// any byte (the offset from $bp)
// printable ascii (the immediate constant)
// byte 00 (second byte of utf-16 encoding of ascii character)
// printable ascii (the immediate constant)
// byte 00 (second byte of utf-16 encoding of ascii character)
// 1 times:
// byte C7 (mov dword)
// byte 45 ($bp-relative, one-byte offset)
// any byte (the offset from $bp)
// any byte (immediate constant or NULL terminator)
// byte 00 (the immediate constant, NULL terminator)
// byte 00 (the immediate constant, NULL terminator)
// byte 00 (the immediate constant, NULL terminator)
$ss_small_bp_dword = /(\xC7\x45.[a-zA-Z0-9 -~]\x00[a-zA-Z0-9 -~]\x00){2,}\xC7\x45..\x00\x00\x00/
// stack strings further away from the frame pointer.
// the compiler may choose to use a four-byte offset from $bp.
// like: mov byte ptr [ebp-D80h], 5Ch
// we restrict the offset to be within 0xFFF (4095) of the frame pointer.
//
// regex explanation:
// 4 times:
// byte C6 (mov byte)
// byte 85 ($bp-relative, four-byte offset)
// any byte (LSB of the offset from $bp)
// byte 0xF0-0xFF (second LSB of the offset from $bp)
// byte FF (second MSB)
// byte FF (MSB of the offset from $bp)
// printable ascii (the immediate constant)
// 1 times:
// byte C6 (mov byte)
// byte 85 ($bp-relative, four-byte offset)
// any byte (LSB of the offset from $bp)
// byte 0xF0-0xFF (second LSB of the offset from $bp)
// byte FF (second MSB)
// byte FF (MSB of the offset from $bp)
// byte 00 (the immediate constant, null terminator)
$ss_big_bp = /(\xC6\x85.[\xF0-\xFF]\xFF\xFF[a-zA-Z0-9 -~]){4,}\xC6\x85.[\xF0-\xFF]\xFF\xFF\x00/
// stack string near the stack pointer.
// the compiler may choose to use a single byte offset from $sp.
// like: mov byte ptr [esp+0Bh], 24h
//
// regex explanation:
// 4 times:
// byte C6 (mov byte)
// byte 44 ($sp-relative, one-byte offset)
// byte 24 ($sp-relative, one-byte offset)
// any byte (the offset from $sp)
// printable ascii (the immediate constant)
// 1 times:
// byte C6 (mov byte)
// byte 44 ($sp-relative, one-byte offset)
// byte 24 ($sp-relative, one-byte offset)
// any byte (the offset from $sp)
// byte 00 (the immediate constant, null terminator)
$ss_small_sp = /(\xC6\x44\x24.[a-zA-Z0-9 -~]){4,}\xC6\x44\x24.\x00/
// stack strings further away from the stack pointer.
// the compiler may choose to use a four-byte offset from $sp.
// like: byte ptr [esp+0DDh], 49h
// we restrict the offset to be within 0xFFF (4095) of the stack pointer.
//
// regex explanation:
// 4 times:
// byte C6 (mov byte)
// byte 84 ($sp-relative, four-byte offset)
// byte 24 ($sp-relative, four-byte offset)
// any byte (LSB of the offset from $sp)
// byte 0x00-0x0F (second LSB of the offset from $sp)
// byte 00 (second MSB)
// byte 00 (MSB of the offset from $sp)
// printable ascii (the immediate constant)
// 1 times:
// byte C6 (mov byte)
// byte 84 ($sp-relative, four-byte offset)
// byte 24 ($sp-relative, four-byte offset)
// any byte (LSB of the offset from $sp)
// byte 0x00-0x0F (second LSB of the offset from $sp)
// byte 00 (second MSB)
// byte 00 (MSB of the offset from $sp)
// byte 00 (the immediate constant, null terminator)
$ss_big_sp = /(\xC6\x84\x24.[\x00-\x0F]\x00\x00[a-zA-Z0-9 -~]){4,}\xC6\x84\x24.[\x00-\x0F]\x00\x00\x00/
condition:
$ss_small_bp or $ss_small_bp_dword or $ss_big_bp or $ss_small_sp or $ss_big_sp
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment