Add HTTP decryption (stable)

This commit is contained in:
Namhyeon Go 2022-11-25 19:32:17 +09:00
parent 20bda58945
commit 9402eb9d46
2 changed files with 55 additions and 42 deletions

View File

@ -2,10 +2,10 @@
// HTTP proxy implementation with PHP socket // HTTP proxy implementation with PHP socket
// Namhyeon Go <gnh1201@gmail.com> // Namhyeon Go <gnh1201@gmail.com>
// Created at: 2022-10-06 // Created at: 2022-10-06
// Updated at: 2022-10-07 // Updated at: 2022-11-25
if (strpos($_SERVER['HTTP_USER_AGENT'], "php-httpproxy/") !== 0) { if (strpos($_SERVER['HTTP_USER_AGENT'], "php-httpproxy/") !== 0) {
exit('<!DOCTYPE html><html><head><title>It works!</title><meta charset="utf-8"></head><body><h1>It works!</h1></body></html>'); exit('<!DOCTYPE html><html><head><title>It works!</title><meta charset="utf-8"></head><body><h1>It works!</h1><p>Version: 0.1.3</p></body></html>');
} }
ini_set("default_socket_timeout", 1); // must be. because of `feof()` works ini_set("default_socket_timeout", 1); // must be. because of `feof()` works
@ -39,13 +39,16 @@ $relay_port = intval($data['port']);
$relay_scheme = $data['scheme']; $relay_scheme = $data['scheme'];
$relay_hostname = $data['server']; $relay_hostname = $data['server'];
if ($relay_scheme == "https") {
$relay_hostname = "tls://" . $relay_hostname;
}
switch ($relay_headers['@method'][0]) { switch ($relay_headers['@method'][0]) {
case "CONNECT": // { case "CONNECT":
echo sprintf("%s 200 Connection Established\r\n\r\n", $relay_headers['@method'][2]); echo sprintf("%s 200 Connection Established\r\n\r\n", $relay_headers['@method'][2]);
break; break;
// }
default: // { default:
$fp = fsockopen($relay_hostname, $relay_port, $errno, $errstr, 1); $fp = fsockopen($relay_hostname, $relay_port, $errno, $errstr, 1);
if (!$fp) { if (!$fp) {
@ -61,5 +64,4 @@ switch ($relay_headers['@method'][0]) {
fclose($fp); fclose($fp);
} }
// } }
}

View File

@ -1,7 +1,7 @@
# gnh1201/php-httpproxy # gnh1201/php-httpproxy
# Go Namyheon <gnh1201@gmail.com> # Go Namyheon <gnh1201@gmail.com>
# Created at: 2022-10-06 # Created at: 2022-10-06
# Updated at: 2022-10-24 # Updated at: 2022-11-25
import argparse import argparse
import socket import socket
@ -63,33 +63,38 @@ def start(): #Main Program
sys.exit(1) sys.exit(1)
def conn_string(conn, data, addr): def conn_string(conn, data, addr):
first_line = data.split(b'\n')[0] try:
first_line = data.split(b'\n')[0]
method, url = first_line.split()[0:2] method, url = first_line.split()[0:2]
http_pos = url.find(b'://') #Finding the position of :// http_pos = url.find(b'://') #Finding the position of ://
scheme = b'http' # check http/https or other protocol scheme = b'http' # check http/https or other protocol
if http_pos == -1: if http_pos == -1:
temp = url temp = url
else: else:
temp = url[(http_pos+3):] temp = url[(http_pos+3):]
scheme = url[0:http_pos] scheme = url[0:http_pos]
port_pos = temp.find(b':') port_pos = temp.find(b':')
webserver_pos = temp.find(b'/') webserver_pos = temp.find(b'/')
if webserver_pos == -1: if webserver_pos == -1:
webserver_pos = len(temp) webserver_pos = len(temp)
webserver = "" webserver = ""
port = -1 port = -1
if port_pos == -1 or webserver_pos < port_pos: if port_pos == -1 or webserver_pos < port_pos:
port = 80 port = 80
webserver = temp[:webserver_pos] webserver = temp[:webserver_pos]
else: else:
port = int((temp[(port_pos+1):])[:webserver_pos-port_pos-1]) port = int((temp[(port_pos+1):])[:webserver_pos-port_pos-1])
webserver = temp[:port_pos] webserver = temp[:port_pos]
if port == 443: if port == 443:
scheme = b'https' scheme = b'https'
except Exception as e:
conn.close()
print("[*] Exception on parsing the header of %s. Because of %s" % (str(addr[0]), str(e)))
return
proxy_server(webserver, port, scheme, method, url, conn, addr, data) proxy_server(webserver, port, scheme, method, url, conn, addr, data)
@ -97,8 +102,10 @@ def proxy_connect(webserver, conn):
hostname = webserver.decode('utf-8') hostname = webserver.decode('utf-8')
certpath = "%s/%s.crt" % (certdir.rstrip('/'), hostname) certpath = "%s/%s.crt" % (certdir.rstrip('/'), hostname)
conn.send(b'HTTP/1.1 200 Connection Established\r\n') # https://stackoverflow.com/questions/24055036/handle-https-request-in-proxy-server-by-c-sharp-connect-tunnel
conn.send(b'HTTP/1.1 200 Connection Established\r\n\r\n')
# https://github.com/inaz2/proxy2/blob/master/proxy2.py
try: try:
if not os.path.isfile(certpath): if not os.path.isfile(certpath):
epoch = "%d" % (time.time() * 1000) epoch = "%d" % (time.time() * 1000)
@ -108,24 +115,30 @@ def proxy_connect(webserver, conn):
except Exception as e: except Exception as e:
print("[*] Skipped generating the key. %s" % (str(e))) print("[*] Skipped generating the key. %s" % (str(e)))
# https://stackoverflow.com/questions/11255530/python-simple-ssl-socket-server
# https://docs.python.org/3/library/ssl.html
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context.load_cert_chain(certpath, certkey) context.load_cert_chain(certpath, certkey)
# what the heck? why hang? # https://stackoverflow.com/questions/11255530/python-simple-ssl-socket-server
conn = context.wrap_socket(conn, server_side=True) conn = context.wrap_socket(conn, server_side=True)
data = conn.recv(buffer_size)
return conn return (conn, data)
def proxy_server(webserver, port, scheme, method, url, conn, addr, data): def proxy_server(webserver, port, scheme, method, url, conn, addr, data):
try: try:
print("[*] Started Request. %s" % (str(addr[0]))) print("[*] Started Request. %s" % (str(addr[0])))
if scheme in [b'https', b'tls', b'ssl'] and method == b'CONNECT': try:
conn = proxy_connect(webserver, conn) if scheme in [b'https', b'tls', b'ssl'] and method == b'CONNECT':
conn, data = proxy_connect(webserver, conn)
except Exception as e:
raise Exception("SSL negotiation failed. %s" % (str(e)))
proxy_data = { proxy_data = {
'headers': { 'headers': {
"User-Agent": "php-httpproxy/0.1.3-dev (Client; Python " + python_version() + ")", "User-Agent": "php-httpproxy/0.1.3 (Client; Python " + python_version() + "); abuse@catswords.com",
}, },
'data': { 'data': {
"data": base64.b64encode(data).decode("utf-8"), "data": base64.b64encode(data).decode("utf-8"),
@ -139,8 +152,6 @@ def proxy_server(webserver, port, scheme, method, url, conn, addr, data):
"datetime": datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f") "datetime": datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")
} }
} }
print (proxy_data)
raw_data = json.dumps(proxy_data['data']) raw_data = json.dumps(proxy_data['data'])
print("[*] Sending %s bytes..." % (str(len(raw_data)))) print("[*] Sending %s bytes..." % (str(len(raw_data))))
@ -151,12 +162,12 @@ def proxy_server(webserver, port, scheme, method, url, conn, addr, data):
conn.send(chunk) conn.send(chunk)
i = i + 1 i = i + 1
print("[*] Received %s chucks. (%s bytes/chuck)" % (str(i), str(buffer_size))) print("[*] Received %s chucks. (%s bytes per chuck)" % (str(i), str(buffer_size)))
print("[*] Request Done. %s" % (str(addr[0]))) print("[*] Request and received. Done. %s" % (str(addr[0])))
conn.close() conn.close()
except Exception as e: except Exception as e:
print("[*] f: proxy_server: %s" % (str(e))) print("[*] Exception on requesting the data. Because of %s" % (str(e)))
conn.close() conn.close()
if __name__== "__main__": if __name__== "__main__":