每天学习理解一点,记录一下
由于AFLNET是在AFLfuzz基础上实现的,新增了状态机指导fuzzing的功能,对于AFLfuzz的源码理解已经比较多了,重点理解一下AFLNET新增的部分。
计划从afl-fuzz.c的main函数入手,分析执行逻辑再对每一部分进行分析理解。
首先看看AFLNET新增的变量:
u32 server_wait_usecs是延迟时间,按照AFLNET论文所说由于AFLNET与被测试服务器没有同步机制,通过设置这个延迟时间来防止发包过快导致服务器没有处理完上一个数据包而导致丢包。
char *response_buf 作为接收服务器返回响应的缓冲区。
int response_buf_size 作为统计整个接收响应的buffer长度的变量。
u32 *response_bytes 是统计累计响应的buffer的长度,示例说 response_bytes[i]的值为从第0个响应到第i个响应从服务器接收到的响应长度值。
(这么看response_buf应该是接收了一次测试的所有响应然后通过response_buf_size和response_bytes记录每个响应的长度来获取单个响应报文)
这里应该是一些跟状态机有关的变量,具体用处等到具体函数分析的时候再看看。
EXP_ST定义在这里
是一个static的选择性编译。
EXP_ST u8 session_virgin_bits[MAP_SIZE] 记录在服务器运行中还未被覆盖的区域。MAP_SIZE等的值定义在config.h中。
EXP_ST u8 *cleanup_script 是用于清理服务器环境的文本。
EXP_ST u8 *netns_name 是用于运行服务器的network namespace名称,Linux network namespace是用来隔离网络环境的,具体细节还没有了解,如果后面需要的话补一节进行理解。
接下来是一些标志变量:
其中state_selection_algo和seed_selection_algo的值定义在aflnet.h中是状态选取策略和种子选取策略的枚举。
Agraph_t ipsm应该是使用的<graphviz/gvc.h>中的数据类型进行状态机描述的,static FILE ipsm_dot_file是记录存放状态机的.dot文件路径的。
应该是使用的klist链表存储消息、状态机路径和状态这样。可能还需要进一步看一看才知道。
这里对M2的表述不是很清楚,不过看注释应该是说M2前指针指向M1的最后一条消息,后指针指向M3的第一条消息,结合AFLNET的论文来看M2应该是一组“中间消息序列”的记录即M1为前缀消息指到达指定状态前的子消息序列,M2为指定状态的第一条消息和最后出指定状态的消息之间的子消息序列,M3为剩余的子消息序列。所以可以推测出
kliter_t(lms) M2_prev和M2_next之间为M2子消息序列。
使用的提取响应码和提取请求的函数定义在aflnet.c中。
到此对AFLNET新增的变量基本看完了,接下来准备看main函数。
2022/11/9 17:40
分析到u32 state_ids_count变量记录协议状态机状态数。
等下还是得把queue_entry 这个结构体看一看,这个挺重要的。
2022/11/9 19:30
发现有几个重要的结构体还没分析,这里补充一下
struct queue_entry {
u8* fname; /* File name for the test case */
u32 len; /* Input length */
u8 cal_failed, /* Calibration failed? */
trim_done, /* Trimmed? */
was_fuzzed, /* Had any fuzzing done yet? */
passed_det, /* Deterministic stages passed? */
has_new_cov, /* Triggers new coverage? */
var_behavior, /* Variable behavior? */
favored, /* Currently favored? */
fs_redundant; /* Marked as redundant in the fs? */
u32 bitmap_size, /* Number of bits set in bitmap */
exec_cksum; /* Checksum of the execution trace */
u64 exec_us, /* Execution time (us) */
handicap, /* Number of queue cycles behind */
depth; /* Path depth */
u8* trace_mini; /* Trace bytes, if kept */
u32 tc_ref; /* Trace bytes ref count */
struct queue_entry *next, /* Next element, if any */
*next_100; /* 100 elements ahead */
region_t *regions; /* Regions keeping information of message(s) sent to the server under test */
u32 region_count; /* Total number of regions in this seed */
u32 index; /* Index of this queue entry in the whole queue */
u32 generating_state_id; /* ID of the start at which the new seed was generated */
u8 is_initial_seed; /* Is this an initial seed */
u32 unique_state_count; /* Unique number of states traversed by this queue entry */
};
static struct queue_entry *queue, /* Fuzzing queue (linked list) */
*queue_cur, /* Current offset within the queue */
*queue_top, /* Top of the list */
*q_prev100; /* Previous 100 marker */
static struct queue_entry*
top_rated[MAP_SIZE]; /* Top entries for bitmap bytes */
queue_entry 记录了种子的基本信息。AFL通过queue 存储所有的种子,通过queue_cur 进行遍历,通过*queue_top记录队列的头。
typedef struct {
int start_byte; /* The start byte, negative if unknown. */
int end_byte; /* The last byte, negative if unknown. */
char modifiable; /* The modifiable flag. */
unsigned int *state_sequence; /* The annotation keeping the state feedback. */
unsigned int state_count; /* Number of states stored in state_sequence. */
} region_t;
typedef struct {
char *mdata; /* Buffer keeping the message data */
int msize; /* Message size */
} message_t;
typedef struct {
u32 id; /* state id */
u8 is_covered; /* has this state been covered */
u32 paths; /* total number of paths exercising this state */
u32 paths_discovered; /* total number of new paths that have been discovered when this state is targeted/selected */
u32 selected_times; /* total number of times this state has been targeted/selected */
u32 fuzzs; /* Total number of fuzzs (i.e., inputs generated) */
u32 score; /* current score of the state */
u32 selected_seed_index; /* the recently selected seed index */
void **seeds; /* keeps all seeds reaching this state -- can be casted to struct queue_entry* */
u32 seeds_count; /* total number of seeds, it must be equal the size of the seeds array */
} state_info_t;
补充一下queue_entry中region_t的结构,其被定义在aflnet.h中,再补充一下其余aflnet中定义的结构体。