From 7bf17220cb8fd03812f3c63c38b98a8e265aa5af Mon Sep 17 00:00:00 2001 From: k-tamura Date: Thu, 2 Mar 2017 22:58:31 +0900 Subject: [PATCH] Add a file upload servlet which can crash JVM --- .../troubles/UnrestrictedUploadServlet.java | 68 ++++++++++++------- src/main/resources/indexpage_en.properties | 2 + src/main/resources/indexpage_ja.properties | 2 + src/main/resources/messages_en.properties | 11 ++- src/main/resources/messages_ja.properties | 11 ++- src/main/webapp/index.jsp | 5 ++ 6 files changed, 70 insertions(+), 29 deletions(-) diff --git a/src/main/java/org/t246osslab/easybuggy/troubles/UnrestrictedUploadServlet.java b/src/main/java/org/t246osslab/easybuggy/troubles/UnrestrictedUploadServlet.java index a558f9f4..945617d2 100644 --- a/src/main/java/org/t246osslab/easybuggy/troubles/UnrestrictedUploadServlet.java +++ b/src/main/java/org/t246osslab/easybuggy/troubles/UnrestrictedUploadServlet.java @@ -38,12 +38,22 @@ public class UnrestrictedUploadServlet extends HttpServlet { private static final String SAVE_DIR = "uploadFiles"; protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + + Locale locale = req.getLocale(); + StringBuilder bodyHtml = new StringBuilder(); bodyHtml.append("
"); - bodyHtml.append("Select file to upload:
"); - bodyHtml.append("
"); + bodyHtml.append(MessageUtils.getMsg("msg.reverse.color", locale)); + bodyHtml.append("

"); + bodyHtml.append("
"); + bodyHtml.append(MessageUtils.getMsg("msg.select.upload.file", locale)); + bodyHtml.append("

"); + bodyHtml.append(""); + bodyHtml.append("

"); + bodyHtml.append(MessageUtils.getMsg("msg.unrestricted.upload", locale)); bodyHtml.append("
"); - HTTPResponseCreator.createSimpleResponse(res, "File Upload", bodyHtml.toString()); + HTTPResponseCreator.createSimpleResponse(res, MessageUtils.getMsg("title.unrestricted.upload", locale), + bodyHtml.toString()); } protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { @@ -73,13 +83,26 @@ protected void doPost(HttpServletRequest req, HttpServletResponse res) throws Se out.write(bytes, 0, read); } - // Revere color of the upload image - revereColor(new File(savePath + File.separator + fileName).getAbsolutePath()); + boolean isConverted = true; + try { + // Revere color of the upload image + revereColor(new File(savePath + File.separator + fileName).getAbsolutePath()); + } catch (Exception e) { + // Log and ignore the exception + log.error("Exception occurs: ", e); + isConverted = false; + } StringBuilder bodyHtml = new StringBuilder(); - bodyHtml.append(MessageUtils.getMsg("msg.reverse.color.complete", locale)); - bodyHtml.append("

"); - bodyHtml.append(""); + if (isConverted) { + bodyHtml.append(MessageUtils.getMsg("msg.reverse.color.complete", locale)); + } else { + bodyHtml.append(MessageUtils.getMsg("msg.reverse.color.fail", locale)); + } + if (isConverted) { + bodyHtml.append("

"); + bodyHtml.append(""); + } bodyHtml.append("

"); bodyHtml.append(""); @@ -103,24 +126,19 @@ private String getFileName(final Part part) { // Revere color of the image file private void revereColor(String fileName) throws IOException { - try { - BufferedImage image = ImageIO.read(new File(fileName)); - WritableRaster raster = image.getRaster(); - int[] pixelBuffer = new int[raster.getNumDataElements()]; - for (int y = 0; y < raster.getHeight(); y++) { - for (int x = 0; x < raster.getWidth(); x++) { - raster.getPixel(x, y, pixelBuffer); - pixelBuffer[0] = ~pixelBuffer[0]; - pixelBuffer[1] = ~pixelBuffer[1]; - pixelBuffer[2] = ~pixelBuffer[2]; - raster.setPixel(x, y, pixelBuffer); - } + BufferedImage image = ImageIO.read(new File(fileName)); + WritableRaster raster = image.getRaster(); + int[] pixelBuffer = new int[raster.getNumDataElements()]; + for (int y = 0; y < raster.getHeight(); y++) { + for (int x = 0; x < raster.getWidth(); x++) { + raster.getPixel(x, y, pixelBuffer); + pixelBuffer[0] = ~pixelBuffer[0]; + pixelBuffer[1] = ~pixelBuffer[1]; + pixelBuffer[2] = ~pixelBuffer[2]; + raster.setPixel(x, y, pixelBuffer); } - // Output the image - ImageIO.write(image, "png", new File(fileName)); - } catch (Exception e) { - // Log and ignore the exception - log.error("Exception occurs: ", e); } + // Output the image + ImageIO.write(image, "png", new File(fileName)); } } diff --git a/src/main/resources/indexpage_en.properties b/src/main/resources/indexpage_en.properties index 30e42e2a..f1820c1b 100644 --- a/src/main/resources/indexpage_en.properties +++ b/src/main/resources/indexpage_en.properties @@ -55,6 +55,8 @@ function.name.ldap.injection=LDAP Injection function.description.ldap.injection=There is an LDAP Injection vulnerability in this page. function.name.code.injection=Code Injection function.description.code.injection=There is a Code Injection vulnerability in this page. +function.name.unrestricted.upload=Unrestricted File Upload +function.description.unrestricted.upload=This page is vulnerable because there are no limitation for uploading. section.errors=Errors diff --git a/src/main/resources/indexpage_ja.properties b/src/main/resources/indexpage_ja.properties index 644cd82f..a5a81034 100644 --- a/src/main/resources/indexpage_ja.properties +++ b/src/main/resources/indexpage_ja.properties @@ -58,6 +58,8 @@ function.name.ldap.injection=LDAP\u30a4\u30f3\u30b8\u30a7\u30af\u30b7\u30e7\u30f function.description.ldap.injection=\u3053\u306e\u30da\u30fc\u30b8\u306b\u306fLDAP\u30a4\u30f3\u30b8\u30a7\u30af\u30b7\u30e7\u30f3\u306e\u8106\u5f31\u6027\u304c\u3042\u308a\u307e\u3059\u3002 function.name.code.injection=\u30b3\u30fc\u30c9\u30a4\u30f3\u30b8\u30a7\u30af\u30b7\u30e7\u30f3 function.description.code.injection=\u3053\u306e\u30da\u30fc\u30b8\u306b\u306f\u30b3\u30fc\u30c9\u30a4\u30f3\u30b8\u30a7\u30af\u30b7\u30e7\u30f3\u306e\u8106\u5f31\u6027\u304c\u3042\u308a\u307e\u3059\u3002 +function.name.unrestricted.upload=\u5236\u9650\u306e\u7121\u3044\u30d5\u30a1\u30a4\u30eb\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9 +function.description.unrestricted.upload=\u3053\u306e\u30da\u30fc\u30b8\u306f\u30d5\u30a1\u30a4\u30eb\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u306e\u5236\u9650\u306e\u7121\u3044\u305f\u3081\u3001\u8106\u5f31\u3067\u3059\u3002 section.errors=\u30a8\u30e9\u30fc diff --git a/src/main/resources/messages_en.properties b/src/main/resources/messages_en.properties index a743b2fb..cbf4ae76 100644 --- a/src/main/resources/messages_en.properties +++ b/src/main/resources/messages_en.properties @@ -66,16 +66,22 @@ msg.note.ldap.injection=  You can see other users information if you set name to "*)(|(objectClass=*" and password to "aaaaaaa)" msg.note.mojibake=  \ Mojibake occurs if you set name in a multibyte language +msg.unrestricted.upload=  \ +If you upload JSP file including <% System.exit(0); %> and access to http://localhost:8080/uploadFiles/exit.jsp, \ +then JavaVM is forcibly finished. msg.note.xss=  \ JavaScript is executed if you set name to >tpircs/<;)\"!SSX\"(trela>tpircs< msg.permgen.space.leak.occur=Memory leak occurs in PermGen space every time you load this page.

\   If keeping on loading this page, OutOfMemoryError is finally thrown. msg.question.reach.the.moon=How many times would you have to fold a piece of paper (thickness 0.1mm) for it to be thick enough to reach the moon (384,400 km)? -msg.reverse.color.complete=The color reversal of the image has completed. +msg.reverse.color=You can reverse the color of an image file. +msg.reverse.color.complete=The color reversal of the image file has completed. +msg.reverse.color.fail=The color reversal of the image file fails. msg.socket.leak.occur=Network socket leak occurs every time you load this page. msg.unknown.exception.occur=Unknown exception occurs. msg.update.records=Updated {0} records. msg.select.asc.or.desc=You can update recordes, inserted in a table of RDBMS, in ascending or descending order of ID. +msg.select.upload.file=Select file to upload. msg.thread.leak.occur=Thread leak occurs every time you load this page. msg.valid.json=Valid JSON! msg.warn.select.asc.or.desc=Please select "asc" or "desc" and click the Update button. @@ -85,8 +91,9 @@ title.integer.overflow.page=The distance from Earth to the moon title.loss.of.trailing.digits.page=Decimal addition title.parse.json=Parse JSON title.round.off.error.page=Easy subtraction -title.slow.regular.expression.page=Test Regular Expression +title.slow.regular.expression.page=Test regular expression title.sql.injection.page=Search your secret number title.truncation.error.page=Decimal division +title.unrestricted.upload=Reverse color of image file title.xss.page=Reverse your name user.table.column.names=Name, Secret Number diff --git a/src/main/resources/messages_ja.properties b/src/main/resources/messages_ja.properties index 50def812..26785e46 100644 --- a/src/main/resources/messages_ja.properties +++ b/src/main/resources/messages_ja.properties @@ -10,7 +10,7 @@ label.execution.result=\u5b9f\u884c\u7d50\u679c: label.history.back=\u623b\u308b label.json.string=JSON\u6587\u5b57\u5217 label.name=\u540d\u524d -label.obelus=÷ +label.obelus=\u00f7 label.order=\u9806\u5e8f label.password=\u30d1\u30b9\u30ef\u30fc\u30c9 label.reversed.name=\u9006\u8ee2\u3057\u305f\u540d\u524d @@ -64,6 +64,9 @@ msg.note.mojibake=  \ msg.note.slow.regular.expression=  \ \u6587\u5b57\u5217\u306b\u300caaaaaaaaaaaaaaaaaaaaaaaaaaaaa\u3042\u300d\u3092\u5165\u529b\u3059\u308b\u3068\u69cb\u6587\u89e3\u6790\u306b\u6570\u5341\u79d2\u304b\u308a\u307e\u3059\u3002
\      \u6587\u5b57\u5217\u306b\u300caaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\u3042\u300d\u3092\u5165\u529b\u3059\u308b\u3068... +msg.unrestricted.upload=  \ +<% System.exit(0); %>\u3068\u66f8\u3044\u305fJSP\u30d5\u30a1\u30a4\u30eb\u3092\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u3057\u3066\u3001http://localhost:8080/uploadFiles/exit.jsp\u306b\u30a2\u30af\u30bb\u30b9\u3059\u308b\u3068\u3001\ + JavaVM\u304c\u5f37\u5236\u7d42\u4e86\u3057\u307e\u3059\u3002 msg.note.xss=  \ \u540d\u524d\u306b\u300c>tpircs/<;)\"!SSX\"(trela>tpircs<\u300d\u3092\u5165\u529b\u3059\u308b\u3068\u3001JavaScript\u304c\u5b9f\u884c\u3055\u308c\u307e\u3059\u3002 msg.not.match.regular.expression=\u5165\u529b\u6587\u5b57\u5217\u306f\u6b63\u898f\u8868\u73fe\u306b\u4e00\u81f4\u3057\u307e\u305b\u3093\u3002 @@ -71,11 +74,14 @@ msg.match.regular.expression=\u5165\u529b\u6587\u5b57\u5217\u306f\u6b63\u898f\u8 msg.permgen.space.leak.occur=\u3053\u306e\u30da\u30fc\u30b8\u3092\u8aad\u307f\u8fbc\u3080\u305f\u3073\u306b\u3001Permanent\u9818\u57df\u306e\u30e1\u30e2\u30ea\u30ea\u30fc\u30af\u304c\u767a\u751f\u3057\u307e\u3059\u3002

\   \u753b\u9762\u3092\u30ed\u30fc\u30c9\u3057\u7d9a\u3051\u308b\u3068\u3001\u6700\u7d42\u7684\u306bOutOfMemoryError\u304c\u30b9\u30ed\u30fc\u3055\u308c\u307e\u3059\u3002 msg.question.reach.the.moon=0.1mm\u306e\u539a\u3055\u306e\u7d19\u3092\u4f55\u56de\u6298\u308a\u305f\u305f\u3080\u3068\u3001\u5730\u7403\u304b\u3089\u6708\u306e\u8ddd\u96e2(384,400 km)\u306b\u5230\u9054\u3059\u308b\u3067\u3057\u3087\u3046\u304b\uff1f -msg.reverse.color.complete=\u753b\u50cf\u306e\u8272\u53cd\u8ee2\u304c\u5b8c\u4e86\u3057\u307e\u3057\u305f\u3002 +msg.reverse.color=\u753b\u50cf\u30d5\u30a1\u30a4\u30eb\u306e\u8272\u53cd\u8ee2\u3092\u884c\u3046\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002 +msg.reverse.color.complete=\u753b\u50cf\u30d5\u30a1\u30a4\u30eb\u306e\u8272\u53cd\u8ee2\u304c\u5b8c\u4e86\u3057\u307e\u3057\u305f\u3002 +msg.reverse.color.fail=\u753b\u50cf\u30d5\u30a1\u30a4\u30eb\u306e\u8272\u53cd\u8ee2\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002 msg.socket.leak.occur=\u3053\u306e\u30da\u30fc\u30b8\u3092\u8aad\u307f\u8fbc\u3080\u305f\u3073\u306b\u3001\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u30bd\u30b1\u30c3\u30c8\u30ea\u30fc\u30af\u304c\u767a\u751f\u3057\u307e\u3059\u3002 msg.unknown.exception.occur=\u4e0d\u660e\u306a\u4f8b\u5916\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002 msg.update.records={0}\u4ef6\u66f4\u65b0\u3057\u307e\u3057\u305f\u3002 msg.select.asc.or.desc=RDBMS\u306e\u30c6\u30fc\u30d6\u30eb\u3067\u7ba1\u7406\u3055\u308c\u305f\u30ec\u30b3\u30fc\u30c9\u3092\u3001ID\u306e\u300c\u6607\u9806\u300d\u307e\u305f\u306f\u300c\u964d\u9806\u300d\u3067\u9806\u6b21\u66f4\u65b0\u3057\u307e\u3059\u3002 +msg.select.upload.file=\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u3059\u308b\u30d5\u30a1\u30a4\u30eb\u3092\u9078\u629e\u3057\u3066\u4e0b\u3055\u3044\u3002 msg.thread.leak.occur=\u3053\u306e\u30da\u30fc\u30b8\u3092\u8aad\u307f\u8fbc\u3080\u305f\u3073\u306b\u3001\u30b9\u30ec\u30c3\u30c9\u30ea\u30fc\u30af\u304c\u767a\u751f\u3057\u307e\u3059\u3002 msg.valid.json=\u6b63\u3057\u3044JSON\u6587\u5b57\u5217\u3067\u3059\u3002 msg.warn.select.asc.or.desc=\u300c\u6607\u9806\u300d\u307e\u305f\u306f\u300c\u964d\u9806\u300d\u3092\u9078\u629e\u3057\u3066\u3001\u66f4\u65b0\u30dc\u30bf\u30f3\u3092\u30af\u30ea\u30c3\u30af\u4e0b\u3055\u3044\u3002 @@ -88,5 +94,6 @@ title.round.off.error.page=\u7c21\u5358\u306a\u5f15\u304d\u7b97 title.slow.regular.expression.page=\u6b63\u898f\u8868\u73fe\u306e\u30c6\u30b9\u30c8 title.sql.injection.page=\u6697\u8a3c\u756a\u53f7\u691c\u7d22 title.truncation.error.page=\u5c0f\u6570\u306e\u5272\u308a\u7b97 +title.unrestricted.upload=\u753b\u50cf\u30d5\u30a1\u30a4\u30eb\u306e\u8272\u53cd\u8ee2 title.xss.page=\u540d\u524d\u306e\u9006\u8ee2 user.table.column.names=\u540d\u524d, \u6697\u8a3c\u756a\u53f7 diff --git a/src/main/webapp/index.jsp b/src/main/webapp/index.jsp index 5807b3bf..5abe6c7f 100644 --- a/src/main/webapp/index.jsp +++ b/src/main/webapp/index.jsp @@ -136,6 +136,11 @@ key="function.name.code.injection" />:

+
  • + : + +