Building Backdoors with Alternative Socket with lib-nosa (No Socket API)
Alternative implementation of winsock2 using AFD.sys for socket realization. Still improving!
lib-nosa is a minimalist C library designed to facilitate socket connections through AFD driver IOCTL operations on Windows. By bypassing the traditional winsock2.h -> (ws2_dll.dll)
header, lib-nosa directly interacts with the internal socket APIs of the AFD (Ancillary Function Driver for WinSock), offering developers a lightweight and low-level alternative for network programming.
Created by ViperX Team
Repository: https://github.com/ViperXSecurity/lib-nosa
Features
Establishes socket connections directly through AFD driver IOCTL calls, bypassing the standard Winsock2 interface.
Focuses on simplicity and performance, with a small footprint and no unnecessary dependencies.
Provides direct access to internal socket APIs, giving developers fine-grained control over network operations.
Avoids the overhead and abstraction of the Winsock2 API, making it ideal for performance-critical applications.
Building a Simple Backdoor with lib-nosa
lib-nosa
Creating a simple backdoor using the lib-nosa
library. We'll explore the core functions provided by lib-nosa
, understand their purposes, and see how they integrate to establish a connection, send and receive data, and execute received shellcode.
Overview
The backdoor's primary function is to connect to a Command and Control (C2) server, signal its readiness, receive a shellcode payload, and execute it. Here's the high-level flow:
Establish Connection: Connect to the C2 server using the specified IP and port.
Allocate Memory: Reserve memory to store the incoming shellcode.
Signal Readiness: Inform the server that the client is ready to receive the shellcode.
Receive Shellcode: Receive the shellcode from the server.
Execute Shellcode: Change memory permissions to executable and run the shellcode.
Cleanup: Release allocated resources.
Let's delve into each step, examining the code and the underlying lib-nosa
APIs.
The Code
Code Run
Detailed Breakdown
1. Establishing a Connection
Function Used: nosa_connect
nosa_connect
Function
Purpose: Establishes a connection to a specified host and port using the desired socket type (e.g., TCP or UDP).
Parameters:
hSocket
: A pointer to aHANDLE
where the function will store the created socket handle upon successful connection.host
: The target hostname or IP address.port
: The target port number.socketType
: The type of socket to use ("TCP"
or"UDP"
).
Return Value: Returns an
NTSTATUS
code indicating success or failure.
Explanation:
The function initializes and creates a socket based on the provided
socketType
.It resolves the
host
to an IP address, possibly usingnosa_dns_lookup
if a domain name is provided.It then attempts to establish a connection to the specified
host
andport
.Upon success, it stores the socket handle in
hSocket
.
2. Allocating Memory
Explanation:
Uses the Windows API
VirtualAlloc
to reserve a memory region of sizeMAX_RECV_BYTES
(4096 bytes in this case) with read/write permissions.This memory will store the incoming shellcode.
memset
ensures the allocated memory is zeroed out to prevent any residual data.
3. Signaling Readiness
Function Used: nosa_send
nosa_send
Function
Purpose: Sends data over an established socket connection.
Parameters:
hSocket
: Pointer to the socket handle over which data will be sent.packet_data
: Pointer to the data buffer to be sent.packet_data_sz
: Size of the data buffer in bytes.
Return Value: Returns an
NTSTATUS
code indicating success or failure.
Explanation:
Sends the string
"READY"
to the server, indicating that the client is prepared to receive the shellcode.Ensures that the entire message is sent successfully.
4. Receiving the Shellcode
Function Used: nosa_recv
nosa_recv
Function
Purpose: Receives data from an established socket connection.
Parameters:
hSocket
: The socket handle from which data will be received.packet_data_received
: Pointer to the buffer where the received data will be stored.
Return Value: Returns the number of bytes received or an
NTSTATUS
code indicating an error.
Explanation:
Receives data from the server, which should be the shellcode payload.
Checks if the received byte count is greater than zero to ensure data was received successfully.
The received data is stored in the previously allocated
pktRecv
buffer.
5. Executing the Shellcode
Explanation:
Changing Memory Permissions: Uses
VirtualProtect
to modify the memory permissions of thepktRecv
buffer, allowing it to be executable.Changes from
PAGE_READWRITE
toPAGE_EXECUTE_READ
.Stores the old protection settings in
oldProtect
(useful for restoring later if needed).
Executing the Shellcode:
Casts the
pktRecv
buffer to a function pointerfunc
.Invokes
func()
, executing the shellcode.
Safety Note: Executing arbitrary shellcode can be extremely dangerous. Ensure that the shellcode is from a trusted source and that testing occurs in a controlled environment.
6. Cleanup
Explanation:
Memory Release: Frees the allocated memory for
pktRecv
usingVirtualFree
.Socket Closure: Closes the established socket connection using
afd_close
.
Understanding Additional lib-nosa
APIs
lib-nosa
APIsnosa_dns_lookup
nosa_dns_lookup
Purpose: Resolves a domain name to its corresponding IP address.
Parameters:
hSocket
: A socket handle used for the DNS query.domain_name
: The domain name to resolve (e.g., "example.com").outBuffer
: A pointer to aDOMAIN_INFO
structure where the resolved IP address and related information will be stored.
Return Value: Returns an
NTSTATUS
code indicating success or failure.
Explanation:
This function is essential when the
host
parameter innosa_connect
is provided as a domain name rather than an IP address.It performs a DNS lookup to retrieve the IP address associated with the given domain.
The resolved information is stored in the
outBuffer
, which can then be used for establishing connections.
afd_close
afd_close
While not explicitly defined in the provided context, afd_close
appears to be a function responsible for closing the socket handle.
Assumed Function Signature:
Purpose: Closes an established socket connection.
Parameters:
hSocket
: The socket handle to be closed.
Explanation: Ensures that the socket resources are properly released, preventing resource leaks.
Last updated