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

Conversation

ol-imorozko
Copy link
Contributor

@ol-imorozko ol-imorozko commented Apr 6, 2023

Not intended to be merged by now
This is draft for the real network support functionality.

(Merges with afa19b6, which is packer revision used in Nyx-Net repository)

Ivan Morozko added 11 commits May 21, 2023 00:35
We can utilizie the sockaddr_in argument directly to establish the connection.
The IP address and port information are extracted from the server structure,
eliminating the need for the ip argument.
This commit just adds an option boilerplate code, no actual logic
are present
This commit introduces a new options to allow users to specify a
custom IP address for the client in real network scenarios.
When fuzzing server in a real network scenario, data is sended
via some client in a different network namespace. Introduced options
allow user to specify ip:port of such client.
As the shared library can be injected into any network application,
it is possible that these applications may have multiple threads
calling the hooked Socket API functions concurrently.
Without proper synchronization, simultaneous access to the global
variable `connections` by different threads may result in unexpected
behavior or data corruption.

By adding the pthread_mutex_lock and pthread_mutex_unlock calls,
we ensure that only one thread at a time can modify that variable.
This prevents race conditions and ensures consistent and correct
behavior across all threads.
Data transfer workflow

The Nyx-Net agent replaces the listen function with the underlying listen and then creates a new thread.
The thread is moved to a separate network namespace and acts as a client. Its job is to receive data from the fuzzer and transfer it.
The thread connects to the server using the real connect function and then idles, waiting for the fuzzer's notification to transfer data.
Server calls hooked accept, TCP handshake is established.
Server calls hooked recv function that does the following:
    Invokes memory snapshot, capturing the server and client after the TCP handshake.
    Gets data from the fuzzer as usual, using the handle_next_packet() function.
    Stores received data in a shared variable and notify the thread.
    Calls real recv.
When the thread receives a notification it sends the data stored in a shared variable using the real write function and then terminates.
Client will eventually get the data from its hooked recv function invocation and starts processing it.
After the data has been processed, the memory snapshot is restored and the process starts again.
Ivan Morozko added 2 commits June 8, 2023 17:59
Prior to running fuzzer we need to obtain negotiated TCP numbers.
We want fuzzer to mutate TCP headers hence we have to put them
in the initial seed. However, we cannot just send them directly
via raw socket to the target application, since it immediately will
get rejected because SEQ/ACK numbers are wrong.

After a handshake we send file with the TCP numbers to the host
using hypercall. rust_fuzzer should check this file and adjust
seeds accordingly.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant