FastCGI协议
介绍
Fast CGI源自旧版本的CGI,旧版本的CGI性能低下,无法应用在高并发的场景,FastCGI应运而生
路由/结构图
language-shell
# 访问url --> 浏览器生成HTTP请求报文 --> web server解析请求(例如nginx)
当访问index.php时,web server 会把HTTP请求转换为FastCGI请求
# --> 转换为FastCGI协议格式
并发送给解析器,这里以php为例
# --> 发送至php-fpm process manager
php-fpm接收到请求后,把请求分配给一个worker,worker就是一个解析服务的进程(一直运行),worker根据请求信息,解析php,返回页面
例如,招新平台运行了15个worker,(不考虑nginx处理时间)同时可以处理15个请求
# --> php-fpm解析并响应
新旧对比
0
FastCGI也是一种通信协议(类似HTTP协议),采用CS架构,web server 为客户端—发送请求,动态语言解析器 为服务端—处理请求
FastCGI报文格式
定义
language-http
typedef struct {
unsigned char version; //版本
unsigned char type; //类型
unsigned char requestIdB1; //请求Id
unsigned char requestIdB0;
unsigned char contentLengthB1; //负载长度
unsigned char contentLengthB0;
unsigned char paddingLength; //填充长度
unsigned char reserved; //保留字节
unsigned char contentData[contentLength]; //负载数据
unsigned char paddingData[paddingLength]; //填充数据
} FCGI_Record;
构造出的执行**ls /**命令的FastCGI请求( 调整过格式,不标准)
language-http
CONTENT_LENGTH 34 # 内容长度
CONTENT_TYPE application/text # 内容格式
REMOTE_PORT 9985 # 请求端口
SERVER_NAME localhost # server名
GATEWAY_INTERFACE FastCGI/1.0 # API
SERVER_SOFTWARE php/fcgiclient # server端 软件
REMOTE_ADDR 127.0.0.1 # 请求ip
SCRIPT_FILENAME /var/www/html/index.php # 脚本文件名
SCRIPT_NAME /var/www/html/index.php # 脚本名
PHP_VALUE auto_prepend_file = php://input
REQUEST_METHOD POST # 请求方法
SERVER_PORT 8 # server端口
SERVER_PROTOCOL HTTP/1.1 # server 协议
QUERYDOCUMENT_ROOT / # 请求文件根目录
IN_VALUE allow_url_include = On # 设置 允许url包含
SERVER_ADDR 127.0.0.1 # server ip
REQUEST_URI /var/www/html/index.php # 请求资源
"" # 内容34
ssrf + fastcgi
- 如果目标服务器使用的是php,并且存在ssrf,那么就可以构造FastCGI请求报文,直接让php解析服务进行解析,进而执行任意代码
- 之前构造出的执行 ls /的FastCGI请求中,关键部分
language-html
PHP_VALUE auto_prepend_file = php://input
# 把auto_prepende_file的内容设置为 php://input http post body
# auto_prepende_file 会在解析指定php文件之前包含(可以理解为执行)
# php://input的内容为POST请求的body
IN_VALUE allow_url_include = On # 设置 允许url包含 使php://input被允许执行
REQUEST_URI /var/www/html/index.php # 请求资源
"" # 内容 post body
- 会在解析index.php之前,包含(执行)php://input的内容
- 这样,就可以使用ssrf+fastcgi执行任意代码了