Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IPfuscation #71

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions techniques/IPfuscation/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# *IPFuscation*

## Authorship information
* Name or nickname (required): *4rkt0uR0s*
* Email: *[email protected]*

## Technique Information
* Technique title (required): IPV4/IPV6 Obfuscation
* Technique category (required): Data Obfuscation
* Technique description (required): The obfuscated payload masquerades itself as an array of ASCII IPv4 addresses. Each one of these IPs is passed to the `RtlIpv4StringToAddressA` function, which will translate the ASCII IP string to binary. The binary representation of all of these IPs is combined to form a blob of shellcode. Additionally, IPfuscation variants were spotted using IPv6 instead of IPv4 addresses, UUIDs, and MAC addresses, all operating in almost the same way.

## Additional resources
* https://www.sentinelone.com/blog/hive-ransomware-deploys-novel-ipfuscation-technique/
* https://www.bleepingcomputer.com/news/security/hive-ransomware-uses-new-ipfuscation-trick-to-hide-payload/
* https://cyware.com/news/ipfuscation-is-hives-new-technique-to-evade-detection-96c3c748

## Code snippets
To generate an obfuscated payload from a shellcode, you must first run the python script which will return the obfuscated payload as a list of IPs
```bash
$ python3 ipv4fuscation.py
char * payload[13] = {
"72.101.108.108","111.32.85.110","112.114.111.116","101.99.116.80","114.111.106.101","99.116.44.32","116.104.105.115",
"32.105.115.32","73.80.118.52","32.111.98.102","117.115.99.97","116.105.111.110","32.58.41.0"
};
```

Then, you can deobfuscate it at runtime in the heap, as in `ipv4defuscation.c`

```c
void Ipv4Deobfuscate(CHAR* Ipv4Array[], int Ipv4ArrayLength) {
PCSTR Terminator = NULL;
PBYTE pointer = NULL, tmp = NULL;
pointer = (PBYTE)HeapAlloc(GetProcessHeap(), 0, Ipv4ArrayLength*4);
addressToWrite = pointer;
printf("Allocated on heap at : 0x%p", pointer);
for (int i = 0; i < Ipv4ArrayLength; i++){
RtlIpv4StringToAddressA(Ipv4Array[i], FALSE, &Terminator, addressToWrite);
addressToWrite = (PBYTE)(addressToWrite + 4);
}
getchar(); // Pause so you can inspect the heap
}
```
30 changes: 30 additions & 0 deletions techniques/IPfuscation/ipv4defuscation.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#include <Windows.h>
#include <stdio.h>
#include <ip2string.h>

#pragma comment(lib, "ntdll.lib")

void Ipv4Deobfuscate(CHAR* Ipv4Array[], int Ipv4ArrayLength) {
PCSTR Terminator = NULL;
PBYTE pointer = NULL, addressToWrite = NULL;
pointer = (PBYTE)HeapAlloc(GetProcessHeap(), 0, Ipv4ArrayLength*4);
addressToWrite = pointer;
printf("Allocated on heap at : 0x%p", pointer);
for (int i = 0; i < Ipv4ArrayLength; i++){
RtlIpv4StringToAddressA(Ipv4Array[i], FALSE, &Terminator, addressToWrite);
addressToWrite = (PBYTE)(addressToWrite + 4);
}
getchar(); // Pause so you can inspect the heap
}


int main() {
char * payload[13] = {
"72.101.108.108","111.32.85.110","112.114.111.116","101.99.116.80","114.111.106.101","99.116.44.32","116.104.105.115",
"32.105.115.32","73.80.118.52","32.111.98.102","117.115.99.97","116.105.111.110","32.58.41.0"
};

Ipv4Deobfuscate(payload, 13);

return 0;
}
27 changes: 27 additions & 0 deletions techniques/IPfuscation/ipv4fuscation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
def generate_ipv4_string(shellcode):
shellcode_size = len(shellcode)

# Ensure shellcode size is a multiple of 4
if shellcode_size % 4 != 0:
raise ValueError("Shellcode size must be a multiple of 4.")

ipv4_array = []
number_of_ip = 0

# Generate shellcode every 4 bytes
for i in range(0, shellcode_size, 4):
ip = f"{int(shellcode[i], 16)}.{int(shellcode[i+1], 16)}.{int(shellcode[i+2], 16)}.{int(shellcode[i+3], 16)}"
number_of_ip += 1

if number_of_ip % (shellcode_size // 4) == 0:
ipv4_array.append(f'"{ip}"')
elif number_of_ip % 8 == 0:
ipv4_array.append(f'\n\t"{ip}",')
else:
ipv4_array.append(f'"{ip}",')

# Print the result in the same format
print(f"char * payload[{len(ipv4_array)}] = {{ \n\t{''.join(ipv4_array)}\n}};\n")

shellcode = ["0x48","0x65","0x6c","0x6c","0x6f","0x20","0x55","0x6e","0x70","0x72","0x6f","0x74","0x65","0x63","0x74","0x50","0x72","0x6f","0x6a","0x65","0x63","0x74","0x2c","0x20","0x74","0x68","0x69","0x73","0x20","0x69","0x73","0x20","0x49","0x50","0x76","0x34","0x20","0x6f","0x62","0x66","0x75","0x73","0x63","0x61","0x74","0x69","0x6f","0x6e","0x20","0x3a","0x29","0x00"]
generate_ipv4_string(shellcode)