PHP手册查阅后のNewly discovered

PHP手册查阅后のNewly discovered

今天把手册通过查找关键字把很多函数都翻了一遍,几乎用了一整天的时间,不过还是有一些新的函数发现的,比如读取文件的readgzfile和代替var_dump和printf的debug_zval_dump以及一大堆回调函数,对php的更能又有了一些新的了解,这里放一些手册查阅过程中看到的一些注意到的函数吧

获取请求头

getallheaders() — 获取全部 HTTP 请求头信息
    getallheaders()['a'] - 获取请求头a的值
apache_request_headers() — 获取全部 HTTP 请求头信息
get_headers() — 取得服务器响应一个 HTTP 请求所发送的所有标头
header("HTTP/1.0 404 Not Found") — 发送原生 HTTP 头

外加一个变量在5.6.0就被废弃的$HTTP_RAW_POST_DATA(后面的版本可以输出但是会给一个Warning并且输出内容为null

同时有一点比较奇怪,我本地只有PHP5.3.29nts我试了一下POST发送数据过去var_dump输出的还是null

image-20220508192909766

image-20220508220419992

回调函数callback

register_tick_function指定回调函数

<?php
declare(ticks=1);
register_tick_function('test', "ticker");
function test($argv){
    echo "\n$argv\n";
    system('calc');
}
echo 1;

通过declare设置ticks时钟之后register_tick_function注册计数器调用的回调函数

此外还有一个函数:

register_shutdown_function — 注册一个会在php中止时执行的函数

一般回调函数

array_map — 为数组的每个元素应用回调函数
array_walk — 使用用户自定义函数对数组中的每个元素做回调处理
array_walk_recursive — 对数组中的每个成员递归地应用用户函数
array_udiff — 用回调函数比较数据来计算数组的差集
array_filter — 用回调函数过滤数组中的单元
array_reduce — 用回调函数迭代地将数组简化为单一的值
array_intersect_ukey — 用回调函数比较键名来计算数组的交集
array_intersect_uassoc — 带索引检查计算数组的交集,用回调函数比较索引
array_uintersect_assoc — 带索引检查计算数组的交集,用回调函数比较数据
array_uintersect_uassoc — 带索引检查计算数组的交集,用单独的回调函数比较数据和索引
filter_var_array — 获取多个变量并且过滤它们
filter_input_array — 获取一系列外部变量,并且可以通过过滤器处理它们
Collator::asort -- collator_asort — Sort array maintaining index association

filter_var_array — 获取多个变量并且过滤它们
filter_input_array — 获取一系列外部变量,并且可以通过过滤器处理它们

call_user_func
call_user_method
call_user_func_array
call_user_method_array

preg_filter
preg_replace_callback
preg_replace_callback_array

forward_static_call -- 限制是貌似只能在类里面的函数执行回调函数
unserialize_callback_func -- 如果解串行器发现有未定义类要被实例化,将会调用 unserialize() 回调函数,这个也没太多说明和示例,不过感觉有点特殊就记一下吧

header_register_callback — 调用一个 header 函数(但是其实就是直接将参数作为函数名直接调用无参方法)

只能说,array的数组处理在回调函数方面的调用函数是真的多

文件操作

写文件操作

DOMDocument::save

<?php

$doc = new DOMDocument('1.0');
// we want a nice output
$doc->formatOutput = true;

$root = $doc->createElement('book');
$root = $doc->appendChild($root);

$title = $doc->createElement('title');
$title = $root->appendChild($title);

$text = $doc->createTextNode('This is the title');
$text = $title->appendChild($text);

echo 'Wrote: ' . $doc->save("/tmp/test.xml") . ' bytes'; // Wrote: 72 bytes

?>

DOMDocument::saveHTMLFile

<?php

$doc = new DOMDocument('1.0');
// we want a nice output
$doc->formatOutput = true;

$root = $doc->createElement('html');
$root = $doc->appendChild($root);

$head = $doc->createElement('head');
$head = $root->appendChild($head);

$title = $doc->createElement('title');
$title = $head->appendChild($title);

$text = $doc->createTextNode('This is the title');
$text = $title->appendChild($text);

echo 'Wrote: ' . $doc->saveHTMLFile("/tmp/test.html") . ' bytes'; // Wrote: 129 bytes

?>

FTP服务下载文件

<?php

// define some variables
$local_file = 'local.zip';
$server_file = 'server.zip';

// set up basic connection
$conn_id = ftp_connect($ftp_server);

// login with username and password
$login_result = ftp_login($conn_id, $ftp_user_name, $ftp_user_pass);

// try to download $server_file and save to $local_file
if (ftp_get($conn_id, $local_file, $server_file, FTP_BINARY)) {
  echo "Successfully written to $local_file\n";
} else {
  echo "There was a problem\n";
}

// close the connection
ftp_close($conn_id);

?>

这三个函数在可以在一些常用的文件操作被ban之后使用,当做一个备用参考吧,至于常用的写文件操作不想写了,网上很多了已经

读文件操作

加上文件名就能直接输出:
highlight_file — 语法高亮一个文件
show_source — 别名 highlight_file()
readfile — 输出文件
readgzfile - 输出打印gz文件,其实和readfile一样,可以直接输出index.php

需要资源但不需要输出函数:
gzpassthru — Output all remaining data on a gz-file pointer(可以直接输出index.php的文件资源)

将文件内需要echo或var_dump:
gzfile - 和file一样
file — 把整个文件读入一个数组中
file_get_contents — 将整个文件读入一个字符串
gzopen("index.php","r")打开的资源可以直接通过gzpassthru函数直接读出内容而不用var_dump,readgzfile更是可以直接输出文件

示例:
gzpassthru(gzopen("index.php","r"));
readgzfile("index.php",);

获取特殊字符

获取当前文件夹的.

session_get_cookie_params -- 获取会话 cookie 参数,第二个键值是/
phpversion — 获取当前的PHP版本
zend_version — 获取当前 Zend 引擎的版本
basename — 返回路径中的文件名部分
dirname — 返回路径中的目录部分

获取配置信息

ini_get_all — 获取所有配置选项
ini_get — 获取一个配置选项的值
get_cfg_var — 获取 PHP 配置选项的值
get_loaded_extensions -- 返回所有编译并加载模块名的 array
get_defined_constants --  返回所有常量的关联数组,键是常量名,值是常量值
get_defined_functions — 返回所有已定义函数的数组
get_defined_vars — 返回由所有已定义变量所组成的数组
get_current_user — 获取当前 PHP 脚本所有者名称

ini_set — 为一个配置选项设置值
ini_alter — 别名 ini_set()
ini_restore — 恢复配置选
parse_ini_file — 解析一个配置文件 项的值

get_defined_vars配合var_dump直接输出全部当前环境的变量得到题目flag变量

命令执行

意外发现两个可以执行命令可以进行RCE但是可惜只能在PHP5.x的部分版本中使用,在php中均已被淘汰

phpdbg_exec — Attempts to set the execution context
php_check_syntax — 检查PHP的语法(并执行)指定的文件

image-20220508164453256

image-20220508164726163

dl — 运行时载入一个 PHP 扩展

runkit

runkit_lint — Check the PHP syntax of the specified php code
runkit_lint_file — Check the PHP syntax of the specified file
runkit_import — Process a PHP file importing function and class definitions, overwriting where appropriate

都可以达到include的效果不过可惜默认拓展情况下并不能执行这个函数

image-20220508170848769

image-20220508170855675

image-20220508204247934

opcache_compile_file

opcache_compile_file — 无需运行,即可编译并缓存 PHP 脚本

不执行,直接编译后缓存,好像并没有什么用,并且默认拓展并不能执行这个函数

but:虽然没执行成功但是看手册的解释“以供后续请求调用”,有没有一种可能就是我们通过加载一个上传的文件,里面有一个RCE函数evil,先通过opcache_compile_file加载这个文件到缓存,然后我们在可控的地方执行index.php并没有定义的evil,然后这样子其实调用的是RCE的evil函数?(并不懂,只是看到注释的联想hh)

image-20220508170623764

命令执行函数:

system — 执行外部程序,并且显示输出
passthru — 执行外部程序并且显示原始输出
exec — 执行一个外部程序
shell_exec — 通过 shell 环境执行命令,并且将完整的输出以字符串的方式返回
proc_open — 执行一个命令,并且打开用来输入/输出的文件指针
proc_terminate — 杀除由 proc_open 打开的进程

pcntl_exec — 在当前进程空间执行指定程序
pcntl_fork — 在当前进程当前位置产生分支(子进程)

popen — 打开进程文件指针

dl — 运行时载入一个 PHP 扩展

几个手册上有但是默认没有的debug函数(看看就好):
php_check_syntax — 检查PHP的语法(并执行)指定的文件
phpdbg_exec — Attempts to set the execution context
phpdbg_break_file — Inserts a breakpoint at a line in a file
phpdbg_break_next — Inserts a breakpoint at the next opcode
phpdbg_break_method — Inserts a breakpoint at entry to a method
phpdbg_break_function — Inserts a breakpoint at entry to a function

反序列化

Array::(un)serialize

查看手册的时候发现除了可以直接使用(un)serialize函数之外在Array数组类的内部也有(un)serialize函数,并且发现可以直接反序列化数据

var_dump(array().unserialize(serialize(new test())));

image-20220508194824460

不过可惜Array内部调用(un)serialize也会受disabled_functions的限制所以并没有太大用处,

image-20220508195249918

除了Array还有很多类也有(un)serialize函数,但是应该和Array一样还是会受到disable_functions限制,所以就不看了,这里方几个类内自己定义了(un)serialize函数的原生类:

ArrayIterator::serialize
ArrayIterator::unserialize

SplDoublyLinkedList::serialize
SplDoublyLinkedList::unserialize

SplObjectStorage::serialize
SplObjectStorage::unserialize

ArrayObject::serialize
ArrayIterator::unserialize

wddx_(un)serialize

除了Array的(un)serialize之外发现还有一个反序列化的函数,不过在7.4.0全部的wddx函数都被弃用了默认情况下使用不了

wddx_deserialize — Unserializes a WDDX packet

image-20220508183901624

至于序列化的话可以用wddx_serialize_vars也可以用wddx_serialize_values函数

<?php
class test{
    function __construct(){
        $this->name= "test";
    }
    function __wakeup(){
        system('calc');
        var_dump($this->name);
    }
}
$test=new test();
var_dump(wddx_deserialize(wddx_serialize_vars("test")));
var_dump(wddx_deserialize(wddx_serialize_value($test)));
?>

image-20220508183833832

打印输出

echo,var_dump,print,scanf都被ban了的话可以通过debug_zval_dump输出包括数组在内的变量

image-20220508190916401

debug_zval_dump用起来感觉和var_dump函数差不多

另外debug函数还有两个方便调试追踪的函数一起放一下吧:

  1. debug_print_backtrace

    image-20220508191507810

    image-20220508191329103

  2. debug_backtrace

    image-20220508191524168

    image-20220508191604292

此外看到array_rand这个函数注意一下,因为相比next,prev,first,current这些只能获取下一个或者上一个又或者最后一个变量的函数相比,它是随机获取一个或多个变量,我们可以通过爆破结合get_headers函数和eval执行命令

image-20220508193502475

协议

扒手册仔细看了一才发现原来php://协议除了之前常用的几种之外还有几个伪协议

php://stdin
php://stdout
php://stderr

php://input
php://output

php://temp
php://memory
php://temp/maxmemory

php://fd

php://filter

image-20220508201039449

除了php://协议之外的其它一些流协议:

ogg:// — 音频流
ftp:// -- ftps:// — 访问 FTP(s) URLs
php:// — 访问各个输入/输出流(I/O streams)
rar:// — RAR
zlib:// -- bzip2:// -- zip:// — 压缩流
data:// — 数据(RFC 2397)
file:// — 访问本地文件系统
glob:// — 查找匹配的文件路径模式
http:// -- https:// — 访问 HTTP(s) 网址
phar:// — PHP 归档
ssh2:// — Secure Shell 2
expect:// — 处理交互式的流

data://text/plain;base64,

压缩流的几个协议:

compress.zlib://file.gz
compress.bzip2://file.bz2
zip://archive.zip#dir/file.txt
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇