jtpereyda / boofuzz

A fork and successor of the Sulley Fuzzing Framework

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

The callback can not capture response when fuzzing http , because the boofuzz send tcp-fin before response .

cuilu414 opened this issue · comments

Report

The callback can not capture response when fuzzing http
code:

session.connect(s_get("Request"), callback=recv_response)
session.fuzz()

def recv_response(target, fuzz_data_logger, session, test_case_context, *args, **kwargs):
    response = target.recv(1024)
    print(response)
    print(session.last_recv)

result is none:
image
the wireshark result : boofuzz send tcp-fin before response
image

Expected behavior

The boofuzz should be send tcp-fin after recevie response .

Actual behavior

No response

Steps to reproduce the problem

1.see report
2.
3.

boofuzz script

No response

boofuzz version

0.4.1

Python version

3.10

Platform

Windows

Anything else?

No response

Hi @cuilu414,
did you set receive_data_after_fuzz in your Session?
It will trigger a receive after sending a fuzzed message and save it to session.last_recv, which you can then access in the callback.

Check https://boofuzz.readthedocs.io/en/stable/source/Session.html for a brief description of the available parameters.

commented

@cuilu414 As to your case, I think this is the expected behaviour. The callback function is used to modify data in node to be sent with extra support, not to receive response from socket.

According to the following code, the callkack function will be called before self.transmit_fuzz(), which is used to send mutated data. If you try to call target.recv(1024) in callback, since the boofuzz hasn't send data to your target, you will get no response of course.

boofuzz/boofuzz/sessions.py

Lines 1766 to 1781 in 69061ef

mutation_context.protocol_session = protocol_session
callback_data = self._callback_current_node(
node=self.fuzz_node, edge=mutation_context.message_path[-1], test_case_context=protocol_session
)
self._fuzz_data_logger.open_test_step("Fuzzing Node '{0}'".format(self.fuzz_node.name))
self.transmit_fuzz(
target,
self.fuzz_node,
mutation_context.message_path[-1],
callback_data=callback_data,
mutation_context=mutation_context,
)
self._check_for_passively_detected_failures(target=target)
if not self._reuse_target_connection:
target.close()

As @SR4ven suggested above, the right way to receive response from socket is to set extra parameters in your Session, like receive_data_after_fuzz=True. Then you can access the last reponse in your custom callback via session.last_recv.

boofuzz/boofuzz/sessions.py

Lines 1204 to 1228 in 69061ef

received = b""
try: # recv
if self._receive_data_after_fuzz:
received = self.targets[0].recv()
except exception.BoofuzzTargetConnectionReset:
if self._check_data_received_each_request:
raise BoofuzzFailure(message=constants.ERR_CONN_RESET)
else:
self._fuzz_data_logger.log_info(constants.ERR_CONN_RESET)
except exception.BoofuzzTargetConnectionAborted as e:
msg = constants.ERR_CONN_ABORTED.format(socket_errno=e.socket_errno, socket_errmsg=e.socket_errmsg)
if self._check_data_received_each_request:
raise BoofuzzFailure(msg)
else:
self._fuzz_data_logger.log_info(msg)
pass
except exception.BoofuzzSSLError as e:
if self._ignore_connection_ssl_errors:
self._fuzz_data_logger.log_info(str(e))
else:
self._fuzz_data_logger.log_fail(str(e))
raise BoofuzzFailure(str(e))
self.last_recv = received

If receive_data_after_fuzz is False, and reuse_target_connection is False. After calling socket.send(), it will close the socket by calling close(). That's why you see "The boofuzz sent tcp-fin before receiving response".

Hope it helps.

Hi @cuilu414, did you set receive_data_after_fuzz in your Session? It will trigger a receive after sending a fuzzed message and save it to session.last_recv, which you can then access in the callback.

Check https://boofuzz.readthedocs.io/en/stable/source/Session.html for a brief description of the available parameters.

Thanks,receive_data_after_fuzz is work !!!

@cuilu414 As to your case, I think this is the expected behaviour. The callback function is used to modify data in node to be sent with extra support, not to receive response from socket.

According to the following code, the callkack function will be called before self.transmit_fuzz(), which is used to send mutated data. If you try to call target.recv(1024) in callback, since the boofuzz hasn't send data to your target, you will get no response of course.

boofuzz/boofuzz/sessions.py

Lines 1766 to 1781 in 69061ef

mutation_context.protocol_session = protocol_session
callback_data = self._callback_current_node(
node=self.fuzz_node, edge=mutation_context.message_path[-1], test_case_context=protocol_session
)
self._fuzz_data_logger.open_test_step("Fuzzing Node '{0}'".format(self.fuzz_node.name))
self.transmit_fuzz(
target,
self.fuzz_node,
mutation_context.message_path[-1],
callback_data=callback_data,
mutation_context=mutation_context,
)
self._check_for_passively_detected_failures(target=target)
if not self._reuse_target_connection:
target.close()

As @SR4ven suggested above, the right way to receive response from socket is to set extra parameters in your Session, like receive_data_after_fuzz=True. Then you can access the last reponse in your custom callback via session.last_recv.

boofuzz/boofuzz/sessions.py

Lines 1204 to 1228 in 69061ef

received = b""
try: # recv
if self._receive_data_after_fuzz:
received = self.targets[0].recv()
except exception.BoofuzzTargetConnectionReset:
if self._check_data_received_each_request:
raise BoofuzzFailure(message=constants.ERR_CONN_RESET)
else:
self._fuzz_data_logger.log_info(constants.ERR_CONN_RESET)
except exception.BoofuzzTargetConnectionAborted as e:
msg = constants.ERR_CONN_ABORTED.format(socket_errno=e.socket_errno, socket_errmsg=e.socket_errmsg)
if self._check_data_received_each_request:
raise BoofuzzFailure(msg)
else:
self._fuzz_data_logger.log_info(msg)
pass
except exception.BoofuzzSSLError as e:
if self._ignore_connection_ssl_errors:
self._fuzz_data_logger.log_info(str(e))
else:
self._fuzz_data_logger.log_fail(str(e))
raise BoofuzzFailure(str(e))
self.last_recv = received

If receive_data_after_fuzz is False, and reuse_target_connection is False. After calling socket.send(), it will close the socket by calling close(). That's why you see "The boofuzz sent tcp-fin before receiving response".

Hope it helps.

Thanks,receive_data_after_fuzz is work !!!

Set receive_data_after_fuzz is true,and use session.last_recv can capture response .