¿Qué significa mov qword rbx, '// bin / sh'?

4

Sigo este tutorial para entender cómo funciona el código de shell de 64 bits.

Por lo tanto, codifico este código de shell y funciona:

BITS 64

xor rax, rax
mov qword rbx, '//bin/sh'
shr rbx, 0x8
push rbx
mov rdi, rsp
push rax
mov rdx, rsp
push rdi
mov rsi, rsp
mov al, 59
syscall

Entiendo todo este código, excepto dos instrucciones:

mov qword rbx, '//bin/sh'
shr rbx, 0x8

Entiendo que una qword es un dato de tamaño de 64 bits, pero cuando quito qword el shellcode no funciona. ¿Por qué necesito agregar qword?

Y después de que se enciendan las instrucciones, mis cadenas deben ser como '% 00 // bin / s' ¿no? ¿Por qué no usar shl en lugar de shr?

    
pregunta sushi 31.12.2016 - 17:11
fuente

1 respuesta

2
  

Entiendo que una qword es un dato de tamaño de 64 bits, pero cuando quito qword el shellcode no funciona. ¿Por qué necesito agregar qword?

Porque estás moviendo una constante qword. Cuando escribes '//bin/sh' estás expresando una matriz de 8 caracteres. Al hacer un prefijo con qword, le indica al ensamblador que trate el operando de la derecha como un entero de 64 bits en línea. De manera predeterminada, probablemente lo tratará como un puntero a esa cadena, o algún otro comportamiento.

  

Y después de que se enciendan las instrucciones, mis cadenas deben ser como '% 00 // bin / s' ¿no?

Los enteros

en los procesadores de arquitectura x86 se almacenan como little-endian . Si su compilador lo tomó literalmente, su cadena se codificaría en ASCII de la siguiente manera:

/  /  b  i  n  /  s  h
2f 2f 62 69 6e 2f 73 68 

Lo que también puede mostrar en la siguiente instrucción:

mov rbx, 0x2f2f62696e2f7368

Esto se codifica de la siguiente manera:

48 BB 68 73 2F 6E 69 62 2F 2F

Podemos dividir esto en 3 secciones:

48        BB                     68 73 2F 6E 69 62 2F 2F
|         |                      |---------------------|
 \         \                             literal
  64-bit     B8 = MOV instr
  prefix        + reg operand
                + r/m operand

En este caso, el byte de instrucciones mov ( BB ) también contiene un campo de 7 bits que describe el registro al que nos estamos moviendo ( rbx ) y el tipo de operando de la derecha (literal).

Pero tenga en cuenta: el literal es no en el mismo orden que la representación ASCII que vimos anteriormente. En cambio, se invierte debido a la poca endiancia.

El problema aquí, por supuesto, es que esto no puede ser lo que ocurra en tu shellcode. Si el nombre se invirtió en los bytes, la función a la que llama vería hs/nib// y fallaría. En su lugar, su ensamblador es lo suficientemente inteligente como para darse cuenta de que quiere esos caracteres ASCII en orden de bytes, lo que significa que realmente codifica la siguiente instrucción:

mov rbx, 0x68732f6e69622f2f

Esto produce la siguiente instrucción codificada:

48 BB 2F 2F 62 69 6E 2F 73 68

Como puede ver, el // aparece primero ( 2F 2F ) en la representación de orden de bytes.

  

¿Por qué no usar shl en lugar de shr?

Usted hace ambas cosas. A su código le falta una instrucción, que se puede ver en el tutorial. Después de shl rbx, 0x8 , inmediatamente sigue un shr rbx, 0x8 .

Su explicación le hace justicia:

  

Después de desplazar 0x08 a la izquierda (piense en cada marcador de posición numérico en la cadena como un 4, de modo que mover 8 bytes más en realidad nos mueve dos espacios) empuja el 11 a la derecha del final. Ahora tenemos esto:

     

0x68732f6e69622f00

     

Luego lo devolvemos como antes, usando shr por el mismo valor, y obtenemos esto:

     

0x0068732f6e69622f

     

Esto nos da con éxito nuestra cadena terminada por un nullbyte sin generar un solo nullbyte en el código de la máquina.

La primera barra es simplemente un carácter de sacrificio que se descarta durante el shl .

El motivo de este truco, en lugar de simplemente cargar el nulo en primer lugar o enmascarar el byte más a la derecha con cero, es que no requiere bytes nulos en la carga útil del exploit, lo cual es muy útil si la entrada se ignora después de un nulo ( por ejemplo, si una cadena se está copiando con strcpy).

    
respondido por el Polynomial 31.12.2016 - 18:20
fuente

Lea otras preguntas en las etiquetas