欢迎进入UG环球官网(环球UG)!

usdt卖出手续费(www.payusdt.vip):Fuzz Server With AFL

admin6天前6

Filecoin官网

Filecoin官网(www.FLaCoin.vip)是Filecoin致力服务于使用Filecoin存储和检索数据的官方权威平台。Filecoin官网实时更新Filecoin(FIL)行情、当前Filecoin(FIL)矿池、Filecoin(FIL)收益数据、各类Filecoin(FIL)矿机出售信息。并开放Filecoin(FIL)交易所、Filecoin云矿机、Filecoin矿机出售、租用、招商等业务。

Problem

​ 由于小我私人偏心AFL,习习用AFL做模糊测试,发现一些CVE,然则一直苦于AFL的事情方式,由于AFL只能够从stdin/file获取输入,变异。

而网络应用多是socket或者其他network相关的通讯方式,而且默认情形下,afl每次都市重新启动程序,网络应用如server启动时间对照久,影响了模糊测试的效率。一样平常情形下,可以通过为特定的程序编写一个harness,用于fuzz程序的部门代码。然则这种方式首先需要你对源码有一定的明白,其次它的笼罩率对照低。

在网上学习发现这篇文章how-fuzz-server-american-fuzzy-lop,方式与头脑都很有学习应用的价值,翻译&应用后纪录此文。

Solution: Persistent mode

AFL的事情模式与模糊测试的主循环一致:确立新的历程,提供一个case,然后监视直到历程竣事,再重复...

为了阻止execve的开销和链接等时间消耗,AFL引入了forkserver机制,新的历程fork获得,由于copy-on-write机制,提高了性能。

但纵然云云,每次新的fuzz的差异case输入仍然会引入fork的开销。

对于许多测试目的,延续的forkinitalization的历程是一个价值较高的历程。在许多情形下,API是没有状态的,或者可以被重置为靠近原始状态的,因此至少在一次历程竣事后可以不用甩掉该历程。这就是历程内模糊测试的看法:在该方案下,测试用例是历程内部天生,并以自界说编写单历程循环的形式反馈到待测试的底层API。历程内模糊测试能够提高模糊测试效率在10x左右,然则也是有价值的:例如,它很容易由于测试代码中存在的内存泄露或者Dos而失败。

自afl-1.81b始,afl-fuzz提供了一种persistent模式——将历程内模糊测试与更传统的多历程工具的壮大功效连系起来。

在该模式下,afl将测试用例喂给一个单独的、存活时间长的历程,该历程读取输入,将其转达给待fuzz的API,并通过终止本历程通知fuzzer测试乐成运行。最终当父历程恢复时,自界说的历程循环回到起点。只需要写一个极简的harness完成这样一个循环,AFL会完成细节,如crash检查。

一个简朴的harness样例

int main(int argc, char** argv) {

  while (__AFL_LOOP(1000)) {

    /* Reset state. */
    memset(buf, 0, 100);

    /* Read input data. */
    read(0, buf, 100);

    /* Parse it in some vulnerable way. You'd normally call a library here. */
    if (buf[0] != 'p') puts("error 1"); else
    if (buf[1] != 'w') puts("error 2"); else
    if (buf[2] != 'n') puts("error 3"); else
      abort();

  }

}

Persisten模式只需要控制以下两点

1、AFL何时fork目的历程

2、AFL何时提供新的测试样例。

3、每一轮循环最先需要重置目的历程状态,否则找到的bug可能是harness的而不是目的程序的。

Persisten mode & server

大部门server实现时都市在处置client的请求后重置状态,通常,一个server的实现如下

while(go):
    req = get_request()
    process(req)

为了使用AFL persistent模式,只需要如下修改程序

while(go):
    put_request(read(file))                 //AFL
    req = get_request()
    process(req)
    notify_fuzzer()                         // AFL

Applying the tachnique in Knot DNS

Analyze

Knot DNS使用sockets通讯,其中处置udp数据包的代码在src/knot/server/udp-handler.c

主要函数udp_master中有一个循环,守候socket事宜,吸收并处置udp数据包,是一个合适的fuzz点。

int udp_master(dthread_t *thread)
{
    if (thread == NULL || thread->data == NULL) {
        return KNOT_EINVAL;
    }

    iohandler_t *handler = (iohandler_t *)thread->data;
    int thread_id = handler->thread_id[dt_get_id(thread)];

    if (handler->server->n_ifaces == 0) {
        return KNOT_EOK;
    }

    /* Set thread affinity to CPU core (same for UDP and XDP). */
    unsigned cpu = dt_online_cpus();
    if (cpu > 1) {
        unsigned cpu_mask = (dt_get_id(thread) % cpu);
        dt_setaffinity(thread, &cpu_mask, 1);
    }

    /* Choose processing API. */
    udp_api_t *api = NULL;
    if (is_xdp_thread(handler->server->ifaces, thread_id)) {
,ifdef ENABLE_XDP
        api = &xdp_recvmmsg_api;
,else
        assert(0);
,endif
    } else {
,ifdef ENABLE_RECVMMSG
        api = &udp_recvmmsg_api;
,else
        api = &udp_recvfrom_api;
,endif
    }
    void *rq = api->udp_init();

    /* Create big enough memory cushion. */
    knot_mm_t mm;
    mm_ctx_mempool(&mm, 16 * MM_DEFAULT_BLKSIZE);

    /* Create UDP answering context. */
    udp_context_t udp = {
        .server = handler->server,
        .thread_id = thread_id,
    };
    knot_layer_init(&udp.layer, &mm, process_query_layer());

    /* Allocate descriptors for the configured interfaces. */
    void *xdp_socket = NULL;
    size_t nifs = handler->server->n_ifaces;
    fdset_t fds;
    if (fdset_init(&fds, nifs) != KNOT_EOK) {
        goto finish;
    }
    unsigned nfds = udp_set_ifaces(handler->server->ifaces, nifs, &fds,
                                   thread_id, &xdp_socket);
    if (nfds == 0) {
        goto finish;
    }
    //** AFL 在主循环之前 界说变量 Shim1**// 

    /* Loop until all data is read. */
    //** 循环守候socket事宜,吸收并处置udp数据包 **/
    for (;;) {
        /* Cancellation point. */
        if (dt_is_cancelled(thread)) {
            break;
        }

        /* Wait for events. */
        fdset_it_t it;
        (void)fdset_poll(&fds, &it, 0, -1);

        // ** AFL:读取输入文件 Shim2**/ 
        /* Process the events. */
        for (; !fdset_it_is_done(&it); fdset_it_next(&it)) {
            if (!fdset_it_is_pollin(&it)) {
                continue;
            }
            if (api->udp_recv(fdset_it_get_fd(&it), rq, xdp_socket) > 0) {
                api->udp_handle(&udp, rq, xdp_socket);
                api->udp_send(rq, xdp_socket);
            }
        }

        //** AFL: 通知fuzzer processing complete Shim3**/
    }

finish:
    api->udp_deinit(rq);
    mp_delete(mm.ctx);
    fdset_clear(&fds);

    return KNOT_EOK;
}
First shim

第一个shim认真界说、初始化用于后续shim的变量

,ifdef KNOT_AFL_PERSISTENT_SHIM  /* For AFL persistent mode fuzzing shim  */

    /* Initialize variables for fuzzing */
    size_t insize;
    struct sockaddr_in servaddr;
    int udp_socket; 
    char *env_dest_ip = getenv("KNOT_AFL_DEST_IP");
    char *env_dest_port = getenv("KNOT_AFL_DEST_PORT");
    int dest_port = env_dest_port ? strtol(env_dest_port, NULL, 10) : 9090;
    char *dest_ip = env_dest_ip ? env_dest_ip : "127.0.0.1";
    bzero(&servaddr,sizeof(servaddr));
    servaddr.sin_family = AF_INET; 
    servaddr.sin_addr.s_addr = inet_addr(dest_ip);
    servaddr.sin_port = htons(dest_port); 
    char buf[5120]; 

,endif // ,ifdef KNOT_AFL_PERSISTENT_SHIM
Second shim

认真从文件中获取测试样例,并将内容填充到Knot DNS监听的socket中,利便起见,这里直接从stdin获取输入

,ifdef KNOT_AFL_PERSISTENT_SHIM  /* For AFL persistent mode fuzzing shim  */

        /* Read fuzzed packet from stdin and send to socket */
        if (getenv("KNOT_AFL_STDIN") || getenv("KNOT_AFL_CMIN") ||
                getenv("AFL_PERSISTENT")) {
            memset(buf, 0, 5120);
            insize = read(0, buf, 5120);                        // read fuzz case from stdin
            udp_socket = handler->server->ifaces->fd_udp[0];
            sendto(udp_socket, buf, insize,0, (struct sockaddr *)&servaddr,sizeof(servaddr));
        }

,endif // ,ifdef KNOT_AFL_PERSISTENT_SHIM
Third shim

最后一个shim就是认真终止本历程,通知fuzzer本次测试完成(通过SIGSTOP信号),以便fuzzer处置下一个测试样例

,ifdef KNOT_AFL_PERSISTENT_SHIM  /* For AFL persistent mode fuzzing shim  */
        /* Signal AFL to fuzz input and continue execution */
        if (getenv("AFL_PERSISTENT")) {
            raise(SIGSTOP);
        } else if (getenv("KNOT_AFL_CMIN")) {
            exit(0);
        }
,endif // ,ifdef KNOT_AFL_PERSISTENT_SHIM
Configure and compile target
CC=~/path-afl/afl-clang-fast CFLAGS='-DKNOT_AFL_PERSISTENT_SHIM' ./configure --disable-shared
make
How run knot server

这些可以在knot项目的Readme中获得

1、首先需要config,使用的./tests-fuzz/knotd_wrap/knot_stdio.conf

2、事情目录,确立config指定的事情目录

3、启动server: src/knotd

Minimize test cases
KNOT_AFL_CMIN=1 ~/path-afl/afl-cmin -i in -o cmin -- ./src/knot -c my_config.config
KNOT_AFL_CMIN=1 ~/treebacker/fuzzwork/mm_afl/afl-2.52b/afl-cmin -i  -o cmin -- ./src/knotd -c my_config.conf
Start fuzzing in persistent mode
AFL_PERSISTENT=1 ~/path-afl/afl-fuzz -i cmin -o out -- ./src/knot -c my_config.conf

More

其着实Knot-dns项目中,我们能找到开发者自己使用AFL测试的几个点:fuzz_packet; fuzz_dnamr_from_str; fuzz_dname_to_str, fuzz_zscanner..

也是为fuzz目的提供一个function wrapper, 最终可以行使AFL从文件获取内容,fuzz一个挪用这个function wrapper的harness。

而且也保留了一个knotd_wrap,重写了udp, tcp 的recv方式,从stdin读取,便于afl模糊测试。

Refer

New in AFL

how-fuzz-server-american-fuzzy-lop

Knot-dns-Project,,,, Fuzz Server With AFL

,

usdt支付接口

菜宝钱包(www.caibao.it)是使用TRC-20协议的Usdt第三方支付平台,Usdt收款平台、Usdt自动充提平台、usdt跑分平台。免费提供入金通道、Usdt钱包支付接口、Usdt自动充值接口、Usdt无需实名寄售回收。菜宝Usdt钱包一键生成Usdt钱包、一键调用API接口、一键无实名出售Usdt。

,

Problem

​ 由于小我私人偏心AFL,习习用AFL做模糊测试,发现一些CVE,然则一直苦于AFL的事情方式,由于AFL只能够从stdin/file获取输入,变异。

而网络应用多是socket或者其他network相关的通讯方式,而且默认情形下,afl每次都市重新启动程序,网络应用如server启动时间对照久,影响了模糊测试的效率。一样平常情形下,可以通过为特定的程序编写一个harness,用于fuzz程序的部门代码。然则这种方式首先需要你对源码有一定的明白,其次它的笼罩率对照低。

在网上学习发现这篇文章,方式与头脑都很有学习应用的价值,翻译&应用后纪录此文。

Solution: Persistent mode

AFL的事情模式与模糊测试的主循环一致:确立新的历程,提供一个case,然后监视直到历程竣事,再重复...

为了阻止execve的开销和链接等时间消耗,AFL引入了forkserver机制,新的历程fork获得,由于copy-on-write机制,提高了性能。

但纵然云云,每次新的fuzz的差异case输入仍然会引入fork的开销。

对于许多测试目的,延续的forkinitalization的历程是一个价值较高的历程。在许多情形下,API是没有状态的,或者可以被重置为靠近原始状态的,因此至少在一次历程竣事后可以不用甩掉该历程。这就是历程内模糊测试的看法:在该方案下,测试用例是历程内部天生,并以自界说编写单历程循环的形式反馈到待测试的底层API。历程内模糊测试能够提高模糊测试效率在10x左右,然则也是有价值的:例如,它很容易由于测试代码中存在的内存泄露或者Dos而失败。

自afl-1.81b始,afl-fuzz提供了一种persistent模式——将历程内模糊测试与更传统的多历程工具的壮大功效连系起来。

在该模式下,afl将测试用例喂给一个单独的、存活时间长的历程,该历程读取输入,将其转达给待fuzz的API,并通过终止本历程通知fuzzer测试乐成运行。最终当父历程恢复时,自界说的历程循环回到起点。只需要写一个极简的harness完成这样一个循环,AFL会完成细节,如crash检查。

一个简朴的harness样例

int main(int argc, char** argv) {

  while (__AFL_LOOP(1000)) {

    /* Reset state. */
    memset(buf, 0, 100);

    /* Read input data. */
    read(0, buf, 100);

    /* Parse it in some vulnerable way. You'd normally call a library here. */
    if (buf[0] != 'p') puts("error 1"); else
    if (buf[1] != 'w') puts("error 2"); else
    if (buf[2] != 'n') puts("error 3"); else
      abort();

  }

}

Persisten模式只需要控制以下两点

1、AFL何时fork目的历程

2、AFL何时提供新的测试样例。

3、每一轮循环最先需要重置目的历程状态,否则找到的bug可能是harness的而不是目的程序的。

Persisten mode & server

大部门server实现时都市在处置client的请求后重置状态,通常,一个server的实现如下

while(go):
    req = get_request()
    process(req)

为了使用AFL persistent模式,只需要如下修改程序

while(go):
    put_request(read(file))                 //AFL
    req = get_request()
    process(req)
    notify_fuzzer()                         // AFL

Applying the tachnique in Knot DNS

Analyze

Knot DNS使用sockets通讯,其中处置udp数据包的代码在src/knot/server/udp-handler.c

主要函数udp_master中有一个循环,守候socket事宜,吸收并处置udp数据包,是一个合适的fuzz点。

int udp_master(dthread_t *thread)
{
    if (thread == NULL || thread->data == NULL) {
        return KNOT_EINVAL;
    }

    iohandler_t *handler = (iohandler_t *)thread->data;
    int thread_id = handler->thread_id[dt_get_id(thread)];

    if (handler->server->n_ifaces == 0) {
        return KNOT_EOK;
    }

    /* Set thread affinity to CPU core (same for UDP and XDP). */
    unsigned cpu = dt_online_cpus();
    if (cpu > 1) {
        unsigned cpu_mask = (dt_get_id(thread) % cpu);
        dt_setaffinity(thread, &cpu_mask, 1);
    }

    /* Choose processing API. */
    udp_api_t *api = NULL;
    if (is_xdp_thread(handler->server->ifaces, thread_id)) {
,ifdef ENABLE_XDP
        api = &xdp_recvmmsg_api;
,else
        assert(0);
,endif
    } else {
,ifdef ENABLE_RECVMMSG
        api = &udp_recvmmsg_api;
,else
        api = &udp_recvfrom_api;
,endif
    }
    void *rq = api->udp_init();

    /* Create big enough memory cushion. */
    knot_mm_t mm;
    mm_ctx_mempool(&mm, 16 * MM_DEFAULT_BLKSIZE);

    /* Create UDP answering context. */
    udp_context_t udp = {
        .server = handler->server,
        .thread_id = thread_id,
    };
    knot_layer_init(&udp.layer, &mm, process_query_layer());

    /* Allocate descriptors for the configured interfaces. */
    void *xdp_socket = NULL;
    size_t nifs = handler->server->n_ifaces;
    fdset_t fds;
    if (fdset_init(&fds, nifs) != KNOT_EOK) {
        goto finish;
    }
    unsigned nfds = udp_set_ifaces(handler->server->ifaces, nifs, &fds,
                                   thread_id, &xdp_socket);
    if (nfds == 0) {
        goto finish;
    }
    //** AFL 在主循环之前 界说变量 Shim1**// 

    /* Loop until all data is read. */
    //** 循环守候socket事宜,吸收并处置udp数据包 **/
    for (;;) {
        /* Cancellation point. */
        if (dt_is_cancelled(thread)) {
            break;
        }

        /* Wait for events. */
        fdset_it_t it;
        (void)fdset_poll(&fds, &it, 0, -1);

        // ** AFL:读取输入文件 Shim2**/ 
        /* Process the events. */
        for (; !fdset_it_is_done(&it); fdset_it_next(&it)) {
            if (!fdset_it_is_pollin(&it)) {
                continue;
            }
            if (api->udp_recv(fdset_it_get_fd(&it), rq, xdp_socket) > 0) {
                api->udp_handle(&udp, rq, xdp_socket);
                api->udp_send(rq, xdp_socket);
            }
        }

        //** AFL: 通知fuzzer processing complete Shim3**/
    }

finish:
    api->udp_deinit(rq);
    mp_delete(mm.ctx);
    fdset_clear(&fds);

    return KNOT_EOK;
}
First shim

第一个shim认真界说、初始化用于后续shim的变量

,ifdef KNOT_AFL_PERSISTENT_SHIM  /* For AFL persistent mode fuzzing shim  */

    /* Initialize variables for fuzzing */
    size_t insize;
    struct sockaddr_in servaddr;
    int udp_socket; 
    char *env_dest_ip = getenv("KNOT_AFL_DEST_IP");
    char *env_dest_port = getenv("KNOT_AFL_DEST_PORT");
    int dest_port = env_dest_port ? strtol(env_dest_port, NULL, 10) : 9090;
    char *dest_ip = env_dest_ip ? env_dest_ip : "127.0.0.1";
    bzero(&servaddr,sizeof(servaddr));
    servaddr.sin_family = AF_INET; 
    servaddr.sin_addr.s_addr = inet_addr(dest_ip);
    servaddr.sin_port = htons(dest_port); 
    char buf[5120]; 

,endif // ,ifdef KNOT_AFL_PERSISTENT_SHIM
Second shim

认真从文件中获取测试样例,并将内容填充到Knot DNS监听的socket中,利便起见,这里直接从stdin获取输入

,ifdef KNOT_AFL_PERSISTENT_SHIM  /* For AFL persistent mode fuzzing shim  */

        /* Read fuzzed packet from stdin and send to socket */
        if (getenv("KNOT_AFL_STDIN") || getenv("KNOT_AFL_CMIN") ||
                getenv("AFL_PERSISTENT")) {
            memset(buf, 0, 5120);
            insize = read(0, buf, 5120);                        // read fuzz case from stdin
            udp_socket = handler->server->ifaces->fd_udp[0];
            sendto(udp_socket, buf, insize,0, (struct sockaddr *)&servaddr,sizeof(servaddr));
        }

,endif // ,ifdef KNOT_AFL_PERSISTENT_SHIM
Third shim

最后一个shim就是认真终止本历程,通知fuzzer本次测试完成(通过SIGSTOP信号),以便fuzzer处置下一个测试样例

,ifdef KNOT_AFL_PERSISTENT_SHIM  /* For AFL persistent mode fuzzing shim  */
        /* Signal AFL to fuzz input and continue execution */
        if (getenv("AFL_PERSISTENT")) {
            raise(SIGSTOP);
        } else if (getenv("KNOT_AFL_CMIN")) {
            exit(0);
        }
,endif // ,ifdef KNOT_AFL_PERSISTENT_SHIM
Configure and compile target
CC=~/path-afl/afl-clang-fast CFLAGS='-DKNOT_AFL_PERSISTENT_SHIM' ./configure --disable-shared
make
How run knot server

这些可以在knot项目的Readme中获得

1、首先需要config,使用的./tests-fuzz/knotd_wrap/knot_stdio.conf

2、事情目录,确立config指定的事情目录

3、启动server: src/knotd

Minimize test cases
KNOT_AFL_CMIN=1 ~/path-afl/afl-cmin -i in -o cmin -- ./src/knot -c my_config.config
KNOT_AFL_CMIN=1 ~/treebacker/fuzzwork/mm_afl/afl-2.52b/afl-cmin -i  -o cmin -- ./src/knotd -c my_config.conf
Start fuzzing in persistent mode
AFL_PERSISTENT=1 ~/path-afl/afl-fuzz -i cmin -o out -- ./src/knot -c my_config.conf

More

其着实Knot-dns项目中,我们能找到开发者自己使用AFL测试的几个点:fuzz_packet; fuzz_dnamr_from_str; fuzz_dname_to_str, fuzz_zscanner..

也是为fuzz目的提供一个function wrapper, 最终可以行使AFL从文件获取内容,fuzz一个挪用这个function wrapper的harness。

而且也保留了一个knotd_wrap,重写了udp, tcp 的recv方式,从stdin读取,便于afl模糊测试。

Refer

New in AFL

how-fuzz-server-american-fuzzy-lop

Knot-dns-Project

上一篇 下一篇

猜你喜欢

网友评论

随机文章
热门文章
热评文章
热门标签