Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/spec/modules/payloads/singles/osx/aarch64/exec_spec.rb
Views: 11791
require 'rspec'12RSpec.describe 'singles/osx/aarch64/exec' do3include_context 'Msf::Simple::Framework#modules loading'45let(:subject) do6load_and_create_module(7module_type: 'payload',8reference_name: 'osx/aarch64/exec',9ancestor_reference_names: [10'singles/osx/aarch64/exec'11]12)13end14let(:cmd) { nil }15let(:datastore_values) { { 'CMD' => cmd } }1617before(:each) do18subject.datastore.merge!(datastore_values)19end2021describe '#create_aarch64_string_in_stack' do22context 'when the string is calc.exe' do23it 'generates the required stack' do24expected = <<~'EOF'25// Next 8 bytes of string: "CALC.EXE"26movz x1, #0x4143 // "AC"27movk x1, #0x434c, lsl #16 // "CL"28movk x1, #0x452e, lsl #32 // "E."29movk x1, #0x4558, lsl #48 // "EX"30str x1, [x9], #8 // Store x1 on x9-stack and increment by 83132mov x1, x9 // Store the current stack location in the target register33sub x1, x1, #8 // Update the target register to point to base of the string34EOF35expect(subject.create_aarch64_string_in_stack('CALC.EXE', registers: { destination: :x1, stack: :x9 })).to match_table expected36end37end3839context 'when the string is /bin/bash -c "echo abcdef1234"' do40it 'generates the required stack' do41expected = <<~'EOF'42// Next 8 bytes of string: "/bin/bas"43movz x1, #0x622f // "b/"44movk x1, #0x6e69, lsl #16 // "ni"45movk x1, #0x622f, lsl #32 // "b/"46movk x1, #0x7361, lsl #48 // "sa"47str x1, [x9], #8 // Store x1 on x9-stack and increment by 848// Next 8 bytes of string: "h -c \"ec"49movz x1, #0x2068 // " h"50movk x1, #0x632d, lsl #16 // "c-"51movk x1, #0x2220, lsl #32 // "\" "52movk x1, #0x6365, lsl #48 // "ce"53str x1, [x9], #8 // Store x1 on x9-stack and increment by 854// Next 8 bytes of string: "ho abcde"55movz x1, #0x6f68 // "oh"56movk x1, #0x6120, lsl #16 // "a "57movk x1, #0x6362, lsl #32 // "cb"58movk x1, #0x6564, lsl #48 // "ed"59str x1, [x9], #8 // Store x1 on x9-stack and increment by 860// Next 8 bytes of string: "f1234\""61movz x1, #0x3166 // "1f"62movk x1, #0x3332, lsl #16 // "32"63movk x1, #0x2234, lsl #32 // "\"4"64str x1, [x9], #8 // Store x1 on x9-stack and increment by 86566mov x1, x9 // Store the current stack location in the target register67sub x1, x1, #32 // Update the target register to point to base of the string68EOF69expect(subject.create_aarch64_string_in_stack('/bin/bash -c "echo abcdef1234"', registers: { destination: :x1, stack: :x9 })).to match_table expected70end71end72end7374describe '#generate' do75# Verify that the compile command is called with the expected asm string76def expect_result_to_match(expected_asm)77allow(subject).to receive(:compile_aarch64).and_wrap_original do |original, asm|78expect(asm).to match_table(expected_asm)79compiled_asm = original.call asm80expect(compiled_asm.length).to be > 081'mock-aarch64-compiled'82end83expect(subject.generate).to eq 'mock-aarch64-compiled'84end8586context 'when the CMD is /bin/bash' do87let(:cmd) { '/bin/bash' }8889it 'generates the execve system call payload without arguments present' do90expected = <<~'EOF'91// Set system call SYS_EXECVE 0x200003b in x1692mov x16, xzr93movk x16, #0x0200, lsl #1694movk x16, #0x003b9596mov x9, sp // Temporarily move SP into scratch register9798// Arg 0: execve - const char *path - Pointer to the program name to run99// Next 8 bytes of string: "/bin/bas"100movz x0, #0x622f // "b/"101movk x0, #0x6e69, lsl #16 // "ni"102movk x0, #0x622f, lsl #32 // "b/"103movk x0, #0x7361, lsl #48 // "sa"104str x0, [x9], #8 // Store x0 on x9-stack and increment by 8105// Next 8 bytes of string: "h\x00"106movz x0, #0x0068 // "\x00h"107str x0, [x9], #8 // Store x0 on x9-stack and increment by 8108109mov x0, x9 // Store the current stack location in the target register110sub x0, x0, #16 // Update the target register to point to base of the string111112113114// Push execve arguments, using x1 as a temporary register115116117// Arg 1: execve - char *const argv[] - program arguments118// argv[0] = create pointer to base of string value "/bin/bash\x00"119mov x1, x9120sub x1, x1, #16 // Update the target register to point to base of the string121str x1, [x9], #8 // Store the pointer in the stack122123124// argv[1] = NULL125str xzr, [x9], #8126127// Set execve arg1 to the base of the argv array of pointers128mov x1, x9129sub x1, x1, #16130131// Arg 2: execve - char *const envp[] - Environment variables, NULL for now132mov x2, xzr133// System call134svc #0135EOF136137expect_result_to_match(expected)138end139end140141context 'when the CMD is /bin/bash -c "echo abc"' do142let(:cmd) { '/bin/bash -c "echo abc"' }143144it 'generates the exece system call payload with arguments present' do145expected = <<~'EOF'146// Set system call SYS_EXECVE 0x200003b in x16147mov x16, xzr148movk x16, #0x0200, lsl #16149movk x16, #0x003b150151mov x9, sp // Temporarily move SP into scratch register152153// Arg 0: execve - const char *path - Pointer to the program name to run154// Next 8 bytes of string: "/bin/bas"155movz x0, #0x622f // "b/"156movk x0, #0x6e69, lsl #16 // "ni"157movk x0, #0x622f, lsl #32 // "b/"158movk x0, #0x7361, lsl #48 // "sa"159str x0, [x9], #8 // Store x0 on x9-stack and increment by 8160// Next 8 bytes of string: "h\x00"161movz x0, #0x0068 // "\x00h"162str x0, [x9], #8 // Store x0 on x9-stack and increment by 8163164mov x0, x9 // Store the current stack location in the target register165sub x0, x0, #16 // Update the target register to point to base of the string166167168169// Push execve arguments, using x1 as a temporary register170// Push argument 0171// Next 8 bytes of string: "-c\x00"172movz x1, #0x632d // "c-"173movk x1, #0x00, lsl #16 // "\x00"174str x1, [x9], #8 // Store x1 on x9-stack and increment by 8175176mov x1, x9 // Store the current stack location in the target register177sub x1, x1, #8 // Update the target register to point to base of the string178179180// Push argument 1181// Next 8 bytes of string: "echo abc"182movz x1, #0x6365 // "ce"183movk x1, #0x6f68, lsl #16 // "oh"184movk x1, #0x6120, lsl #32 // "a "185movk x1, #0x6362, lsl #48 // "cb"186str x1, [x9], #8 // Store x1 on x9-stack and increment by 8187// Next 8 bytes of string: "\x00"188movz x1, #0x00 // "\x00"189str x1, [x9], #8 // Store x1 on x9-stack and increment by 8190191mov x1, x9 // Store the current stack location in the target register192sub x1, x1, #16 // Update the target register to point to base of the string193194195196// Arg 1: execve - char *const argv[] - program arguments197// argv[0] = create pointer to base of string value "/bin/bash\x00"198mov x1, x9199sub x1, x1, #40 // Update the target register to point to base of the string200str x1, [x9], #8 // Store the pointer in the stack201202// argv[1] = create pointer to base of string value "-c\x00"203mov x1, x9204sub x1, x1, #32 // Update the target register to point to base of the string205str x1, [x9], #8 // Store the pointer in the stack206207// argv[2] = create pointer to base of string value "echo abc\x00"208mov x1, x9209sub x1, x1, #32 // Update the target register to point to base of the string210str x1, [x9], #8 // Store the pointer in the stack211212213// argv[3] = NULL214str xzr, [x9], #8215216// Set execve arg1 to the base of the argv array of pointers217mov x1, x9218sub x1, x1, #32219220// Arg 2: execve - char *const envp[] - Environment variables, NULL for now221mov x2, xzr222// System call223svc #0224EOF225expect_result_to_match(expected)226end227end228end229end230231232