Tag Archives: exploit

Windows exploit development ( the hard way )

ExploitLogo

Hello !

Today I’m going to share with you the hard time I was having creating a working exploit for “KnFTP Server”, please read the full post as there are many interesting things inside and they might come in handy for you someday !

Vulnerable software : “KnFTP Server 1.0.0” ( https://www.exploit-db.com/apps/182e4b13190ed23c06c8647dda9198dd-knftpd-1.0.0-bin.zip )

Crash POC : https://www.exploit-db.com/exploits/17856/

  • Fuzzing : 

Since we already have the crash POC we won’t dive deep into “how-to fuzzing”. Looking at the crash POC we see that the vulnerable command is “PWD” :

———————————————————————————————–

import socket
buffer = "\x41" * 9000
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
connect=s.connect(('IP',21))
s.recv(1024)
s.send('USER test\r\n')
s.recv(1024)
s.send('PASS test\r\n')
s.recv(1024)
s.send('PWD ' + buffer + '\r\n')
s.recv(1024)
s.send('QUIT\r\n')
s.close
———————————————————————————————–

Just to confirm that we have control over the SEH handler we replicate the crash, I hooked up the process to immunity debugger then lunched the script and here is what I got :

1

2

Great ! so now we have to determine the right amount of data to send in order to overwrite SEH. For this I used “pattern_create.rb” and “pattern_offset.rb” from Metasploit.

First, I created a 9000 long pattern :

3

Then I replaced the “\x41″*9000 with it :

4

So now the script should send that pattern we created and once the application crash we get pull out the exact bytes that overwrote SEH and pass it to “pattern_offset.rb” in order to tell their location :

6

7

Ok, we now know that SEH is overwritten after 324 bytes of data. We can confirm that by sending 324 bytes of data followed by 4 B’s and we should overwrite SEH with “42424242” … let’s see :

8

9

Awesome ! now we confirmed that we own SEH. Now we can jump to the exploitation part.

  • Exploitation : 

Since we have control over SEH handler the typical thing to do is :

  1. Search for an address that would point to a “pop pop ret” commands.
  2. Generate a shellcode ( and eliminate any bad characters from it ).
  3. Control the next SEH handler and replace it with a jump command.
  4. Fill in some nops ( for reliability ).
  5. The exploit would look something like : junk -> jmp_seh -> seh -> shellcode.

But not for this case AT ALL and let me tell why …

* Null character in the “pop pop ret” address :

I used the great “mona.py” script to search for a POP POP RET sequence and the output was :

10

Can you see the issue ? well .. yes null byte in the beginning of the addresses.

Since we can’t use a null byte in a regular exploit ( because a null byte would stop the execution of all the commands that comes after it ). We have to adopt another approach which is place everything before that address in our exploit, meaning :

junk -> shellcode -> jmp_back_to_shellcode -> seh

Using this method we can still have a null byte in our “pop pop ret” address because if for example take “0x004011CB”, the address will have to be inputted inverted ( little indian ) format : “\xCB\x11\x40\x00” so the last byte in our exploit is “\x00” and there is nothing coming after it. In fact there is no need to put the last “\x00” byte because the application will fill it automatically as it’s the end of the user input.

Let’s test this out ( shellcode = “44”*10 … just to test things out first ) :

11

12

Cool, we are now pointing to the right “POP POP RET” address and it’s taking us back to our controlled area.

We need to put things together now and see how it works, put in mind that we have about 300 bytes space for our shellcode.

Remember our exploit should look something like : junk -> shellcode -> jmp_back_to_shellcode -> seh ..

SEH is overwritten after 324 bytes, meaning that we need to subtract the size of ( junk + shellcode + jmp_back_to_shellcode ) from it. So we’ll now proceed with adding all other components to our exploit in order to have an accurate calculation.

**Jumps :

In order to create the opcode for the jump I used the “nasm_shell.rb” script :

13

We’ll leave our shellcode at last so we’ll fill it’s place with A’s, now that we have everything we need we can do calculations.

We need to pass 324 bytes of data at first the 3 bytes that follow it will overwrite the SEH handler, and the jump will occupy 2 bytes => so our exploit “for now” will look like this :

14

Let’s test it out :

15

Press F8 to take the jump !

16

But !!! since we filled in 322 bytes of A’s and we are jumping 100 bytes ( backwards ) it means we should jump to A’s not this !!

I soon came to the realization that this is messed up and I have to work with the 28 bytes and make something …  an egghunter comes to mind but it’ll need at least 32 bytes ..

I was messing around and thought of making use of the small chunks of data I have control over with the combination of that 28 bytes ( locate them using a pattern and use jumps to hop from chunk to another and execute the shellcode ) but really we don’t have much space ! the only 3 chunks I found were like 4 bytes so it doesn’t really help.

* Tight space : 

Until I had a moment of glory when I found out ( using mona.py ) that the rest of the chunk is located in a different address :

18

19

Still not much space but something to work with, what I need to do is the following :

  1. Send a shellcode to the application before crashing it using some other commands like “CWD”
  2. Since the shellcode now reside in memory I can point the execution flow to that space I found and place an egghunter there to search for the shellcode and execute it.

But first I need to make sure I had control over that area, I used the 32 bytes of the “BEAUTIFUL” egghunter code inside the junk data and see if I can have it there ( if not then create a pattern, get the lower and the higher addresses of that chunk of data and locate it **EXTRA WORK** )

21

CONFIRMED ! egghunter is there, but the last thing we need to do is place it somewhere in the middle of those 322 bytes because we see that if we place it at the end then it’s going to corrupt the execution flow as the “pop pop ret” is going to point directly to the last byte of the egghunter which is “JMP EDI”.

22

WAIT WAIT !!!

At some point we’ll need to jump to that chunk of data, replace those A’s with a nop slide and the egghunter will be executed, but we see that if we need to jump to that chunk then we’re going to have to use addresses that begin with a null byte …. OH NOT AGAIN !!

* Null character .. again : ( Creativity )

Now we have to overcome the null byte issue again, how are we going to jump to an address that begins with a null byte inside exploit. We already clarified that we can’t have any null byte inside our exploit as it’s going to terminate the execution flow.

With little thinking I came up with an idea, if I can put some commands that are going to generate the address for me ( those commands will not use null bytes ) and place it in a register then jmp to it … POSSIBLE !!

The 28 bytes of space are going to come REALLY REALLY handy as we’re going to use them in order to generate the address that begins with a null byte.

For that we’ll have to do some assembly calculations, what instructions and values we can use in order to generate a value of “003E3988” !!

We’ll use the EAX register to store the value and “JMP EAX” in order to jump to our egghunter …

After some calculations I’ve came up with the following commands that are going to generate “003E3988” in EAX for us :

AND EAX,41414141 “ZERO OUT EAX”
AND EAX,3E3E3E3E “ZERO OUT EAX”
SUB EAX,4B4A687D
SUB EAX,6A3C0951
SUB EAX,4A3B5468 “=> EAX=003E3988”

I have generated the opcode for those commands and the final code is : “\x25\x41\x41\x41\x41\x25\x3E\x3E\x3E\x3E\x2D\x7D\x68\x4A\x4B\x2D\x51\x09\x3C\x6A\x2D\x68\x54\x3B\x4A” and it’s 25 bytes long .. so close .. so close …

Where to put it ? remember that placing something at the end of our junk data will automatically be at the 28 bytes space ? this is going to be there so we’ll append this code at the end.

We now only need to use that jmp in order to place ourselves at the beginning of the generator ( jump back 28 bytes “\xEB\xE2” ) and place a “JMP EAX” ( \xFF\xE0 ) at the end of that since we have extra LAST 5 bytes.

24

**Testing :

25

YAAAAY !!! we got a reliable execution flow and it’s  now pointing to that chunk of data and you can see the egghunter there just sitting waiting to be executed 🙂

* Putting it all together :

  1. We have to replace the A’s with nops inside our exploit because we are hitting A’s too much and they could interrupt the execution flow, in the other side if we hit nops slide then we are 100% sure that the next instruction after then will be executed.
  2. I have tested our characters and we don’t have any limitations on the “CWD” command only “x00 and xFF”.
  3. We don’t have any shellcode size restriction now as we are injecting it from a different dedicated input.

I have added a bind meterpreter shellcode on port 4444, lunched the exploit and started the multi_handler aaaaand … :

17

VOILA ! this is what I wanted to share with you and I hope it’ll help you overcome the issues I was having when creating this exploit.

Exploit code is available at : https://github.com/MrNasro/scripts/blob/master/KnFTP_1.0.0_exploit.py

THANKS !

Tagged , , , ,

A vulnerability and a hidden admin account all inside “SITEL DS114-W” routers !

Hello, Hope you are doing well everyone ! It has been a long time since my last post, well let’s say I was occupied by some stuff but I’m back with a new discovery 🙂

As as an Algerian internet consumer, I’m a subscriber at “Djaweb ISP” as I don’t have much choices — let’s not talk about that now and dive into some serious stuff !

I found out the routers shipped by Algerian ISP “Djaweb” are now backdoored with a secret admin account and as it appears they didn’t do a good job in hiding it  … not only that but with a session management vulnerability too !

EXPLORATION :

As usual internet goes down from time to time and we are used to that in Algeria, this time it took long time so I went to restart the modem from the web interface .

VULNERABILITY #1 :

But after restarting it I logged out and kept looking at the “login” page thinking “What if there is a vulnerability inside .. ?” and that’s when the journey started ..

login

As usual, I hooked up “Burp” as a proxy and logged in :

2

“Cookie : SessionID=3” … too easy to predict !

Now comes Burp “Intruder” functionality, it will allow us to brute force any parameter inside the request body and that’s exactly what we need to brute force the SessionID .

Steps : ( quick tips for Burp )

1- Right click on the request and click “Send to Intruder”

2- Go to the “intruder” tab you’ll see :

Screen Shot 2015-01-04 at 3.23.38 AM

3- Navigate to “Positions”, that’s where we are going to specify the parameter we want to brute force. Leave the “Attack type” to “Sniper”

Screen Shot 2015-01-04 at 3.24.25 AM

4- Go to “payloads” and set the payload type to “Numbers” with :

  • Type : Sequential
  • From : 1
  • To : 100
  • Step : 1

Screen Shot 2015-01-04 at 3.25.10 AM

So in total the app will make 100 requests to the router      

Now with everything set I fired up the intruder attack and …

Screen Shot 2015-01-04 at 3.25.21 AM

We can see that the session #4 is what we had earlier initialized for our access by the web app :

Screen Shot 2015-01-04 at 3.47.24 AM

But when scrolling down we see some weird things :

Screen Shot 2015-01-04 at 3.47.44 AM

Sessions from 40 to 49 are also initialized, I logged off the sessions dropped down .. when logged back in and brute forced the session IDs they appear to be another 10 sessions initialized on another range .

Knowing that the user only require one session to be initialized and it should be hooked to only the user logged in, not any other one, so when the user login to the router other sessions are initialized giving an attacker with a simple brute force access to the router without knowing the password .

This makes up a session management vulnerability .

pwned

The vendor has been notified but without response from them .

VULNERABILITY #2 :

I had a sense that there was more than one vulnerability inside that damn thing … so have gone further, testing every functionality from login to rebooting the modem and while doing that I came up across another weird thing. The thing resides inside the config file.

Step 1 : I saved the config file, while burp is hooked up as usual .

Step 2 : The router give you a “.img” file which when executed under a OSX environment you’ll get :

Screen Shot 2015-01-04 at 7.52.15 PM

As it’s not a valid image to be mounted . I looked into the burpsuite request-response raw data and surprisingly :

Screen Shot 2015-01-04 at 3.49.46 AM

The configuration parameters are saved in a plain text format !!! I inspected every parameter inside until ….. :

Screen Shot 2015-01-04 at 7.57.22 PM

The first two account I did set and the passwords are the ones I specified, but what about that 3rd “admin” account that has a parameter saying “<V N=”BACKDOOR” V=”0x1″/>”, which means “BACKDOOR = YES”

Trying to ssh to the router with that account :

Screen Shot 2015-01-04 at 8.03.32 PM

Aaaand, IT WORKS !!!

picard-facepalm7

Well, obviously the routers are shipped by the ISP with a backdoor account, and this is the 2nd discovery ! I have built a python script that automate the process of the two attacks :

  • If the user is already logged into the router and have a valid session we can brute force the whole range from 1 to 100 in order to find the other initialized session, and to save time you can chose a step of “10” from 1 to 100 so you’ll only make “10” requests to the router instead of “100” to successfully login .
  • If the attacker is not sure if the user is logged into the account and want to get access then use the backdoor account : Username : admin , Password : 5B80airocon

The vendor has been notified but without response from them .

CONCLUSION :

Routers are becoming the main attack surface for bad hackers, as it’s the entry point for them to take over your network . Make sure your router is secure and doesn’t expose any service ( HTTP, SSH, FTP ) to the wild web .

As usual happy hacking :), for any questions please leave a comment !

Tagged , , , , ,

“Mobilis Algeria” Millions of users at risk

Hello guys,

I’m back with a new post and a new discovery. As I’m a Mobilis GSM subscriber I thought about registering to their online invoice system, I took the steps and I have been provided with access to my account online .

EXPLORING THE WONDERLAND :

When you first login you get this page :

1

You can do some things from here, like viewing/downloading your invoices and canceling the online account, we are mainly interested in the invoices as they contain all information about the target in order to help conduct further attacks on him/her
2

I hooked up burp suite proxy to the browser and I logged in, I was amazed about what I was seeing 😮 …. this is happening upon login :

3

5

Isn’t that a session initializer ? : /servlet/InitSessionExt?USER=”account_id”&ACCESS=1&INVOICE=”invoice_id”

The “account_id” can be brute forced as it a sequence number, but how can we get the “invoice_id” for the target account if we don’t have access yet ? .. remember the Graph we saw previously ? well it could be our entry point as it reveals all invoices ids for a particular account .

With fingers crossed I tried to pass a “random” 😉 account_id

6

wow !! I got all invoices numbers associated to that account 😀

And now that I have everything I can pass those paramerters to the “InitSessionExt” using Burp repeater and see if it initilize the session without a password required,

Screen Shot 2014-08-20 at 6.55.52 PM

And ….

7

 

YES ! I’m in (y)

8

A malicious attacker can then use those information to social engineer the help desk guys into doing things to the account like suspending it, I’ll let you work the machine and think about other potential scenarios 🙂

 

VIDEO POC :

Tagged , , ,