Как передать аргументы argv в execv в asm на 64-битной (Linux) - PullRequest
4 голосов
/ 08 мая 2019

Я пытаюсь передать аргументы при вызове /bin/bash для 64-битного кода.Я не могу использовать раздел .data, и это немного сложно для меня.Я рассмотрел различные примеры кода, но ни один из них не очень понятен (новичок здесь).Я хотел бы вызвать /bin/bash -c id.

Мой код работает, когда я пытаюсь оставить второй аргумент пустым, но когда я добавляю его, я получаю следующую ошибку:

execve("/bin/bash", [0x7361622f6e69622f, 0x646920632d2068, 0x7361622f6e69622f, 0x68], NULL) = -1 EFAULT (Bad address)

Составлено с: nasm -f elf64 -o test.o test.asm;ld -o test test.o

section .text 
  global _start

_start:
  mov rax,59                     
  lea rdi,[rel bin]             
  lea rsi,[rel msg]
  syscall                       

align 8
  msg db '/bin/bash -c /bin/id',0
  bin db '/bin/bash',0

1 Ответ

3 голосов
/ 08 мая 2019

Второй аргумент для execve - это адрес массива строковых указателей (char ** или char *argv[]). Вы дали ему адрес одной строки (char *).

Также execve(2) принимает третий параметр, список среды. Как описывает man-страница, argv и / или envp могут иметь значение NULL, и Linux рассматривает это как эквивалент пустого списка (действительный указатель на NULL в памяти).

Вот что должно быть:

      mov rax, 59
      lea rdi, [rel bin]
      lea rsi, [rel args]
      xor edx, edx             ; Linux accepts NULL instead of a pointer to NULL
      syscall


; section   .rodata
      align 8
args  dq bin, arg1, arg2, 0

arg1  db '-c',0
arg2  db '/bin/id',0
bin   db '/bin/bash',0

Если вы пишете шелл-код, обратите внимание, что он содержит несколько байтов 0 как в инструкциях (неотрицательные rel32 режимы адресации и 32-битные непосредственные значения), так и в данных.

Если вы не пишете шелл-код (который будет извлечен в плоский двоичный файл с кодом и данными вместе), поместите ваши данные в отдельный раздел, предпочтительно .rodata для данных только для чтения.

...