[HACK] Re: [DeepZone black tool] NT/2k/XP portable shellcode generator updated! (Win32 viral stuff add-on!)
|Zan
izan at deepzone.org
Thu Sep 27 18:37:14 CEST 2001
> Bueno, lo primero decir q yo no sabia nada de programacion de shellcodes
> ni de asm en windows 9x/NT hasta 1 mes antes de realizar la shellcode, asi
> q en algunas cuestiones tecnicas no te podre rebatir, te ruego me perdones
> ;).
No hay ningun problema.
>> A ver, estoy seguro que cuando leas la informacion complementaria del
>> generador observaras que el codigo tiene un fin muy claro y el compromiso
>> seguido en su elaboracion no permite soporte para el kernel 9x.
>
> Vamos a ver, que quieres q te diga?.. Tu shellcode tendra ventajas y
> desventajas, igual que la mia, pero yo prefiero que funcione en cuantos
> mas sistemas operativos mejor, tu no?.
En el mail anterior te comente que el generador es para explotar tecnologia
NT
y fue desarrollado con esta premisa en mente. Esto permite utilizar y asumir
ciertos criterios que no podrian asumirse de realizar un diseño mas general.
Como ya te puntualice esto es solamente cuestion de compromiso. Este tipo de
preguntas tienen respuesta en las necesidades y criterios seguidos en la
elaboracion del generador:
- Bindea una consola (imagen binaria cmd.exe)
- Necesita GetProcAddress y LoadLibraryA en la IT.
Al bindear una consola cmd.exe es imprescindible que la imagen binaria
exista
en disco. Solo existe en NT/2k/XP y sucesivos.
Una programacion dinamica y profesional exige que las dos APIs anteriores
tengan que existir en la IT (todos los b0fs vistos hasta el momento tenian
estas
dos APIs linkadas).
Como puedes observar tu pregunta de que una shellcode corra en la mayoria de
OS no es aplicable dentro del marco de desarrollo que tiene el generador
solamente por los principios de diseño que tiene.
> Estoy de acuerdo, pero aqui volvemos a lo mismo, la shellcode se supone
> que esta hecha para realizar exploits con ella. Esos exploits se supone
> que en algunos casos se usaran como sistema de testeo y otras veces no.
> Resumiendo, solo se realizan exploits para testear/hackear empresas
> "serias"?.
En DeepZone si. Todo tiene su justo valor; personalmente no creo que un b0f
sea la forma mas adecuada de atacar un kernel 9x por su inestabilidad. Para
el creo que existen formas mas adecuadas, mas portables y con mayor
probabilidad de exito. Esto es opinable por supuesto, no entrare por lo
tanto
a refutar opiniones.
> Los exploits para windows9x son factibles, asi que xq no una
> shellcode para ese sistema operativo?.
Nadie ha dicho lo contrario. Completamente de acuerdo.
> Yo cuando me puse a hacer la shellcode inicialmente iba a hacer eso, pero
> un colega me comento que el tema de bindear 'shells' en windows 9x esta
> muy complicado, por eso elegi el metodo de bajar/ejecutar un programa de
> algun server web.
ok. Has elegido una tecnica y la has explotado.
>> La verdad es que no hemos buscado la compatibilidad para Win9x porque no
es
>> interesante desde la perspectiva de un *ataque real* por un potencial
>> intruso. Si lo que buscas es lanzar una consola (como es el caso) el no
>> soporte de Win9x no es ninguna limitacion. Me sorprenderia ver un
servidor
>> de la casa blanca sirviendo con Windows 95 y Personal Web Server ...
>
> No estoy de acuerdo con esa politica, segun tu solo se deberin realizar
> exploits para los sistemas operativos de la nasa o la casa blanca?. Te
> olvidas que Windows 98 y ME es el sistema operativo mas difundido del
> mundo.
A ver, exactamente donde he dicho que solamente se deberian realizar
exploits
para los OS de la NASA o la Casa Blanca ?
Mi intencion con el parrafo anterior era subrayar que la mayoria de ataques
reales
basados en b0fs se realizan contra servidores que estan conectados 24h al
dia con
lo cual Win9x no forma parte de la familia de operativos preparados para
soportar
una carga elevada. El sistema operativo de Microsoft mas difundido en el
mundo en
el campo de servidores es NT/2k segun las estadisticas de Netcraft. Su otro
gran rival
lo constituye Linux (presencia realmente importante) y los derivados de
UNIX.
Los operativos corriendo el kernel 9x (95, 98, ME) son los mas difundidos en
el
campo de clientes NO en el de servidores.
Aunque los datos son claros al respecto yo entiendo que te pueda parecer
util
explotar Win9x. El hecho de que yo haya dicho que no me parece interesante
vuelve
a ser una mera cuestion de opinion.
>> Esto no es asi en absoluto. El shellcode utiliza GetProcAddress (GPA) y
>> LoadLibraryA (LLA) para reconstruir las direcciones correctas en el stack
>> pero las direcciones de estas no se consiguen con un valor hardcodeado en
>> absoluto. Esto significa que un exploit para el mismo binario funcionara
en
>> todas las versiones corriendo el kernel NT/2k/XP y futuras.
>
> Mm.. sino me equivoco lo que haces es referencias las direcciones GPA y
> LLA desde el propio Import Table (IT) del binario?.
Algo asi. Referencio las direcciones de las API con dos saltos indirectos en
la IT de
un binario vulnerable que conozco de antemano. Siempre conoces la imagen
vulnerable de antemano puesto que estas realizando el exploit para un bug
concreto.
Lo anterior hace que obtener el resto de APIs necesarias no sea funcion del
sistema
operativo sino de la imagen binaria vulnerable.
> Si es asi, que pasa si no estan pq no fueron importadas?. Segun mis
conocimientos la unica
> segura que esta es GetModuleHandleA
No existe ninguna API que este presente en la IT al 100%, ni siquiera
GetModuleHandleA.
El generador trata de explotar el hecho de que los programas comerciales son
realizados con
ciertas metodologias y compiladores que actuan de forma conocida. La
programacion dinamica
de un servidor es mas que frecuente. Si estas realizando un proyecto mas o
menos importantes
utilizaras componentes de Msoft y reutilizacion de codigo como hace IIS,
Statistics Server ... lo que
implica que se linken las dos APIs necesarias al igual que GetModuleHandleA
con probabilidades
muy altas.
Las posibilidades de encontrar las dos APIs necesarias de funcionamiento asi
como GetModuleHandleA
son mas elevadas que encontrar cualquier otro tipo de API pero pueden no
estar alli. En el momento
que un desarrollador de exploits conoce si existen o no existen tendra que
evaluar que tecnica implementar
o la forma mas adecuada de abordar el problema.
> Repito, que pasa si las direcciones no estan en el binario?. Tendrias que
> sacar de alguna manera la direccion de KERNEL32 en memoria y recorrer su
> Export Table (ET) para encontrar las direcciones correctas (lo que hago
> yo).
Yo prefiero basar la explotacion en el binario conocido y no en la version
de operativo desconocido
que pueda estar corriendo el servidor a atacar. Esto significa que cuando
lanzo un ataque la imagen
del servidor a abusar siempre es la misma (sino es la mima entonces esta
claro que se trata de una
version actualizada o parcheada). Esto es uno de los motivos por los cuales
cree el generador. Prefiero
generar una shellcode que se adapte a mi problema y en la cual pueda ajustar
cualquier tipo de variable
(puerto, encriptacion ...) de manera inmediata a tener una shellcode general
y tener que aceptar esa clase
de compromiso (recorrer la ET, mirar APIs exportadas ...).
Como te he dicho anteriormente es una cuestion de eleccion personal.
>> Estamos hablando de un hack completo. No se trata de hacer un ejercicio
de
>> programacion ni de optimizar. Se ha elegido una tecnica con sus ventajas
y
>> sus desventajas. Imaginate el siguiente escenario.
>
> Perdona pero no estoy de acuerdo, yo creo que si un codigo ha de
> optimizarse para reducir su tamaño ese es una shellcode. Muchas veces a la
> hora de explotar un programa vulnerable se anda muy escaso de memoria, asi
> que cuanto menos espacio ocupe la shellcode mejor.
Si me hubieses dicho esto hablando de Unix o derivados mi respuesta
inmediata hubiese sido un 'SI'
rotundo.
En NT esto no es asi. Sino tienes espacio los exploits mas recientes han
demostrado que sobreescribir
pasada la direccion de retorno no es un problema.
Por otro lado estamos hablando de una diferencia de 700 a 1200 bytes. Me
inclino a pensar que si
es explotable con 700 bytes no habra ningun problema para hacerlo con 1200.
Si esto no fuera posible
un ataque multi-disparo (tienes algun ejemplo en BugTraq de algun exploit
hecho por mi hara un año)
puede ser apropiada.
> Ya, pero con mi metodo te puedes hasta hacer (siempre que se pueda grabar
> en disco y ejecutar) un programa para dar shell por icmp's. Lo bueno es
> que puedes programar lo que quieras porque luego se va a ejecutar. Tienes
> posibilidades ilimitadas para hacer lo que quieras, mientras que bindeando
> una shell solo podras eso, dar una shell.
Tu lo has dicho, SIEMPRE que se pueda grabar en disco y ejecutar. Si te das
cuenta (y vuelvo a las
pautas de diseño) mi eleccion de bindear un shell no fue caprichosa o
arbitraria. Bindear un shell
te permite *leer* (no escribir) una imagen de disco, mantener *una unica
conexion entrante* durante
todo el hack y lo mas importante mantenerte *IN-PROCESS* el hack. No cambias
de proceso e interactuas
escasamente (principio de minima perturbacion) con el sistema operativo.
>> Como ves es una cuestion de compromiso. Eliges una tecnica y la explotas.
>
> Sip, pero yo creo que mi tecnica es mejor jeje.
Eso sin duda. Te has aferrado a tu tecnica desde un principio lo que me
parece perfecto. Nosotros
en cambio preferimos proporcionar una herramienta para desarrollar exploits
precisos y portables y que
sea el pen-tester quien decida que es lo que mas le interesa. Es nuestra
opinion por supuesto.
> Mm.. no comparto esa opinion. Explotar un overflow en windows 9x es
> perfectamente posible. Yo te invito a que leas NetSearch Ezine #7
Explotar b0fs localmente en 9x es posible, lo que es menos frecuente es
encontrar b0fs remotos *puros*
en 9x. Por ejemplo, el b0f del winamp, outlook ... no son b0fs remotos
aunque tienen el vector de ataque
en el exterior pero el b0f se produce localmente.
Servicios lanzados en 9x son deslinkados frecuentemente cuando el exploit
quiere retomar el control y
es a esta clase de b0fs a los que me referia como b0fs remotos.
>> Nota que he dicho "complicada" y no "imposible"; pero esos pocos casos
que
>> servirian de contraejemplo habria que encontrarlos en el software real
>> comercial. Practicamente imposible.
>
> Perdona pero te equivocas otra vez. Es mas, las posibilidades de encontrar
> overflows en programas (servidores, etc.) diseñados exclusivamente para
> windows9x, es mas alta que los que estan diseñados para Windows NT. O al
> menos eso pienso.
Dices que me equivoco "otra vez" X) Esta claro que este punto es totalmente
opinable. No creo que
saquemos nada en limpio dandole vueltas. Yo creo que ya te he comentado en
lineas anteriores todo
lo que te tenia que decir sobre este tema.
> De todas formas para exploits locales tengo otra shellcode, que ejecuta
system("cmd.exe"). Ocupa unos
> 450 bytes (sin optimizar) y usa la misma tecnica, recorrer la IT del
binario y luego la ET de KERNEL32.
> Funciona en Windows 9x y Windows NT, pero claro, en el primero tiene poco
sentido.
Tu lo has dicho :)
> Ahap. Sip, se que no es nada nuevo. Es mas, me base en documentos de
> programacion de virus para hacer la shellcode. Lo que no habia visto en
> ningun sitio es aplicar esa tecnica a una shellcode. La tecnica SEH no la
> conozco :/
SEH son las siglas de "Structured Exception Handling". En virus las
utilizamos para romper virtualizaciones,
chequeos, cambios de flujo ... La idea es proteger un fragmento de codigo
que puede lanzar una excepcion
estableciendo en la pila el frame adecuado.
again:
__ try {
codigo delicado
__ except (....) {
modificar variables y volver a iterar (call again)
}
En el codigo anterior el "codigo delicado" puede lanzar una excepcion. El OS
lo detecta y se ejecuta el
codigo que hay en el "except". Nota que esto es una version muy simplificada
y libre de lo que realmente
ocurre (hay "unwinds", varias pilas ...)
En este camino el "codigo delicado" podria ser una potencialmente correcta
direccion del K32. De esta
manera no te haria falta que GetModuleHandleA existiera en la IT. Tu
solamente tendrias un array
sosteniendo todas las direcciones del K32 o un bucle recorriendo el rango de
posibles direcciones y
cuando una validara escanearias la ET y obtendrias el resto de APIs. Como
sabrias que ha validado ? pues
comprobando que empieza por 'MZ' que en determinado offset tienes un puntero
que apunta a la cabecera
opcional ... etc ... etc ...
Lo anterior suena estupendo pero los problemas aparecen cuando la pila es
inconsistente. Por que? ... bien
el manejador de excepciones es un servicio proporcionado por el propio
sistema operativo que NT "arregla
y entiende" para que un proceso de usuario pueda manejarlo. Cuando tu
declaras un manejador para un tipo de
excepciones este se implementa con una logica basada en la pila. Es decir,
la pila se ve modificada (ESP, EBP ...)
al estar tratando un desbordamiento no siempre puedes asegurar un stack
"solido" en el que iterar.
>> Asumir una direccion base es, sencillamente, hardcodear. Pierdes la
>> independencia y con ella todas sus ventajas. Es igual que tu exploit
dependa
>> de 1 byte como de 600. O es portable o no lo es :).
>
> La direccion base es la misma para todos los programas con una posibilidad
> de error del 98% / 99%.
Supongo que aqui lo que habras querido decir es que tienes una posibilidad
de encontrar la direccion base
en 4....h del 98% / 99% con un error del 1% o 2 % ?
Aun asi y sin animo de ofenderte (sino no estaria debatiendo contigo) tienes
una facilidad alucinante de hacer
predicciones, juicios de valor y enunciados basados en la Fe que me han
llegado a sorprender X)
Me has dicho que me he "equivocado varias veces", que mi "codigo no era
portable", que "tu tecnica es mejor",
has basado la eficiencia de tu codigo en 9x cuando la implementacion de una
consola remota en NT es (casi) imposible,
has incluido la "presencia de defectillos" en el codigo cuando no es asi y
ahora enuncias una probabilidad con la
que tengo que estar de acuerdo (supongo ... cualquiera te dice algo ;).
Fuera de bromas, el 98% y 99% de probabilidades podra existir pero como te
he dicho pongo 5 servidores de
DeepZone delante con un b0f conocido y estoy seguro que no entras en
ninguno. Al igual que en cualquier
servidor mas o menos bien configurado. Pero ni con tu tecnica ni con la mia.
El exito de un b0f reside en conocer
la imagen de antemano y basarse en settings por defecto. Si la imagen mapea
en 4......h entonces en 4xxxxxxh y
4yyyyyyh habra siempre las direcciones indirectas a las APIs que necesito.
Como ves, no es un problema ni estoy
añadiendo aleatoriedad.
> Las posibilidades de elegir dos direccion de 32
> bits y acertar con las de GPA y LLA te aseguro que son bastante mas
> elevadas :)
Estas seguro ?
Imaginate que el siguiente programa es el que estas interesado en explotar.
Conoce la direccion de ExitProcess
en la IT y la utilizas de forma indirecta. Es decir, he hardcodeado la
direccion de ExitProcess a la IT. Ahora,
pruebalo en cualquier sistema operativo que quieras y veras como funciona
sin problemas. Portabilidad a nivel
de aplicacion y no de sistema operativo. Si estoy generando shellcodes es
porque prefiero una explotacion
quirurgica y portable. Puedes pensar en el generador como la solucion para
eliminar el scanneo que realizas
en la IT/ET para conseguir las direcciones base. Realmente estas generando
una shellcode para cada bug, es
cierto, pero la generas con un click de boton y en 1 segundo. Vamos, que si
te despistas tardas mas en copiar
y pegar una shellcode general.
.386
locals
jumps
.model flat,STDCALL
extrn ExitProcess:PROC ; fuerzo el linkado en la IT
.data
db 0
.code
DZ:
xor eax, eax
push eax ; salgo con eax = 0
mov eax, 403030h ; eax = puntero sosteniendo
direccion de ExitProcess
call dword ptr [eax] ; exit(0)
end DZ
>> Es decir, tienes dos versiones que ocupan mas de la mitad de esos 1200
bytes
>> que te parecian exagerados y tienes mas posibilidades de no acabar en
exito.
>
> Dicho de otro modo, mi shellcode ocupa la mitad de la tuya y sin tocar
> nada las probabilidades de que funcione son del 99% :). Aunque entrar en
> un debate de cual tiene mas probabilidades de funcionar me parece
> un poco infantil. Las dos examinando el binario funcionaran, pero
> sinceramente creo que la mia tiene mas ventajas (es una opinion).
Desde luego cada shellcode generada ocupa 500 bytes mas que la tuya y visto
desde ese punto es aceptable aunque como ya te comente esos 500 bytes mas
implican una shell remota, una unica conexion entrante, un hack IN-PROCESS
...
Cuestion de valorar necesidades.
> Como ya he dicho el 99% de las veces la direccion base siempre es la misma
> para todos los programas, y si en vez de 00400000h es 00300000h pues se
cambia
> un byte y punto. Pero comparar eso a tener que meter dos valores de 32
bits aleatorios
X)
A ver, la direccion es de 32 bits = 4 bytes con lo cual el cambio potencial
puede ser
de hasta 4 bytes. Pero esto es lo de menos.
Yo prefiero modificar solamente 8 bytes (inmediato con el generador) y
evitar ese monton
de bytes que utilizas para scannear por la IT/ET y todo, insisto, porque
conoces la imagen
a explotar.
> para cada binario.. Con mi metodo sin conocer el binario hay muchas
posibilidades de
> que funcione, mientras q con el tuyo las posibilidades son nulas.
Como que sin conocer el binario. Tienes que conocer de cuanto es el
desbordamiento, estudiar
un punto de vuelta al codigo y observar en el proceso dos punteros mas no es
que sea un
trabajo excesivamente cansino. Vamos, esto ultimo me ha sonado a broma ;)
More information about the hacking
mailing list