diff --git a/java-sec-code.iml b/java-sec-code.iml index 1f7ef7b5..0140638a 100644 --- a/java-sec-code.iml +++ b/java-sec-code.iml @@ -61,7 +61,6 @@ - @@ -101,7 +100,7 @@ - + @@ -181,5 +180,18 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/poc.xlsx b/poc.xlsx new file mode 100644 index 00000000..19ef11a5 Binary files /dev/null and b/poc.xlsx differ diff --git a/pom.xml b/pom.xml index 5f39a0bc..65c1d5bf 100644 --- a/pom.xml +++ b/pom.xml @@ -196,6 +196,26 @@ 1.4.10 + + org.apache.poi + poi + 3.10-FINAL + + + + + org.apache.poi + poi-ooxml + 3.10-FINAL + + + + com.monitorjbl + xlsx-streamer + 2.0.0 + + + diff --git a/src/main/java/org/joychou/controller/CommandInject.java b/src/main/java/org/joychou/controller/CommandInject.java index 758df64a..bf4f6515 100644 --- a/src/main/java/org/joychou/controller/CommandInject.java +++ b/src/main/java/org/joychou/controller/CommandInject.java @@ -16,7 +16,7 @@ public class CommandInject { protected final Logger logger = LoggerFactory.getLogger(this.getClass()); /** - * http://localhost:8080/codeinject?filepath=/tmp;pwd + * http://localhost:8080/codeinject?filepath=/tmp;cat /etc/passwd * * @param filepath filepath * @return result @@ -33,7 +33,7 @@ public static String codeInject(String filepath) throws IOException { /** * Host Injection - * host: Host: hacked by joychou;curl ssrf.http.joychou.org + * Host: hacked by joychou;cat /etc/passwd * http://localhost:8080/codeinject/host * */ diff --git a/src/main/java/org/joychou/controller/XXE.java b/src/main/java/org/joychou/controller/XXE.java index e5ea009e..79133f16 100644 --- a/src/main/java/org/joychou/controller/XXE.java +++ b/src/main/java/org/joychou/controller/XXE.java @@ -1,9 +1,9 @@ package org.joychou.controller; - import org.dom4j.io.SAXReader; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; + import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; @@ -37,7 +37,7 @@ public String xxe_xmlReader(HttpServletRequest request) { String xml_con = Tools.getRequestBody(request); System.out.println(xml_con); XMLReader xmlReader = XMLReaderFactory.createXMLReader(); - xmlReader.parse( new InputSource(new StringReader(xml_con)) ); // parse xml + xmlReader.parse(new InputSource(new StringReader(xml_con))); // parse xml return "ok"; } catch (Exception e) { System.out.println(e); @@ -47,7 +47,7 @@ public String xxe_xmlReader(HttpServletRequest request) { @RequestMapping(value = "/xmlReader_fix", method = RequestMethod.POST) - public String xxe_xmlReader_fix(HttpServletRequest request) { + public String xxe_xmlReader_fix(HttpServletRequest request) { try { String xml_con = Tools.getRequestBody(request); System.out.println(xml_con); @@ -58,7 +58,7 @@ public String xxe_xmlReader_fix(HttpServletRequest request) { xmlReader.setFeature("http://xml.org/sax/features/external-general-entities", false); xmlReader.setFeature("http://xml.org/sax/features/external-parameter-entities", false); //fix code end - xmlReader.parse( new InputSource(new StringReader(xml_con)) ); // parse xml + xmlReader.parse(new InputSource(new StringReader(xml_con))); // parse xml return "ok"; } catch (Exception e) { @@ -69,13 +69,13 @@ public String xxe_xmlReader_fix(HttpServletRequest request) { @RequestMapping(value = "/SAXBuilder", method = RequestMethod.POST) - public String xxe_SAXBuilder(HttpServletRequest request) { + public String xxe_SAXBuilder(HttpServletRequest request) { try { String xml_con = Tools.getRequestBody(request); System.out.println(xml_con); SAXBuilder builder = new SAXBuilder(); - org.jdom2.Document document = builder.build( new InputSource(new StringReader(xml_con)) ); // cause xxe + org.jdom2.Document document = builder.build(new InputSource(new StringReader(xml_con))); // cause xxe return "ok"; } catch (Exception e) { System.out.println(e); @@ -84,7 +84,7 @@ public String xxe_SAXBuilder(HttpServletRequest request) { } @RequestMapping(value = "/SAXBuilder_fix", method = RequestMethod.POST) - public String xxe_SAXBuilder_fix(HttpServletRequest request) { + public String xxe_SAXBuilder_fix(HttpServletRequest request) { try { String xml_con = Tools.getRequestBody(request); System.out.println(xml_con); @@ -93,7 +93,7 @@ public String xxe_SAXBuilder_fix(HttpServletRequest request) { 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); - org.jdom2.Document document = builder.build( new InputSource(new StringReader(xml_con)) ); + org.jdom2.Document document = builder.build(new InputSource(new StringReader(xml_con))); return "ok"; } catch (Exception e) { @@ -102,13 +102,13 @@ public String xxe_SAXBuilder_fix(HttpServletRequest request) { } @RequestMapping(value = "/SAXReader", method = RequestMethod.POST) - public String xxe_SAXReader(HttpServletRequest request) { + public String xxe_SAXReader(HttpServletRequest request) { try { String xml_con = Tools.getRequestBody(request); System.out.println(xml_con); SAXReader reader = new SAXReader(); - org.dom4j.Document document = reader.read( new InputSource(new StringReader(xml_con)) ); // cause xxe + org.dom4j.Document document = reader.read(new InputSource(new StringReader(xml_con))); // cause xxe return "ok"; } catch (Exception e) { @@ -118,7 +118,7 @@ public String xxe_SAXReader(HttpServletRequest request) { } @RequestMapping(value = "/SAXReader_fix", method = RequestMethod.POST) - public String xxe_SAXReader_fix(HttpServletRequest request) { + public String xxe_SAXReader_fix(HttpServletRequest request) { try { String xml_con = Tools.getRequestBody(request); System.out.println(xml_con); @@ -127,7 +127,7 @@ public String xxe_SAXReader_fix(HttpServletRequest request) { reader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); reader.setFeature("http://xml.org/sax/features/external-general-entities", false); reader.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - org.dom4j.Document document = reader.read( new InputSource(new StringReader(xml_con)) ); + org.dom4j.Document document = reader.read(new InputSource(new StringReader(xml_con))); return "ok"; } catch (Exception e) { @@ -231,7 +231,7 @@ public String xxeDocumentBuilderReturn(HttpServletRequest request) { NodeList child = rootNode.getChildNodes(); for (int j = 0; j < child.getLength(); j++) { Node node = child.item(j); - buf.append( node.getNodeName() + ": " + node.getTextContent() + "\n" ); + buf.append(node.getNodeName() + ": " + node.getTextContent() + "\n"); } } sr.close(); @@ -265,8 +265,8 @@ public String DocumentBuilder(HttpServletRequest request) { for (int j = 0; j < child.getLength(); j++) { Node node = child.item(j); // 正常解析XML,需要判断是否是ELEMENT_NODE类型。否则会出现多余的的节点。 - if(child.item(j).getNodeType() == Node.ELEMENT_NODE) { - result.append( node.getNodeName() + ": " + node.getFirstChild().getNodeValue() + "\n" ); + if (child.item(j).getNodeType() == Node.ELEMENT_NODE) { + result.append(node.getNodeName() + ": " + node.getFirstChild().getNodeValue() + "\n"); } } } @@ -387,7 +387,7 @@ public String XMLReaderVul(HttpServletRequest request) { SAXParserFactory spf = SAXParserFactory.newInstance(); SAXParser saxParser = spf.newSAXParser(); XMLReader xmlReader = saxParser.getXMLReader(); - xmlReader.parse( new InputSource(new StringReader(xml_con)) ); + xmlReader.parse(new InputSource(new StringReader(xml_con))); return "test"; } catch (Exception e) { System.out.println(e.toString()); @@ -407,7 +407,7 @@ public String XMLReaderSec(HttpServletRequest request) { xmlReader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); xmlReader.setFeature("http://xml.org/sax/features/external-general-entities", false); xmlReader.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - xmlReader.parse( new InputSource(new StringReader(xml_con)) ); + xmlReader.parse(new InputSource(new StringReader(xml_con))); return "test"; } catch (Exception e) { System.out.println(e.toString()); @@ -415,4 +415,9 @@ public String XMLReaderSec(HttpServletRequest request) { } } + + public static void main(String[] args) throws Exception { + + } + } \ No newline at end of file diff --git a/src/main/java/org/joychou/controller/othervulns/ooxmlXXE.java b/src/main/java/org/joychou/controller/othervulns/ooxmlXXE.java new file mode 100644 index 00000000..6a17e366 --- /dev/null +++ b/src/main/java/org/joychou/controller/othervulns/ooxmlXXE.java @@ -0,0 +1,79 @@ +package org.joychou.controller.othervulns; + +import org.apache.poi.xssf.usermodel.XSSFCell; +import org.apache.poi.xssf.usermodel.XSSFRow; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; +import java.util.Iterator; + +import static org.apache.commons.lang.StringUtils.isBlank; + +/** + * Desc: poi-ooxml xxe vuln code + * Usage: [Content_Type].xml + * Ref: https://www.itread01.com/hkpcyyp.html + * Fix: Update poi-ooxml to 3.15 or above. + * Vuln: 3.10 or below exist xxe vuln. 3.14 or above exist dos vuln. So 3.15 or above is safe version. + * + * @author JoyChou @2019-09-05 + */ +@Controller +@RequestMapping("ooxml") +public class ooxmlXXE { + + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + + @GetMapping("/upload") + public String index() { + return "xxe_upload"; // return xxe_upload.html page + } + + + @PostMapping("/readxlsx") + @ResponseBody + public String ooxml_xxe(MultipartFile file)throws IOException { + XSSFWorkbook wb = new XSSFWorkbook(file.getInputStream()); // xxe vuln + + XSSFSheet sheet = wb.getSheetAt(0); + XSSFRow row; + XSSFCell cell; + + Iterator rows = sheet.rowIterator(); + String result = ""; + + while (rows.hasNext()) + { + row=(XSSFRow) rows.next(); + Iterator cells = row.cellIterator(); + while (cells.hasNext()) + { + cell=(XSSFCell) cells.next(); + + if (cell.getCellType() == XSSFCell.CELL_TYPE_STRING) { + result += cell.getStringCellValue()+ " "; + } else if(cell.getCellType() == XSSFCell.CELL_TYPE_NUMERIC) { + result += cell.getNumericCellValue()+ " "; + } else { + logger.info("errors"); + } + } + } + if ( isBlank(result) ){ + result = "xxe test"; + } + + return result; + } +} diff --git a/src/main/java/org/joychou/controller/othervulns/xlsxStreamerXXE.java b/src/main/java/org/joychou/controller/othervulns/xlsxStreamerXXE.java new file mode 100644 index 00000000..4ca4bf2f --- /dev/null +++ b/src/main/java/org/joychou/controller/othervulns/xlsxStreamerXXE.java @@ -0,0 +1,44 @@ +package org.joychou.controller.othervulns; + +import com.monitorjbl.xlsx.StreamingReader; +import org.apache.poi.ss.usermodel.Workbook; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.multipart.MultipartFile; + +import java.io.FileInputStream; +import java.io.IOException; + + +/** + * Desc: xlsx-streamer xxe vuln code + * Usage: xl/workbook.xml + * Ref: https://www.itread01.com/hkpcyyp.html + * Fix: update xlsx-streamer to 2.1.0 or above + * + * @author JoyChou @2019-09-05 + */ +@Controller +@RequestMapping("xlsx-streamer") +public class xlsxStreamerXXE { + + + @GetMapping("/upload") + public String index() { + return "xxe_upload"; // return xxe_upload.html page + } + + + @PostMapping("/readxlsx") + public void xllx_streamer_xxe(MultipartFile file)throws IOException { + Workbook wb = StreamingReader.builder().open(file.getInputStream()); + } + + + public static void main(String[] args) throws Exception { + Workbook wb = StreamingReader.builder().open((new FileInputStream("poc.xlsx"))); + } +} diff --git a/src/main/java/org/joychou/security/LoginSuccessHandler.java b/src/main/java/org/joychou/security/LoginSuccessHandler.java index 2a81afa2..75765b02 100644 --- a/src/main/java/org/joychou/security/LoginSuccessHandler.java +++ b/src/main/java/org/joychou/security/LoginSuccessHandler.java @@ -1,15 +1,22 @@ package org.joychou.security; +import com.alibaba.fastjson.JSON; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.MediaType; import org.springframework.security.core.Authentication; import org.springframework.security.web.authentication.AuthenticationSuccessHandler; +import org.springframework.security.web.savedrequest.DefaultSavedRequest; +import org.springframework.security.web.savedrequest.HttpSessionRequestCache; +import org.springframework.security.web.savedrequest.SavedRequest; + import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; - +import java.net.URI; +import java.util.HashMap; +import java.util.Map; public class LoginSuccessHandler implements AuthenticationSuccessHandler { @@ -23,8 +30,17 @@ public void onAuthenticationSuccess(HttpServletRequest request, logger.info("USER " + authentication.getName()+ " LOGIN SUCCESS."); + SavedRequest savedRequest = new HttpSessionRequestCache().getRequest(request, response); + if (savedRequest != null) { + logger.info("Original url is: " + savedRequest.getRedirectUrl()); + } + + Map content = new HashMap<>(); + content.put("code", "0"); + content.put("message", "Login success"); + // google ajax and sendRedirect response.setContentType(MediaType.APPLICATION_JSON_VALUE); - response.getWriter().write("{\"code\":0, \"message\":\"Login success\"}"); + response.getWriter().write(JSON.toJSONString(content)); } } diff --git a/src/main/resources/templates/index.html b/src/main/resources/templates/index.html index 15b78a69..cab90aad 100644 --- a/src/main/resources/templates/index.html +++ b/src/main/resources/templates/index.html @@ -8,7 +8,7 @@

Hello .

Welcome to login java-sec-code application. Application Infomation

- CmdInject   + CmdInject   JSONP   PathTraversal   SqlInject   @@ -17,5 +17,6 @@

...

logout + \ No newline at end of file diff --git a/src/main/resources/templates/login.html b/src/main/resources/templates/login.html index f5c4f7f2..1b069872 100644 --- a/src/main/resources/templates/login.html +++ b/src/main/resources/templates/login.html @@ -51,9 +51,9 @@ data: { "username": username, "password": password, "remember-me": remember_me}, dataType: "json", success: function (r) { - if (r.code == 0) { + if (r.code == "0") { // alert(r.message); - location.href = ctx + 'index'; + location.href = ctx + "index"; } else { alert(r.message); } diff --git a/src/main/resources/templates/xxe_upload.html b/src/main/resources/templates/xxe_upload.html new file mode 100644 index 00000000..d58426f0 --- /dev/null +++ b/src/main/resources/templates/xxe_upload.html @@ -0,0 +1,14 @@ + + + + +

xlsx xxe test page

+ +
+

+ + +
+ + + diff --git a/xxe.xlsx b/xxe.xlsx new file mode 100644 index 00000000..1146b478 Binary files /dev/null and b/xxe.xlsx differ