Skip to content

Commit

Permalink
Add a file upload servlet which can crash JVM
Browse files Browse the repository at this point in the history
  • Loading branch information
k-tamura committed Mar 2, 2017
1 parent b901f38 commit 7bf1722
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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("<form method=\"post\" action=\"urupload\" enctype=\"multipart/form-data\">");
bodyHtml.append("Select file to upload: <input type=\"file\" name=\"file\" size=\"60\" /><br>");
bodyHtml.append("<br><input type=\"submit\" value=\"Upload\" />");
bodyHtml.append(MessageUtils.getMsg("msg.reverse.color", locale));
bodyHtml.append("<br><br>");
bodyHtml.append("<input type=\"file\" name=\"file\" size=\"60\" /><br>");
bodyHtml.append(MessageUtils.getMsg("msg.select.upload.file", locale));
bodyHtml.append("<br><br>");
bodyHtml.append("<input type=\"submit\" value=\"Upload\" />");
bodyHtml.append("<br><br>");
bodyHtml.append(MessageUtils.getMsg("msg.unrestricted.upload", locale));
bodyHtml.append("</form>");
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 {
Expand Down Expand Up @@ -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("<br><br>");
bodyHtml.append("<img src=\"" + SAVE_DIR + "/" + fileName + "\">");
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("<br><br>");
bodyHtml.append("<img src=\"" + SAVE_DIR + "/" + fileName + "\">");
}
bodyHtml.append("<br><br>");
bodyHtml.append("<INPUT type=\"button\" onClick='history.back();' value=\""
+ MessageUtils.getMsg("label.history.back", locale) + "\">");
Expand All @@ -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));
}
}
2 changes: 2 additions & 0 deletions src/main/resources/indexpage_en.properties
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions src/main/resources/indexpage_ja.properties
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
11 changes: 9 additions & 2 deletions src/main/resources/messages_en.properties
Original file line number Diff line number Diff line change
Expand Up @@ -66,16 +66,22 @@ msg.note.ldap.injection=<span class="glyphicon glyphicon-info-sign"></span>&nbsp
You can see other users information if you set name to "*)(|(objectClass=*" and password to "aaaaaaa)"
msg.note.mojibake=<span class="glyphicon glyphicon-info-sign"></span>&nbsp; \
Mojibake occurs if you set name in a multibyte language
msg.unrestricted.upload=<span class="glyphicon glyphicon-info-sign"></span>&nbsp; \
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=<span class="glyphicon glyphicon-info-sign"></span>&nbsp; \
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.<BR><BR> \
<span class="glyphicon glyphicon-info-sign"></span>&nbsp; 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.
Expand All @@ -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
11 changes: 9 additions & 2 deletions src/main/resources/messages_ja.properties
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -64,18 +64,24 @@ msg.note.mojibake=<span class="glyphicon glyphicon-info-sign"></span>&nbsp; \
msg.note.slow.regular.expression=<span class="glyphicon glyphicon-info-sign"></span>&nbsp; \
\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<br> \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\u6587\u5b57\u5217\u306b\u300caaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\u3042\u300d\u3092\u5165\u529b\u3059\u308b\u3068...
msg.unrestricted.upload=<span class="glyphicon glyphicon-info-sign"></span>&nbsp; \
<% 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=<span class="glyphicon glyphicon-info-sign"></span>&nbsp; \
\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
msg.match.regular.expression=\u5165\u529b\u6587\u5b57\u5217\u306f\u6b63\u898f\u8868\u73fe\u306b\u4e00\u81f4\u3057\u307e\u3057\u305f\u3002
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<BR><BR> \
<span class="glyphicon glyphicon-info-sign"></span>&nbsp; \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
Expand All @@ -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
5 changes: 5 additions & 0 deletions src/main/webapp/index.jsp
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,11 @@
key="function.name.code.injection" /></a>:
<fmt:message key="function.description.code.injection" />
</p></li>
<li><p>
<a href="urupload" target="_blank"><fmt:message
key="function.name.unrestricted.upload" /></a>:
<fmt:message key="function.description.unrestricted.upload" />
</p></li>
</ul>

<h2>
Expand Down

0 comments on commit 7bf1722

Please sign in to comment.