Portcullis Labs » fuzzing https://labs.portcullis.co.uk Research and Development en-US hourly 1 http://wordpress.org/?v=3.8.5 This way to 10.10.10.1: Playing with labelled switching https://labs.portcullis.co.uk/blog/this-way-to-10-10-10-1-playing-with-labeled-switching/ https://labs.portcullis.co.uk/blog/this-way-to-10-10-10-1-playing-with-labeled-switching/#comments Fri, 17 Apr 2015 15:28:45 +0000 https://labs.portcullis.co.uk/?p=5080 As a pentester, there are days when you’ll get asked to look at the ordinary, and there are days that you’ll be asked to look at something more challenging. This week was full of days that met the latter criteria and not the former. Whilst I can’t share the scope, Portcullis was asked to examine […]

The post This way to 10.10.10.1: Playing with labelled switching appeared first on Portcullis Labs.

]]>
As a pentester, there are days when you’ll get asked to look at the ordinary, and there are days that you’ll be asked to look at something more challenging. This week was full of days that met the latter criteria and not the former. Whilst I can’t share the scope, Portcullis was asked to examine a network implementation using the MPLS protocol and comment on the security, or otherwise, of it.

I suspect that the reasons why I was selected to lead this task were two fold: one I happen to co-own AS28792 and am not therefore an Internet n00b and two, rumour has it that I once “heckled” a talk on just this subject. Rumours can be unfair and I don’t recall the full details but, as I remember it, I simply answered a question from a fellow audience member on how MPLS labels are meant to be processed.

For those of you that may not have heard of it, MPLS is not a commonly used protocol, at least not outside of tier 1 networks. The purpose of this blog post isn’t to discuss the ins and outs of the protocol, but rather to show how we used the Scapy framework to quickly craft MPLS labelled packets and to highlight why it is important that testers can code.

Given the testing requirements, the Team examined the options available to complete the assessment. There are few, if any, tools that can be used to appropriately test MPLS implementations. The toolset I had in mind (having previously used it) was no longer available and whilst Google has a “not yet mainline” MPLS implementation for the Linux kernel, it seemed an inefficient use of time to get that running. In such circumstances, we would need to develop our own code quickly.

Scouring the Internet, I came across a post on the use of Scapy to craft MPLS packets. The code has a couple of bugs (IMO), around misnaming the bottom of stack marker bitfield and the author’s choice of default TTL, but otherwise it does the trick.

Consider the following code, taken from the post:

class MPLS(Packet):
        name = "MPLS"
        fields_desc =  [
                BitField("label", 3, 20),
                BitField("experimental_bits", 0, 3),
                BitField("bottom_of_label_stack", 1, 1), # Now we're at the bottom
                ByteField("TTL", 255)
        ]

This snippet specifies an MPLS class which, given Packet, will add 4 fields worth of data. The fields in question map on to the 32-bits of an MPLS header. I’ll leave you to read up on what the header will actually look like, but suffice it to say, label affects where packets go, TTL affects how far they go and bottom_of_label_stack and experimental_bits affect how the labels are processed along the way by routers (technically it’s a bit more complicated than that, but it will do as a starting point). The label has a length of 20 bits and a default value of 3 (a special reserved label meaning Implicit NULL Label), whilst the bottom_of_label_stack marker has a length of 1 bit and a default value of 1. As a byte field, TTL has an implicit length of 8 bits.

Next we have the following:

bind_layers(Ether, MPLS, type = 0x8847) # Marks MPLS
bind_layers(MPLS, MPLS, bottom_of_label_stack = 0) # We're not at the bottom yet
bind_layers(MPLS, IP)

In Scapy, we use bind_layers() to specify how various headers can be ordered within the overall packet. What this says is that an MPLS header can follow either an Ethernet header (with a type of 0×8847) or another MPLS header. In the latter case we should set the previous MPLS header’s bottom_of_label_stack marker to 0, to indicate that there is at least one further label header. Finally, we must follow our MPLS layer headers up with an IP header, before traversing into the more traditional TCP or UDP packet structure.

To craft a MPLS labelled packet, we can then call the following Python code:

p = Ether(src = "<my MAC address>", dst = "<next hop MAC address>") / MPLS(label = 255, TTL = 255) / IP(src = "<my IP address>", dst = "<target IP address>") / TCP(dport = 80)
p.show()
sendp(p, iface="eth0")

In layman’s terms, this means we will create an Ethernet frame, containing an MPLS header, with a label and TTL of 255, with an IP header and finally a TCP header.

Having shown how we can craft a TCP packet, let us look at the minimum set of MPLS protocol vulnerabilities we need to test for. The client had obviously read some papers on MPLS security, or at least RFC 4381, since the aims of the assessment identified the main points of concern as follows:

  • Test for rejection of MPLS labelled packets on a P(provider) E(dge) interface
  • Test for rejection of MPLS labelled packets with no bottom_of_label_stack marker
  • Test for rejection of MPLS labelled packets with an early bottom_of_label_stack marker
  • Test for rejection of MPLS labelled packets with large numbers of labels

The first test is about ensuring that the PE router cannot be tricked into misdirecting malicious packets, whilst the latter 3 are a minimum test set designed to ensure that it does not misprocess the packets in a way that may lead to Denial of Service or worse. A correct implementation will therefore gracefully reject MPLS packets in each of these cases.

There are of course more test cases that we could consider, and indeed the Team ended up using p.fuzz() to create infinite malformed packets, but let’s look at these test cases which formed the basis of our assessment.

An analogy for those of you that are unfamiliar with MPLS would be 802.11q tagging and whether a switch will accept a pre-tagged packet with a spoofed VLAN ID. In the VLAN world, acceptance of a spoofed ID would place the attacker on a VLAN for which they have not been authorised. In the case of MPLS, acceptance of a spoofed MPLS label might give the attacker access to another customer’s private virtual network. MPLS networks, and the P routers from which they are constructed, inherently trust the labels, so if you gain access beyond the PE, all bets are off.

In order to answer our client’s questions, we need to determine whether our MPLS labelled packets are rejected. RFC 4364 states that “a backbone router does not accept labelled packets over a particular data link, unless it is known that that data link attaches only to trusted systems”. In this instance, the client’s MPLS core was fiber and it was not possible to connect a testing laptop directly to it, either to simulate the PE router itself or indeed to simulate any of the inner P routers that made up the core. We could however mimic a C(ustomer) E(dge) router and see the PE router which gave us some ideas on how determining acceptance could be achieved.

Firstly, the client was able to configure a spanning port on the PE router. This gave us the ability to visually inspect the traffic as it passed through and confirm that our crafted packets never left the incoming CE to PE interface. The second solution was a bit less reliable but avoided the need for the PE router (or indeed the client’s collaboration, in this instance). The Team had already observed that the PE router itself had an SSH service listening on a loopback interface for management and that it was possible to route to and indeed connect to this. The Team hypothesised that, if a TCP packet was sent (with the SYN flag set) and if the packets were labelled with MPLS headers, then the connection would fail and no response would be seen from the SSH service on the router. As expected, both approaches proved successful and the Team was able to show that our labelled packets were ignored by the PE router.

One last note and something our Technical Director commented upon. Isn’t it nice when implementations actually follow design? Hats off to the various MPLS RFC authors for producing a set of standards that can be followed by both the developers of these routers and the administrators who ultimately commission them.

The post This way to 10.10.10.1: Playing with labelled switching appeared first on Portcullis Labs.

]]>
https://labs.portcullis.co.uk/blog/this-way-to-10-10-10-1-playing-with-labeled-switching/feed/ 0
An introduction to binary dynamic analysis https://labs.portcullis.co.uk/blog/an-introduction-to-binary-dynamic-analysis/ https://labs.portcullis.co.uk/blog/an-introduction-to-binary-dynamic-analysis/#comments Tue, 13 May 2014 13:29:24 +0000 https://labs.portcullis.co.uk/?p=3001 The term dynamic instrumentation refers to the act of monitoring the execution of a program in order to extract debug information, to measure code performance or to detect errors. Dynamic instrumentation can be used to generate measures of functions properties such as execution time, call counts, registers status or call graphs. Tools Several software solutions […]

The post An introduction to binary dynamic analysis appeared first on Portcullis Labs.

]]>
The term dynamic instrumentation refers to the act of monitoring the execution of a program in order to extract debug information, to measure code performance or to detect errors. Dynamic instrumentation can be used to generate measures of functions properties such as execution time, call counts, registers status or call graphs.

Tools

Several software solutions exists to help the developers and researchers to commit this task of inspecting a program runtime behaviour, being some of the prominent the following ones:

Two of the the most widely used tool dynamic binary instrumentation tools are PIN and DynamoRIO. PIN is developed by Intel and provided by the University of Virginia whereas DynamoRIO is a collaboration between Hewlett-Packard and MIT. Both are free to use but only DynamoRIO is open source. PIN and DynamoRIO are both equally useful and usually the election is the result of personal taste.

mtrace

mtrace is the memory debugger included in the GNU C Library. The usage of mtrace(3) can be summarised as follows:

  1. Export the variable MALLOC_TRACE to point to the result logfile
  2. Include the header mcheck.h in the code
  3. Call to mtrace() before allocating memory
  4. Call untrace() at the end of the code (usually the main() function)
  5. Compile the program with debugging symbols (gcc prog.c -g)
  6. Read output using mtrace exec_file mtrace_output filename

Following a example extracted from the mtrace(3) man page to clarify the usage:

#include <mcheck.h>
#include <stdlib.h>
#include <stdio.h>

int main()
{
   int j;

   mtrace();

   for (j = 0; j < 2; j++)
       malloc(100);            /* Never freed--a memory leak */

   calloc(16, 16);             /* Never freed--a memory leak */
   exit(EXIT_SUCCESS);
}

A little script could be created in order to automate the compilation the analysis:

#!/bin/sh
export MALLOC_TRACE=mtrace.log
bin=prog
src=mtrace.c
gcc -g $src -o $bin
./$bin
mtrace $bin $MALLOC_TRACE

The execution will result in the following excerpt:

$ ./mtrace.sh 

Memory not freed:
-----------------
           Address     Size     Caller
0x0000000002054460     0x64  at /home/user/mtrace.c:11 (discriminator 2)
0x00000000020544d0     0x64  at /home/user/mtrace.c:11 (discriminator 2)
0x0000000002054540    0x100  at /home/user/mtrace.c:15

As can be seen, mtrace(3) has detected the error absence of free(), resulting in a memory leak error.

Intel PIN tool

PIN is a framework for creating dynamic binary analysis tools for the i386 and x86-64 architectures that can be used to perform program analysis on user space applications in Linux and Windows at run time on the compiled binary files. Pin provides an API that abstracts the instruction set and the binary schema and allows to inspect register contents, program code and symbol and debug information.

PIN performs instrumentation by taking control of the program just after it loads into memory and recompiling just-in-time sections of binary code just before they are run. Regarding the performance, PIN’s overhead is about 30 percent.PIN was originally created as a tool for computer architecture analysis, but its flexible API and an active community (called "Pinheads") have created a diverse set of tools for security, emulation and parallel program analysis.

A pin tool comprises of three types of routines:

  1. Instrumentation routines that enable the insertion of analysis routines
  2. Analysis routines which are called when the code they are associated is run
  3. Callback routines that called when specific conditions are met or when a certain event has occurred such as library loads, system calls, signals/exceptions and thread creation events

PIN includes in the directories source/tools/ManualExamples and source/tools/SimpleExamples several examples. Below can be seen the execution of the instruction counter and opcode mix profiler PIN tools:

$ cd pin-2.12-58423-gcc.4.4.7-linux
$ ./pin -appdebug -t source/tools/ManualExamples/obj-ia32/inscount0.so -- `which evolution`
$ cd pin-2.12-58423-gcc.4.4.7-linux
$ ./pin -t source/tools/SimpleExamples/obj-intel64/opcodemix.so -- /bin/ls

Another interesting example can be found on the imageload.cpp file. This example demonstrates the use of the API functions IMG_AddInstrumentFunction and IMG_AddUnloadFunction which are called when the binary images are loaded by the operating system:

$ cd source/tools/ManualExamples
$ make -f makefile obj-intel64/imageload.so
$ ../../../pin -t obj-intel64/imageload.so -- /bin/ls
$ cat imageload.out
	Loading /bin/ls, Image id = 1
	Loading /lib64/ld-linux-x86-64.so.2, Image id = 2
	Loading /lib/x86_64-linux-gnu/libselinux.so.1, Image id = 3
	Loading /lib/x86_64-linux-gnu/librt.so.1, Image id = 4
	Loading /lib/x86_64-linux-gnu/libacl.so.1, Image id = 5
	Loading /lib/x86_64-linux-gnu/libc.so.6, Image id = 6
	Loading /lib/x86_64-linux-gnu/libdl.so.2, Image id = 7
	Loading /lib/x86_64-linux-gnu/libpthread.so.0, Image id = 8
	Loading /lib/x86_64-linux-gnu/libattr.so.1, Image id = 9
	Unloading /bin/ls
	Unloading /lib64/ld-linux-x86-64.so.2
	Unloading /lib/x86_64-linux-gnu/libselinux.so.1
	Unloading /lib/x86_64-linux-gnu/librt.so.1
	Unloading /lib/x86_64-linux-gnu/libacl.so.1
	Unloading /lib/x86_64-linux-gnu/libc.so.6
	Unloading /lib/x86_64-linux-gnu/libdl.so.2
	Unloading /lib/x86_64-linux-gnu/libpthread.so.0
	Unloading /lib/x86_64-linux-gnu/libattr.so.1	

A classification of some of the shipped PIN tools examples are:

Analysing instructions

  • inscount0.cpp: checks number of executed instructions of application program
  • itrace.cpp: lists addresses of executed instructions of application program
  • pinatrace.cpp: lists addresses of accessed memory and type of operation (read, write)
  • opcodemix.cpp: lists opcodes of executed instructions with number of executions and category summary
  • regmix.cpp: analyses the usage or program registers

Analysing basic blocks

  • inscount1.cpp: counts all instructions of a basic block at once.
  • edgcnt.cpp:lists addresses of jump instructions, type of jump (direct, indirect), and number of times performed

Analysing routines

  • proccount.cpp: counts number of times each routine is invoked and number of instructions in it

Analysing libraries

  • imageload.cpp: lists loading and unloading of dynamic libraries invoked by program

Developing the first PIN tool

PIN includes in source/tools/MyPinTool/ a sample tool that can be used as code code base to start creating basic PIN tools. To create, compile and execute a this basic example, the following commands could be used:

$ cp -r pin-2.12-58423-gcc.4.4.7-linux/source/tools/MyPinTool/ pin1/
$ cd pin1
$ make -f makefile mPIN_ROOT=../pin-2.12-58423-gcc.4.4.7-linux
$ ls obj-intel64/
MyPinTool.o  MyPinTool.so
$ ../pin-2.12-58423-gcc.4.4.7-linux/pin -t obj-intel64/MyPinTool.so -- /bin/ls
===============================================
This application is instrumented by MyPinTool
===============================================
makefile  makefile.rules  MyPinTool.cpp  obj-intel64

To make things simple, a development directory “mytools” could be created outside the PIN directory hierarchy:

$ ls -l
total 35636
drwxr-xr-x 4 user users     4096 mar  9 22:39 mytools
lrwxrwxrwx 1 user users       30 ago 24  2013 pin -> pin-2.12-58423-gcc.4.4.7-linux
drwxr-xr-x 7 user users     4096 mar 10 01:12 pin-2.12-58423-gcc.4.4.7-linux

The development directory will contain the tools source code and the objects:

 
$ ls -l mytools
total 120
-rw-r--r-- 1 user users  676 feb  3 2013 Makefile
-rwxr-xr-x 1 user users  366 feb  3 2013 build.sh
-rw-r--r-- 1 user users 6033 feb  9 05:08 check_pc_sections.cpp
-rw-r--r-- 1 user users 7062 feb  9 03:27 check_secciones.cpp
-rw-r--r-- 1 user users 7796 feb  9 04:44 detect_pc_noexec.cpp
-rw-r--r-- 1 user users 5278 feb  9 02:30 load_unload_imag.cpp
-rw-r--r-- 1 user users 5435 feb  9 02:44 load_unload_sec.cpp
-rw-r--r-- 1 user users 2822 feb  4  2013 makefile.rules
drwxr-xr-x 2 user users 4096 feb  3 18:46 obj-intel64

A script (build.sh) could be created in order to help the compilation of PIN tools that reside in the development directory. The code of the script could be as shown below:

#!/bin/sh
PIN_ROOT=../pin
dstdir=obj-intel64
function negrita() { echo -e &quot;\033[1m${1}\033[0m&quot;; }

test -d $dstdir || mkdir $dstdir

for f in *.cpp; do
    negrita &quot;[*] Building $f&quot;;
    obj=`echo $f | sed -e 's/cpp/so/'`
    make $dstdir/$obj PIN_ROOT=$PIN_ROOT
    negrita &quot;[*] Exec $PIN_ROOT/pin -t $dstdir/$obj -- <program>&quot;
done

This script can be used to compile or all tools contained in the “mytools” development directory at one. Also, some tricks could help when using this dynamic instrumentation framework:

  • The option -appdebug tells PIN to start a GDB server to debug the application
  • The -appdebug option can also be used to debug from IDA Pro any application using PIN using the remote GDB debugger
  • It can’t be specified which port PIN will listen in as it will be randomly selected every time we execute PIN
    • The post An introduction to binary dynamic analysis appeared first on Portcullis Labs.

      ]]> https://labs.portcullis.co.uk/blog/an-introduction-to-binary-dynamic-analysis/feed/ 0 Crash https://labs.portcullis.co.uk/tools/crash/ https://labs.portcullis.co.uk/tools/crash/#comments Tue, 17 Dec 2013 16:08:23 +0000 https://labs.portcullis.co.uk/?p=2672 The purpose of this tool is to catch crashes from OS X applications and print debugging information such as registers, disassembled code and a memory dump of the stack. The intended use is with the conjunction of an application fuzzer. Key features Catch OS X application’s crashes Display CPU registers Display disassembled code at the […]

      The post Crash appeared first on Portcullis Labs.

      ]]>
      The purpose of this tool is to catch crashes from OS X applications and print debugging information such as registers, disassembled code and a memory dump of the stack. The intended use is with the conjunction of an application fuzzer.

      Key features

      • Catch OS X application’s crashes
      • Display CPU registers
      • Display disassembled code at the instruction that produced the crash
      • Display a part of the stack
      • Works transparently wether the application is 32 or 64 bits

      Overview

      The crash tool is a similar tool than the crash.exe tool from FileFuzz but for OS X. Used with an application fuzzer, it monitors the target application for exceptions.

      It is written in C and it works on both x86 and x86_64 architectures. It uses the excellent BeaEngine to disassemble the code.

      Installation

      In order to install the tool, you’ll need to generate a developer certificate.

      It can be done following those simple steps:

      1. Open Keychain Access.app
      2. Open menu Keychain Access/Certificate Assistant/Create a Certificate…
      3. Choose a name (codesigning-cert in the example).
      4. Set Identity Type to Self Signed Root.
      5. Set Certificate Type to Code Signing.
      6. Select the Let me override defaults.
      7. Click several times on Continue until you get to the Specify a Location For The Certificate screen, then set Keychain to System.
      8. Finally, using the contextual menu for the certificate, select Get Info, open the Trust item, and set Code Signing to Always Trust.
      9. You must quit Keychain Access application in order to use the certificate.

      Then run the following commands:

      $ make
      gcc -Iinclude/ -Wall -pedantic -framework Security -sectcreate __TEXT __info_plist ./Info.plist BeaEngine.o crash.c -o crash
      $ sudo make install
      Password:
      cp crash /usr/local/bin
      chgrp procmod /usr/local/bin/crash
      chmod 2755 /usr/local/bin/crash
      codesign -s codesigning-cert /usr/local/bin/crash
      $
      

      Usage

      $ ./crash
      Usage: crash [options] target arguments
        -t seconds        timeout (default: 5).
      
      Using BeaEngine version 4.1-175.
      

      Examples

      # Define the amount of time the target program is allowed to live.
      $ sudo ./crash -t 2 /usr/local/bin/dummy64
      [+] PID: 31273. Executing: /usr/local/bin/dummy64
      PID: 31273 (0x7a29)
      [+] Timeout exceeded, exiting.
      $
      
      # Catching a crash from a 64 bits application.
      $ sudo ./crash -t 2 /usr/local/bin/dummy64 1 0
      [+] PID: 31282. Executing: /usr/local/bin/dummy64 1 0
      [+] Exception: unknown exception code 0xd.
      ----------------------------------------------------------------------------------------------
      [ RAX: 4141414141414141  RBX: 0000000000000000  RCX: 4242424242424242  RDX: ffffffffffffffff ]
      [ RSI: 0000000000000000  RDI: 000000000000003c  RBP: 00007fff52359ef0  RSP: 00007fff52359eb0 ]
      [ R08: 0000000000000000  R09: 0000000000000000  R10: 0000000000000001  R11: 00007fff76360250 ]
      [ R12: 0000000000000000  R13: 0000000000000000  R14: 0000000000000000  R15: 0000000000000000 ]
      [     CS: 002b      FS: 0000      GS: 0000      RIP: 000000010d8a6ed4    o d I t s Z a p C   ]
      
      000000010d8a6ed4: mov        qword [rax], rcx
      000000010d8a6ed7: mov         [rbp-0x18], 0x00000000
      000000010d8a6ede: mov        eax,  [rbp-0x18]
      000000010d8a6ee1: mov         [rbp-0x14], eax
      000000010d8a6ee4: mov        eax,  [rbp-0x14]
      000000010d8a6ee7: add        rsp, 0x40
      
      Stack:
      00007fff52359eb0: 00007fff52359f38  8.5R....
      00007fff52359eb0: 0000000000000000  ........
      00007fff52359eb0: 0000000000000000  ........
      00007fff52359eb0: 4141414141414141  AAAAAAAA
      00007fff52359eb0: 0000000000000001  ........
      00007fff52359eb0: 0000000000000000  ........
      00007fff52359eb0: 00007fff52359f10  ..5R....
      00007fff52359eb0: 000000036d4a705e  ^pJm....
      ----------------------------------------------------------------------------------------------
      
      # Catching a crash from a 32 bits application.
      $ sudo ./crash -t 2 /usr/local/bin/dummy32 1 0
      [+] PID: 31285. Executing: /usr/local/bin/dummy32 1 0
      [+] Exception: KERN_INVALID_ADDRESS.
      --------------------------------------------------------------
      [ EAX: 00000000  EBX: bff6df54  ECX: bff6de4c  EDX: 99ce68e6 ]
      [ ESI: 00000000  EDI: 00000000  EBP: bff6df08  ESP: bff6ded0 ]
      [ ES: 0023  CS: 001b  SS: 0023  DS: 0023  FS: 0000  GS: 000f ]
      [ EIP: 00093f23                            o d I t S Z a P C ]
      
      00093f23: mov         [0x41414141], 0x42424242
      00093f2d: mov         [ebp-0x10], 0x00000000
      00093f34: mov        eax,  [ebp-0x10]
      00093f37: mov         [ebp-0x0C], eax
      00093f3a: mov        eax,  [ebp-0x0C]
      00093f3d: add        esp, 0x38
      
      Stack:
      bff6ded0: 00000000  ....
      bff6ded0: 0000000a  ....
      bff6ded0: 8fe925ec  .%..
      bff6ded0: 00093e5b  [>..
      bff6ded0: 00000001  ....
      bff6ded0: bff6df50  P...
      bff6ded0: bff6df40  @...
      bff6ded0: bff6df38  8...
      --------------------------------------------------------------
      
      Crash-1.0 Tar
      crash-1.0.tar.bz2
      December 17, 2013
      253.3 KiB
      MD5 hash: 53f1eb77dc8d1eeee38bc5da6cca25be
      Details

      The post Crash appeared first on Portcullis Labs.

      ]]>
      https://labs.portcullis.co.uk/tools/crash/feed/ 0