IoT小设备HTTP漏洞挖掘研究:BOA篇
BOA是IoT小设备上常见的HTTPD之一。本文将从源码分析、漏洞挖掘、真实漏洞分析三个部分总结BOA的相关特性。其中,源码分析部分涉及到Linux网络编程,漏洞挖掘部分主要关注于如何快速恢复请求结构体、了解数据包处理逻辑以及CGI如何传递数据,真实漏洞分析部分则是分析了三个典型的BOA认证前漏洞,其中两个能够导致认证前任意代码执行,一个认证前信息泄漏。 一、BOA简介 BOA是一个单任务的HTTPD,简单说,BOA不像常见的HTTPD,为每一个连接使用fork创建子进程进行处理,也不会提前创建一个进程池、线程池用于同时处理多个连接。它在内部采用了多路复用和请求链表来处理所有来自客户端的连接,并且仅仅针对CGI程序、自动目录生成和自动文件压缩采用fork子进程的形式进行处理。简而言之,BOA是一个轻量级的HTTP服务器,主要设计用于嵌入式系统,以高效的性能和小巧的代码体积著称,通常被应用于资源受限的设备,例如路由器、智能家居或者其他的嵌入式环境。 BOA具有如下的一些特点: 单线程架构:BOA采用了单线程、事件驱动的架构来处理多个HTTP请求。传统的WEB服务器会为每一个请求使用fork创建子进程进行处理,每次请求都会造成进程创建的开销。BOA的架构避免了这种操作,从而节省了系统资源。但是,只能说BOA适合嵌入式这种请求速度慢、并发少的情景。 资源占用低:BOA的代码体积非常小,内存和CPU的使用效率高,适用于资源受限的嵌入式设备。 配置简单:BOA的配置文件简单明了,容易调整和优化,可以快速进行部署。 快速响应:单线程事件驱动模型使得在轻负载情况下响应迅速,适用于处理少量并发连接。 BOA的源码和官方文档都可以在Boa Webserver处找到。 二、BOA源码分析(TL;DR) 本章节从源码分析BOA,主要从常规分析HTTPD源码的角度,例如信号量处理、socket从创建到复用、CGI数据传递等,帮助更好理解BOA的运行特性。该部分篇幅过长,对Linux网络编程已经较为熟悉的师傅可以跳过到2.4节BOA的请求结构体说明部分和2.5节状态机处理数据包示意图部分。 2.1 信号量处理 HTTPD服务器会处理一些常见的信号量,以免HTTPD发生异常终止。在BOA中也是如此,main函数中调用函数init_signals,收到指定的信号时,执行预先设定的处理函数。 信号量的处理一般是如下流程: 创建信号量处理相关的结构体变量。 初始化清空信号量集合。 将需要关注的信号量以及对应信号量的处理函数加入到信号量集合中。 当HTTPD接收到相应的信号量时,执行预先设定的处理函数。 BOA源码中,对信号量的处理也是满足如上的流程。 /* * Name: init_signals * Description: Sets up signal handlers for all our friends. */ void init_signals(void) // 初始化信号处理函数,收到指定信号的时候,执行预定义的处理函数 { struct sigaction sa; // 不使用任何特殊标志 sa.sa_flags = 0; // 初始化信号屏蔽集sa_mask // 将如下的几个信号量,添加到sa_mask中 sigemptyset(&sa.sa_mask); sigaddset(&sa.sa_mask, SIGSEGV); // 段错误 sigaddset(&sa.sa_mask, SIGBUS); // 总线错误 sigaddset(&sa.sa_mask, SIGTERM); // 终止信号 sigaddset(&sa.sa_mask, SIGHUP); // 挂起信号 sigaddset(&sa....