一、SQL注入
关键词搜索正则:
(?:select.+from.+where.+|insert.+into.+values.*\(|update.+set.+where.+|delete.+from.+where.+|StringBuffer\s+sql|sql\w*\.append\(|exec\(?:|Sql\(|createSQLQuery|createQuery|HibernateUtil|beginTransaction|java.sql.Statement|java.sql.PreparedStatement|executeQuery|createStatement|jdbcTemplate.execute|JdbcTemplate\(.execute\()
若使用MyBatis框架需重点关注$符:
order by ${id} ascin (${id})like ‘%${id}%’
Oracle的模糊查询更特殊一点:
like ‘%$id$%’like ‘%’||’$id$’||’%’
重点查看SQL语句是否是拼接而成,且拼接的各个位置的参数值是否可以外部输入,熟悉存在即不存在漏洞的代码写法,如没有SQL注入的java片段:
再如,这样写存在SQL注入:
select from table wherename=<%:name% >content>
这样则不存在SQL注入:
select from table wherename=:name
二、XXE注入
关键词搜索正则:
documentbuilder|DocumentBuilderFactory|SAXReader|SAXParser|SAXParserFactory|SAXBuilder|TransformerFactory|reqXml|getInputStream\(|XMLReaderFactory|\.newInstance|SchemaFactory|SAXTransformerFactory|javax.xml.bind|XMLReader|ValidatorSample|Unmarshaller|XMLInputFactory|JAXBContext|DocumentHelper|dom4j
1、DocumentBuilderFactory
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();//实例化factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl",true);//设置featurefactory.setFeature("http://xml.org/sax/features/external-general-entities",false);factory.setFeature("http://xml.org/sax/features/external-parameter-entities",false);factory.setFeature("http://javax.xml.XMLConstants/feature/secure-processing",true);DocumentBuilder dbuilder =factory.newDocumentBuilder(); //生成数据Document document = dbuilder.parse(newFile(fileName)); //执行解析xml
需要注意的是,使用工厂类时一定要先设置Feature,再去builder生成数据。下面这种写法则是无效的:
DocumentBuilderFactory factory =DocumentBuilderFactory.newInstance(); //实例化DocumentBuilder dbuilder =factory.newDocumentBuilder(); //生成数据factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl",true);//设置featurefactory.setFeature("http://xml.org/sax/features/external-general-entities",false);factory.setFeature("http://xml.org/sax/features/external-parameter-entities",false);factory.setFeature("http://javax.xml.XMLConstants/feature/secure-processing",true);Document document = dbuilder.parse(newFile(fileName));
微信支付SDK的XXE漏洞就是WXPayIUtil.xmlToMap()方法使用了DocumentBuilderFactory没有限制外部查询而导致XXE,代码如:
public static Map<String, String>xmlToMap(String strXML) throws Exception { try { Map<String, String> data = new HashMap<String, String>(); DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();//没有设置对外部实例访问的限制 DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); InputStream stream = new ByteArrayInputStream(strXML.getBytes( "UTF-8")); org.w3c.dom.Document doc = documentBuilder.parse(stream);
2、SAXParserFactory
SAXParserFactory spf = SAXParserFactory.newInstance();spf.setFeature("http://apache.org/xml/features/disallow-doctype-decl",true);spf.setFeature("http://xml.org/sax/features/external-general-entities",false);spf.setFeature("http://xml.org/sax/features/external-parameter-entities",false);spf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd",false);SAXParser parser = spf.newSAXParser();parser.parse(InputSource, (HandlerBase)null); //解析
3、SAXReader
SAXReader saxReader = new SAXReader();saxReader.setFeature("http://apache.org/xml/features/disallow-doctype-decl",true);saxReader.setFeature("http://xml.org/sax/features/external-general-entities",false);saxReader.setFeature("http://xml.org/sax/features/external-parameter-entities",false);saxReader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd",false);saxReader.read(InputSource);
若使用默认配置,未设置feature则会产生XXE。此外,低版本dom4j 中DocumentHelper.parseText()使用了默认SaxReader配置,因此存在XXE问题,需升级到2.1.1或重构代码。
4、TransformerFactory
TransformerFactory tf =TransformerFactory.newInstance();tf.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD,"");tf.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET,"");StreamSource source = newStreamSourceInputSource);tf.newTransformer().transform(source, newDOMResult());
5、SAXTransformerFactory
SAXTransformerFactory sf =(SAXTransformerFactory) SAXTransformerFactory.newInstance();sf.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD,"");sf.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET,"");StreamSource source = newStreamSource(InputSource);sf.newTransformerHandler(source);
但默认配置,虽然能够触发XXE漏洞,但是出现运行时会报错。
6、SchemaFactory
SchemaFactory factory =SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");factory.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD,"");factory.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA,"");StreamSource source = newStreamSource(InputSource);Schema schema = factory.newSchema(source);
情况和SAXTransformerFactory类似。
7、ValidatorSample
SchemaFactory factory =SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");Schema schema = factory.newSchema();Validator validator =schema.newValidator();validator.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD,"");validator.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA,"");StreamSource source = newStreamSource(InputSource);validator.validate(source);
8、XMLReader/ XMLInputFactory
XMLReader reader =XMLReaderFactory.createXMLReader();reader.setFeature("http://apache.org/xml/features/disallow-doctype-decl",true);reader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd",false);reader.setFeature("http://xml.org/sax/features/external-general-entities",false);reader.setFeature("http://xml.org/sax/features/external-parameter-entities",false);reader.parse(new InputSource(InputSource));
XMLInputFactory factory =XMLInputFactory.newInstance();xmlInputFactory.setProperty(XMLInputFactory.SUPPORT_DTD,false);xmlInputFactory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES,false);XMLStreamReader reader =factory.createXMLStreamReader();
9、SAXBuilder
方式1:
SAXBuilder builder = new SAXBuilder(true);Document doc = builder.build(InputSource);//解析xml
方式2:
SAXBuilder builder = new SAXBuilder();builder.setFeature("http://apache.org/xml/features/disallow-doctype-decl",true);builder.setFeature("http://xml.org/sax/features/external-general-entities",false);builder.setFeature("http://xml.org/sax/features/external-parameter-entities",false);builder.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd",false);Document doc = builder.build(InputSource);
10、JAXB Marshaller
Class tClass = Some.class;JAXBContext context = JAXBContext.newInstance(tClass);Unmarshaller um =context.createUnmarshaller();Object o =um.unmarshal(ResourceUtils.getPoc1());tClass.cast(o);
存在问题:
JAXBContext context =JAXBContext.newInstance(klass);Unmarshaller unmarshaller =context.createUnmarshaller();return unmarshaller.unmarshal(newStringReader(xml));
经测试,unmashaller在jdk1.6和jdk1.7环境下都可XXE,但在jdk1.8下执行不了。
有效过滤:
JAXBContextcontext = JAXBContext.newInstance(klass);XMLInputFactoryxif = XMLInputFactory.newFactory();xif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES,false);xif.setProperty(XMLInputFactory.SUPPORT_DTD,true);XMLStreamReaderxsr = xif.createXMLStreamReader(new StringReader(xml));Unmarshallerunmarshaller = context.createUnmarshaller();returnunmarshaller.unmarshal(xsr);
总结:
xml问题的本质是配置不当,修复方式一般是三种:
1)设置setFeature的方式来防御XXE。
2)setAttribute或setProperty:
XMLConstants.ACCESS_EXTERNAL_DTD,""XMLConstants.ACCESS_EXTERNAL_STYLESHEET,""
3)较少见的有效防护方式
FEATURE = "http://javax.xml.XMLConstants/feature/secure-processing";dbf.setFeature(FEATURE, true);
三、SSRF
HttpURLConnection. getInputStreamURLConnection. getInputStreamRequest.Get. executeRequest.Post. executeURL.openStreamImageIO.readOkHttpClient.newCall.executeHttpClients. executeHttpClient.execute
正则表达式:
HttpClient|HttpURLConnection|URLConnection|Socket|\.getInputStream|Request\.Get|Reques\.Post|\.openStream|ImageIO|OkHttpClient|\.newCall|\.execute|HttpPost|HttpGet|Connection
发送请求的代码层步骤一般为:创建实例,制定URL地址并添加参数,调用execute方法发送请求,得到HttpResponse,可获取响应头getHeaders和内容getEntity,最后释放连接。
1、HttpClients
public void post() {// 创建默认的httpClient实例. CloseableHttpClient httpclient =HttpClients.createDefault();// 创建httppost HttpPost httppost = newHttpPost("http://localhost:8080/myDemo/Ajax/serivceJ.action");// 创建参数队列 List formparams = new ArrayList();formparams.add(newBasicNameValuePair("type", "house"));CloseableHttpResponse response =httpclient.execute(httppost);// 获取响应实体 HttpEntity entity = response.getEntity();// 关闭连接,释放资源 httpclient.close();
2、HttpURLConnection
String url =request.getParameter("picurl");StringBuffer response = new StringBuffer(); URL pic = new URL(url);HttpURLConnection con = (HttpURLConnection)pic.openConnection();con.setRequestMethod("GET");con.setRequestProperty("User-Agent","Mozilla/5.0");BufferedReader in = new BufferedReader(newInputStreamReader(con.getInputStream()));String inputLine;while ((inputLine = in.readLine()) != null){ response.append(inputLine); }in.close();modelMap.put("resp",response.toString());return "getimg.htm";
3、Socket
String host =request.getParameter("host"); String port = request.getParameter("port"); Socket socket = null; try{ socket = new Socket(host, port); return true; } catch (Exception e) { logger.error("connect test failed!", e); return false; } finally { if (socket != null) { try { socket.close(); } catch (IOException e) { logger.error("Socketclose error!", e); }}}
4、OkHttpClient
String url =request.getParameter("url");OkHttpClient httpClient = new OkHttpClient();Request request = new Request.Builder() .url(url) .build();Response response = httpClient.newCall(request).execute();return response.body().string();
5、ImageIO
String imgurl = request.getParameter("url"); URLurl = new URL(imgurl); Image image = ImageIO.read(url); return image;
6、其他协议
public boolean connection(String url,String username,String passwd) { DataSource mysqlDataSource =getDataSourceByDriver("com.mysql.jdbc.Driver", username, passwd,url); Connection conn = null; try { conn = mysqlDataSource.getConnection(); if (conn == null) return false; return true; } catch (SQLException e) { logger.error("mysql Connect failed! url:" + url, e); handleSQLException(e); } return false; }
四、命令注入
(?:ProcessBuilder\(|Runtime\.exec\(|getRuntime\(|execlp\(|execvp\(|ShellExecute\(|wsystem\(|eval\(|execfile\(|input\(|popen\(|system\(|execute\(|passthru\(|Shell_exec\(|StandardInput.WriteLine\(|execCmd)Runtime.getRuntime().exec(command)ProcessBuilder(command)
入参最常使用的是&或||等符号绕过。
五、日志注入/打印
log.debug|logger.severe|log.error|log.info|log.warn|logger.warn|log.fatal|log.trace
1)打印敏感信息:追踪打印数据的来源,是否包含敏感信息;
2日志注入:追踪打印参数,是否用户可控,是否可注入换行符%0A%0D;
六、Dos攻击
Dos攻击需关注保持连接、上传大文件等对系统资源消耗较大的功能,看代码层是否作线程、频率限制,除此外需关注ReDos攻击:
(Pattern.compile\()|(.matches\()|reg|Regex|REGEX|REG
找到所有的正则表达式,然后使用开源的工具Regex Fuzzer分析,若显示Failed则存在Redos漏洞: