Pikachu靶场系列之XSS钓鱼攻击与PHP中的HTTP认证

背景

最近在Pikachu靶场中复现钓鱼攻击时,最后一步 Basic 认证后数据无法发送到后台,而是一直重复弹出认证提示框。经过一番折腾后终于发现了原因并解决。

原因

先贴出后台 fish.php 代码


这里可以看到,基本逻辑是判断 $_SERVER['PHP_AUTH_USER']$_SERVER['PHP_AUTH_PW'] 是否为空,若为空则弹窗认证框。但是实验时发现无论怎么输入,都是一直循环弹认证框,猜测输入的内容没有传到这2个变量。于是我将 var_dump($_SERVER) 的注释移除,看看 $_SERVER 变量里到底有哪些数据

array(44) {    ["PATH"]=> string(726) "G:\XShell6\;...E:\Git\bin;"    ["SYSTEMROOT"]=> string(10) "C:\WINDOWS"    ["COMSPEC"]=> string(27) "C:\WINDOWS\system32\cmd.exe"    ["PATHEXT"]=> string(53) ".COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC"    ["WINDIR"]=> string(10) "C:\WINDOWS"    ["PHP_FCGI_MAX_REQUESTS"]=> string(4) "1000"    ["PHPRC"]=> string(31) "G:/phpStudy/php/php-7.0.12-nts/"    ["_FCGI_SHUTDOWN_EVENT_"]=> string(4) "2312"    ["SCRIPT_NAME"]=> string(29) "/pikachu/pkxss/xfish/fish.php"    ["REQUEST_URI"]=> string(29) "/pikachu/pkxss/xfish/fish.php"    ["QUERY_STRING"]=> string(0) ""    ["REQUEST_METHOD"]=> string(3) "GET"    ["SERVER_PROTOCOL"]=> string(8) "HTTP/1.1"    ["GATEWAY_INTERFACE"]=> string(7) "CGI/1.1"    ["REMOTE_PORT"]=> string(4) "1278"    ["SCRIPT_FILENAME"]=> string(44) "G:/phpStudy/WWW/pikachu/pkxss/xfish/fish.php"    ["SERVER_ADMIN"]=> string(18) "admin@phpStudy.net"    ["CONTEXT_DOCUMENT_ROOT"]=> string(15) "G:/phpStudy/WWW"    ["CONTEXT_PREFIX"]=> string(0) ""    ["REQUEST_SCHEME"]=> string(4) "http"    ["DOCUMENT_ROOT"]=> string(15) "G:/phpStudy/WWW"    ["REMOTE_ADDR"]=> string(9) "127.0.0.1"    ["SERVER_PORT"]=> string(2) "80"    ["SERVER_ADDR"]=> string(9) "127.0.0.1"    ["SERVER_NAME"]=> string(9) "127.0.0.1"    ["SERVER_SOFTWARE"]=> string(52) "Apache/2.4.23 (Win32) OpenSSL/1.0.2j mod_fcgid/2.3.9"    ["SERVER_SIGNATURE"]=> string(0) ""    ["SystemRoot"]=> string(10) "C:\WINDOWS"    ["HTTP_COOKIE"]=> string(36) "PHPSESSID=i8puesvk7tu2s13kokh88qgtu1"    ["HTTP_ACCEPT_LANGUAGE"]=> string(14) "zh-CN,zh;q=0.9"    ["HTTP_ACCEPT_ENCODING"]=> string(17) "gzip, deflate, br"    ["HTTP_SEC_FETCH_MODE"]=> string(8) "navigate"    ["HTTP_SEC_FETCH_SITE"]=> string(4) "none"    ["HTTP_ACCEPT"]=> string(124) "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"    ["HTTP_SEC_FETCH_USER"]=> string(2) "?1"    ["HTTP_USER_AGENT"]=> string(115) "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36"    ["HTTP_UPGRADE_INSECURE_REQUESTS"]=> string(1) "1"    ["HTTP_CACHE_CONTROL"]=> string(9) "max-age=0"    ["HTTP_CONNECTION"]=> string(5) "close"    ["HTTP_HOST"]=> string(9) "127.0.0.1"    ["FCGI_ROLE"]=> string(9) "RESPONDER"    ["PHP_SELF"]=> string(29) "/pikachu/pkxss/xfish/fish.php"    ["REQUEST_TIME_FLOAT"]=> float(1580478129.2173)    ["REQUEST_TIME"]=> int(1580478129)  }  Authorization Required.

这里可以看到根本没有 $_SERVER['PHP_AUTH_USER']$_SERVER['PHP_AUTH_PW'] 这2个变量。经过搜索找到了原因: PHP的HTTP认证机制仅在PHP以Apache模块方式运行时才有效,因此该功能不适用于CGI版本。 通过 phpinfo() 页面可以看到 Server APICGI/FastCGI

重新部署环境

所以现在可以知道,只需将PHP 以模块模式运行 即可使HTTP认证机制生效。而phpStudy默认是以 CGI/FastCGI 模式运行,如果想以模块方式运行,则需要收到安装Apache和对应版本的PHP。

安装Apache

首先下载 Apache 。Apache要在VC运行库里运行,如果没有VC库也可以在该页面下载对应的 VC14VC15

下载完成后解压到指定目录,打开 Apache24/conf/httpd.conf 文件,找到 Define SRVROOT ,将 /Apache24 修改为解压目录,如这里解压在 G:\Apache24 目录

Define SRVROOT "G:\Apache24"

然后使用管理员权限打开CMD,执行以下命令

G:\Apache24\bin\httpd.exe -k install -n apache

进入 bin 目录,运行 ApacheMonitor.exe 。在托盘处左键点击Apache小图标,选择 start ,然后访问 localhost 测试

配置PHP

关于PHP的版本选择需要注意以下几点

VC版本:以模块模式运行,需要VC版本库一致,前面Apache是VC15,所以PHP也要选择VC15。并且如果电脑上没有VC15运行库,需要另外安装。

TS/NTS: TS 是指具有多线程功能的构建, NTS 仅指单线程构建。NTS一般适用于CGI/FastCGI,因此这里需要选择 TS

x86/x64:前面Apache是x86,尽量选择一致的,避免各种不兼容。所以选择 x86

总结:如果你的Apache版本和我的一样: httpd-2.4.41-o111c-x86-vc15-r2 ,那么PHP请选择: php-7.x.x-Win32-vc15-x86.zip

下载 PHP 并解压

打开Apache的 httpd.conf 文件,在最后面增加配置

# 此处修改为你的PHP目录 LoadModule php7_module G:/php/php7apache2_4.dll PHPIniDir G:/php AddType application/x-httpd-php .php

重启Apache,并Apache安装目录下的 htdocs 目录新建一个 test.php ,写入以下内容:


最后通过浏览器访问: [http://localhost/test.php](http://localhost/test.php) ,可以看到 Server APIApache 2.0 Handler

复现钓鱼攻击

先把PHP安装目录下的 php.ini-production 文件复制一份并重命名为 php.ini ,然后打开

找到 extension = mysqli ,将前面 ; 去掉

找到 extension_dir = "ext" ,将前面 ; 去掉,并修改为PHP路径下的 ext

extension_dir = "G:/php/ext"

Pikachu 靶场复制到 htdocs 目录下,并开启MySQL。这里使用的是phpStudy环境,由于Apache已经另外安装并开启了,因此这里只需要单独启动MySQL即可

浏览器访问: http://127.0.0.1/pikachu/vul/xss/xss_stored.php ,插入恶意代码


另开一个浏览器,模拟普通用户访问 http://127.0.0.1/pikachu/vul/xss/xss_stored.php ,弹框输入账号密码,输入后点击确定

此时,黑客可从后台看到账号密码。至此,整个实验终于结束了

总结

PHP运行模式

这里说明一下PHP的运行模式,共有4种:

CGI协议模式:该模式允许web服务器通过特定的协议与应用程序通信。由于 每次用户请求都得fork创建进程调用一次程序 ,然后销毁进程,所以性能较低,调用原理大概为:

用户请求

Web服务器接收请求

fork子进程调用程序/执行程序

程序返回内容/程序调用结束

Web服务器接收内容

返回给用户

Fast-CGI协议模式:CGI协议模式升级版。它像是一个常驻型CGI, 只要开启就可一直处理请求,不再需要结束进程 。调用原理大概为:

Web服务器Fast-CGI进程管理器初始化

预先fork n个进程用户请求

Web服务器接收请求

交给Fast-CGI进程管理器

Fast-CGI进程管理区接收,给其中一个空闲Fast-CGI进程处理

处理完成,Fast-CGI进程变为空闲状态,等待下次请求

web服务器接收内容

返回给用户

Apache 2.0 Handler 模块模式:Apache+PHP运行时,默认使用的是模块模式,它把PHP作为Apache的模块随Apache启动而启动, PHP进程和Apache进程合一块 。接收到用户请求时则直接通过调用 mod_php 模块进行处理。 模块模式是以 mod_php5 模块的形式集成,此时 mod_php5 模块的作用是接收Apache传递过来的PHP文件请求,并处理这些请求,然后将处理后的结果返回给Apache。如果我们在Apache启动前在其配置文件中配置好了PHP模块( mod_php5 ),PHP模块通过注册Apache2的 ap_hook_post_config 挂钩,在Apache启动的时候启动此模块以接受PHP文件的请求

PHP-Cli模式:命令行模式。该模式不需要借助其他程序,直接输入 php xx.php 就能执行PHP代码,命令行模式和常规web模式明显不一样有以下几点

没有超时时间

默认关闭Buffer缓冲

STDINSTDOUT 标准输入/输出/错误的使用

echovar_dumpphpinfo 等输出直接输出到控制台

可使用的类/函数 不同

php.ini 配置的不同

参考文章:

$_SERVER[‘PHP_AUTH_USER’]

PHP的四种运行方式

*本文作者:FengSec,转载请注明来自FreeBuf.COM