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

Real network support #23

Draft
wants to merge 13 commits into
base: main
Choose a base branch
from
Draft
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
212 changes: 212 additions & 0 deletions README-Realnetwork.md

Large diffs are not rendered by default.

93 changes: 93 additions & 0 deletions modify_seq_ack.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import glob
import socket
import time
import struct
import sys
import os

def checksum(msg):
if len(msg) % 2 != 0:
msg += struct.pack('!B', 0)

s = 0
# loop taking 2 characters at a time
for i in range(0, len(msg), 2):
w = (msg[i] << 8) + msg[i+1]
s = s + w

s = (s>>16) + (s & 0xffff);
#s = s + (s >> 16);
#complement and mask to 4 byte short
s = ~s & 0xffff

return s

def calculate_checksum(source_ip, dest_ip, tcp_header, tcp_data):
pseudo_header = struct.pack('!4s4sBBH',
socket.inet_aton(source_ip),
socket.inet_aton(dest_ip),
0,
socket.IPPROTO_TCP,
len(tcp_header) + len(tcp_data))

return checksum(pseudo_header + tcp_header + tcp_data)

def modify_seed(new_syn_seq_num, new_synack_seq_num, file_name, source_ip, dest_ip):
# Open the file and read its contents
with open(file_name, 'rb') as f:
file_data = f.read()

# Extract old sequence numbers from the file
old_syn_seq_num, old_synack_seq_num = struct.unpack('!II', file_data[:8]) # '!II' means two unsigned integers in network byte order

# Remove the first 8 bytes from the file data and split it by CRLF
packets = file_data[8:].split(b'\r\n')

# Calculate relative sequence and acknowledgment numbers for each packet
for i in range(len(packets) - 1): # exclude last empty packet after final split
packet = packets[i]
# sequence and acknowledgment numbers are located at 4-8 and 8-12 bytes of TCP header
seq_num, ack_num = struct.unpack('!II', packet[4:12])
relative_seq_num = seq_num - old_syn_seq_num
relative_ack_num = ack_num - old_synack_seq_num
print(relative_seq_num, relative_ack_num)

# Calculate new sequence and acknowledgment numbers
new_seq_num = new_syn_seq_num + relative_seq_num
new_ack_num = new_synack_seq_num + relative_ack_num

# Replace the sequence and acknowledgment numbers in the packet
packets[i] = packet[:4] + struct.pack('!II', new_seq_num, new_ack_num) + packet[12:]

for i in range(len(packets) - 1): # exclude last empty packet after final split
# Recalculate the checksum
tcp_header = packets[i][:20]
tcp_data = packets[i][20:]
tcp_data += b'\r\n'
# Make checksum field in TCP header zero
tcp_header = tcp_header[:16] + struct.pack('!H', 0) + tcp_header[18:]

checksum = calculate_checksum(source_ip, dest_ip, tcp_header, tcp_data)

# Insert the new checksum into the TCP header
packets[i] = tcp_header[:16] + struct.pack('!H', checksum) + tcp_header[18:] + tcp_data
print("new checksum is ", checksum)

# Join the packets back together and write the result to the file
with open(file_name, 'wb') as f:
for packet in packets:
f.write(packet)

# Verify command line arguments
if len(sys.argv) != 5:
print("Usage: python script.py <client_ip> <server_ip> <client_seq_num> <server_seq_num>")
sys.exit(1)

client_ip = sys.argv[1]
server_ip = sys.argv[2]
syn_seq_num = int(sys.argv[3])
synack_seq_num = int(sys.argv[4])

for path in glob.glob("lightftpd/*.raw"):
modify_seed(syn_seq_num, synack_seq_num, path, client_ip, server_ip)

3 changes: 3 additions & 0 deletions packer/common/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,9 @@ def __load_arguments(self):
nyx_net_group.add_argument('--nyx_net_port', metavar='<nyx_net_port>', help='fuzz specified network port', default=0, type=int)
nyx_net_group.add_argument('--nyx_net_udp', help='fuzz UDP port instead TCP', action='store_true', default=False)
nyx_net_group.add_argument('--nyx_net_client_mode', help='fuzz target in client mode', action='store_true', default=False)
nyx_net_group.add_argument('--nyx_net_real_network_mode', help='Use real network to transfer data to target', action='store_true', default=False)
nyx_net_group.add_argument('--nyx_net_client_ip', metavar='<ip addr>', help='specify client ip (useful with real network mode)', default="127.0.0.1", type=str)
nyx_net_group.add_argument('--nyx_net_client_port', metavar='<port>', help='specify client port (useful with real network mode)', default=0, type=int)
nyx_net_group.add_argument('--nyx_net_stdin', help='use file as stdin input', action=FullPath, type=parse_is_file)

nyx_net_group = parser.add_argument_group("Nyx-Net Extras")
Expand Down
2 changes: 1 addition & 1 deletion packer/linux_x86_64-userspace/compile_32.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ else

if [ "$NET_FUZZ" = "ON" ]
then
MODE="${UDP_MODE} ${CLIENT_MODE} ${DEBUG_MODE} ${STDOUT_STDERR_DEBUG}"
MODE="${UDP_MODE} ${CLIENT_MODE} ${DEBUG_MODE} ${STDOUT_STDERR_DEBUG} ${REAL_NETWORK_MODE}"
echo "MODES => $MODE"
clang -shared -g -O0 -m32 -Werror $EXTRA $MODE -fPIC src/ld_preload_fuzz.c src/misc/crash_handler.c src/misc/harness_state.c src/netfuzz/inject.c src/netfuzz/syscalls.c src/netfuzz/socket_cache.c -I../../ -DNET_FUZZ -I$NYX_SPEC_FOLDER -o bin32/ld_preload_fuzz.so -ldl -Isrc
clang -shared -g -O0 -m32 -Werror -DNO_PT_NYX $EXTRA $MODE -fPIC src/ld_preload_fuzz.c src/misc/crash_handler.c src/misc/harness_state.c src/netfuzz/inject.c src/netfuzz/syscalls.c src/netfuzz/socket_cache.c -I../../ -DNET_FUZZ -I$NYX_SPEC_FOLDER -o bin32/ld_preload_fuzz_no_pt.so -ldl -Isrc
Expand Down
6 changes: 3 additions & 3 deletions packer/linux_x86_64-userspace/compile_64.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ else

if [ "$NET_FUZZ" = "ON" ]
then
MODE="${UDP_MODE} ${CLIENT_MODE} ${DEBUG_MODE} ${STDOUT_STDERR_DEBUG}"
MODE="${UDP_MODE} ${CLIENT_MODE} ${DEBUG_MODE} ${STDOUT_STDERR_DEBUG} ${REAL_NETWORK_MODE}"
#echo "MODES => $MODE"
clang -shared -g -O0 -m64 -Werror $EXTRA $MODE -fPIC src/ld_preload_fuzz.c src/misc/crash_handler.c src/misc/harness_state.c src/netfuzz/inject.c src/netfuzz/syscalls.c src/netfuzz/socket_cache.c -I../../ -DNET_FUZZ -I$NYX_SPEC_FOLDER -o bin64/ld_preload_fuzz.so -ldl -Isrc
clang -shared -g -O0 -m64 -Werror -DNO_PT_NYX $EXTRA $MODE -fPIC src/ld_preload_fuzz.c src/misc/crash_handler.c src/misc/harness_state.c src/netfuzz/inject.c src/netfuzz/syscalls.c src/netfuzz/socket_cache.c -I../../ -DNET_FUZZ -I$NYX_SPEC_FOLDER -o bin64/ld_preload_fuzz_no_pt.so -ldl -Isrc
clang -shared -g -O0 -m64 -Werror $EXTRA $MODE -fPIC src/ld_preload_fuzz.c src/misc/crash_handler.c src/misc/harness_state.c src/netfuzz/inject.c src/netfuzz/syscalls.c src/netfuzz/socket_cache.c -I../../ -DNET_FUZZ -I$NYX_SPEC_FOLDER -o bin64/ld_preload_fuzz.so -ldl -Isrc -pthread
clang -shared -g -O0 -m64 -Werror -DNO_PT_NYX $EXTRA $MODE -fPIC src/ld_preload_fuzz.c src/misc/crash_handler.c src/misc/harness_state.c src/netfuzz/inject.c src/netfuzz/syscalls.c src/netfuzz/socket_cache.c -I../../ -DNET_FUZZ -I$NYX_SPEC_FOLDER -o bin64/ld_preload_fuzz_no_pt.so -ldl -Isrc -pthread

else

Expand Down
2 changes: 1 addition & 1 deletion packer/linux_x86_64-userspace/src/loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,4 +155,4 @@ int main(int argc, char** argv){
}
printf("Usage: <loader>\n");
return 0;
}
}
32 changes: 32 additions & 0 deletions packer/linux_x86_64-userspace/src/misc/harness_state.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#define _GNU_SOURCE

#include <stdlib.h>
#include <arpa/inet.h>
#include <dlfcn.h>
#include "misc/harness_state.h"
#include "netfuzz/syscalls.h"
Expand Down Expand Up @@ -34,6 +35,13 @@ static bool check_env(const char* env){
return ret;
}

static bool validate_ip_addr(const char *ip_addr)
{
struct in_addr ipv4_binary;

return inet_pton(AF_INET, ip_addr, &ipv4_binary) == 1;
}

void set_harness_state(void){
harness_state_t* state = get_harness_state();

Expand All @@ -53,6 +61,29 @@ void set_harness_state(void){
state->nyx_net_port = 0;
}

if(real_getenv("NYX_NET_CLIENT_IP_ADDR")){
char *ip_addr = real_getenv("NYX_NET_CLIENT_IP_ADDR");

if (!validate_ip_addr(ip_addr))
{
hprintf("Invalid IPv4 address in NYX_NET_CLIENT_IP_ADDR environment variable.\n");
exit(EXIT_FAILURE);
}

strncpy(state->nyx_net_client_ip_addr, ip_addr, INET_ADDRSTRLEN - 1);
state->nyx_net_client_ip_addr[INET_ADDRSTRLEN - 1] = '\0'; // Ensure null-termination
}
else{
strcpy(state->nyx_net_client_ip_addr, "127.0.0.1");
}

if(real_getenv("NYX_NET_CLIENT_PORT")){
state->nyx_net_client_port = (uint16_t)strtol(real_getenv("NYX_NET_CLIENT_PORT"), NULL, 10);
}
else{
state->nyx_net_client_port = 0;
}

#ifdef DEBUG_HARNESS_STATE
hprintf("fast_exit_mode: %d\n", state->fast_exit_mode);
hprintf("asan_executable: %d\n", state->asan_executable);
Expand All @@ -63,6 +94,7 @@ void set_harness_state(void){
hprintf("pt_auto_addr_range_a: %d\n", state->pt_auto_addr_range_a);
hprintf("pt_auto_addr_range_b: %d\n", state->pt_auto_addr_range_b);
hprintf("NYX_NET_PORT: %d\n", state->nyx_net_port);
hprintf("NYX_NET_CLIENT_IP_ADDR: %s\n", state->NYX_NET_CLIENT_IP_ADDR);
#endif

harness_state_ready = true;
Expand Down
3 changes: 3 additions & 0 deletions packer/linux_x86_64-userspace/src/misc/harness_state.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include <netinet/in.h>
#include <stdbool.h>
#include <stdint.h>

Expand All @@ -14,6 +15,8 @@ typedef struct harness_state_s{
bool pt_auto_addr_range_a;
bool pt_auto_addr_range_b;
uint16_t nyx_net_port;
char nyx_net_client_ip_addr[INET_ADDRSTRLEN];
uint16_t nyx_net_client_port;
} harness_state_t;

harness_state_t* get_harness_state(void);
Expand Down
62 changes: 46 additions & 16 deletions packer/linux_x86_64-userspace/src/netfuzz/inject.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,9 @@ static inline void init_nyx(void){
static bool init_done = false;
if(!init_done){
DEBUG("%s: init_done = false\n", __func__);
#if REAL_NETWORK_MODE
wait_for_client();
#endif
nyx_init_start();
init_done = true;
}
Expand Down Expand Up @@ -344,11 +347,23 @@ ssize_t recv(int sockfd, void *buf, size_t len, int flags){
//int client_socket = server_socket_to_client_socket(sockfd);
//if(client_socket != -1){
DEBUG("%s --> %d\n", __func__, sockfd);
#ifdef REAL_NETWORK_MODE
char buff_for_send[8200] = {0};
#endif

if(server_socket_exists(sockfd)){
#ifndef NET_STANDALONE
init_nyx();
#ifdef REAL_NETWORK_MODE
size_t data_len = handle_next_packet(sockfd, buff_for_send, len, false);

//notify client thread
send_malformed_data(buff_for_send, data_len);

return real_recv(sockfd, buf, len, flags);
#else
return handle_next_packet(sockfd, buf, len, false);
#endif
#endif

//hprintf("%s: not implemented\n", __func__);
Expand Down Expand Up @@ -595,6 +610,7 @@ int close(int fd){
/* broken ? */
if(get_active_connections() == 0){
DEBUG("RELEASE!\n");
real_close(fd);
//while(1){}
//
//}
Expand Down Expand Up @@ -660,9 +676,9 @@ int poll(struct pollfd *fds, nfds_t nfds, int timeout){

extern void foo(void);

int connect_to_server(const char* ip, int port){
int connect_to_server(struct sockaddr_in *server){
int socket_desc;
struct sockaddr_in server;
uint16_t port = ntohs(server->sin_port);

DEBUG("%s enter\n", __func__);

Expand Down Expand Up @@ -700,13 +716,10 @@ int connect_to_server(const char* ip, int port){
exit(-1);
}

server.sin_addr.s_addr = inet_addr(ip); //inet_addr(ip); //"74.125.235.20");
server.sin_family = AF_INET;
server.sin_port = htons(port);

//Connect to remote server
//printf("%s: connect to socket...\n", __func__);
if (connect(socket_desc , (struct sockaddr *)&server , sizeof(server)) < 0)
if (connect(socket_desc , (struct sockaddr *)server , sizeof(*server)) < 0)
{
DEBUG("connect error %s", strerror(errno));
exit(-1);
Expand Down Expand Up @@ -751,6 +764,17 @@ int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen){
return accept4(sockfd, addr, addrlen, 0);
}

static void get_client_sockaddr(struct sockaddr_in *addr)
{
addr->sin_family = AF_INET;
addr->sin_port = htons(get_harness_state()->nyx_net_client_port);
if (inet_pton(AF_INET, get_harness_state()->nyx_net_client_ip_addr, &addr->sin_addr) < 0)
{
hprintf("inet_pton failed: %s\n", strerror(errno));
exit(-1);
}
}

#ifdef UDP_MODE
#ifndef CLIENT_MODE
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen){
Expand Down Expand Up @@ -782,7 +806,7 @@ int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen){

add_connection(ntohs(((struct sockaddr_in*)addr)->sin_port));

connect_to_server("127.0.0.1", ntohs(((struct sockaddr_in*)addr)->sin_port)); /* fix me */
connect_to_server((struct sockaddr_in*)addr);
//hprintf("%s %d %d\n", __func__, tmp_addr.sin_port, ret);
assert(set_server_socket_to_connection(ntohs(((struct sockaddr_in*)addr)->sin_port), sockfd));
}
Expand Down Expand Up @@ -824,30 +848,36 @@ int accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen){
#ifndef CLIENT_MODE

int listen(int sockfd, int backlog){
struct sockaddr_in addr;
struct sockaddr_in server_addr;
int len = sizeof(struct sockaddr);

//hprintf("=== %s\n", __func__);

int ret = -1;

if(getsockname(sockfd, (struct sockaddr *) &addr, (void*)&len) != -1){
if(getsockname(sockfd, (struct sockaddr *) &server_addr, (void*)&len) != -1){

bool exists = connection_exists(ntohs(addr.sin_port));
bool exists = connection_exists(ntohs(server_addr.sin_port));

if(!exists){
DEBUG("%s: port number %d\n", __func__, ntohs(addr.sin_port));
DEBUG("%s: port number %d\n", __func__, ntohs(server_addr.sin_port));
}

ret = real_listen(sockfd, backlog);

if(!exists){
if(is_target_port(ntohs(addr.sin_port))){
add_connection(ntohs(addr.sin_port));
connect_to_server("127.0.0.1", ntohs(addr.sin_port)); /* fix me */
DEBUG("%s: DONE \n", __func__);
if(is_target_port(ntohs(server_addr.sin_port))){
add_connection(ntohs(server_addr.sin_port));

}
#ifdef REAL_NETWORK_MODE
struct sockaddr_in client_addr;
get_client_sockaddr(&client_addr);
create_client(&server_addr, &client_addr);
#else
connect_to_server(&server_addr);
#endif
DEBUG("%s: DONE \n", __func__);
}
}
}

Expand Down
Loading