PoC Tapnapping (autofocus + onblur)

Anuncio
PoC Tapnapping (autofocus + onblur)
(The X-C3LL)
¡Saludos!
A día de hoy es muy común la navegación usando varias pestañas al mismo tiempo, teniendo en
cada pestaña una web diferente. Además, también es común mantener abierta la sesión de alguna
red social mientras que por las otras pestañas se realiza una navegación normal. El tabnapping es
una técnica de phising que intenta engañar al navegante redireccionando una web que se está
visitando hacia otra donde se encuentra un scammer, realizándose tal redirección en el momento en
el que cambia de pestaña. De esta forma el usuario pueda pensar que ese scammer es en realidad la
otra pestaña que tenía abierta con la red social (por ejemplo, aunque puede aplicarse a cualquier
aplicacion web que requiera de login) y que, por algún error, se ha deslogueado.
La prueba de concepto más sencilla que se me ocurrió fue esta:
<script>
var pag ="http://www.google.com";
function redireccionar(){
location.href=pag;
}
</script>
<input type="text" onblur="redireccionar();" autofocus>
Para saber si el usuario ha cambiado de pestaña (y asi poder realizar la redirección) utilizamos el
evento onblur que se ejecuta cuando se pierde el foco. Cuando cambiamos de pestaña el foco
cambia y se lanza la función redireccionar() que es la encargada de la redirección a google. Por
otra parte para que el usuario no tenga que clickar dentro del input (para colocar en él el foco)
utilizamos autofocus (incluido en HTML5), de esta forma el foco se coloca directamente en el
input sin interacción voluntaria por parte del usuario.
¿Qué es datamining?
(HolyKnight)
Definición
El datamining (minería de datos), es el conjunto de técnicas y tecnologías que permiten explorar
grandes bases de datos, de manera automática o semiautomática, con el objetivo de encontrar
patrones repetitivos, tendencias o reglas que expliquen el comportamiento de los datos en un
determinado contexto.
Básicamente, el datamining surge para intentar ayudar a comprender el contenido de un repositorio
de datos. Con este fin, hace uso de prácticas estadísticas y, en algunos casos, de algoritmos de
búsqueda próximos a la Inteligencia Artificial y a las redes neuronales.
De forma general, los datos son la materia prima bruta. En el momento que el usuario les atribuye
algún significado especial pasan a convertirse en información. Cuando los especialistas elaboran o
encuentran un modelo, haciendo que la interpretación que surge entre la información y ese modelo
represente un valor agregado, entonces nos referimos al conocimiento.
A grandes rasgos la minería de datos busca encontrar datos implícitos en conjuntos (estructurados o
no-estructurados) de información, como puede ser una base de datos, que puedan servir para
comprender mejor el comportamiento de los flujos de información.
Proceso
Un proceso típico de minería de datos consta de los siguientes pasos generales:
• Selección del conjunto de datos, tanto en lo que se refiere a las variables objetivo (aquellas
que se quiere predecir, calcular o inferir), como a las variables independientes (las que
sirven para hacer el cálculo o proceso), como posiblemente al muestreo de los registros
disponibles.
• Análisis de las propiedades de los datos, en especial los histogramas, diagramas de
dispersión, presencia de valores atípicos y ausencia de datos (valores nulos).
• Transformación del conjunto de datos de entrada, se realizará de diversas formas en función
del análisis previo, con el objetivo de prepararlo para aplicar la técnica de minería de datos
que mejor se adapte a los datos y al problema, a este paso también se le conoce como
preprocesamiento de los datos.
• Seleccionar y aplicar la técnica de minería de datos, se construye el modelo predictivo, de
clasificación o segmentación.
• Extracción de conocimiento, mediante una técnica de minería de datos, se obtiene un
modelo de conocimiento, que representa patrones de comportamiento observados en los
valores de las variables del problema o relaciones de asociación entre dichas variables.
También pueden usarse varias técnicas a la vez para generar distintos modelos, aunque
generalmente cada técnica obliga a un preprocesado diferente de los datos.
• Interpretación y evaluación de datos, una vez obtenido el modelo, se debe proceder a su
validación comprobando que las conclusiones que arroja son válidas y suficientemente
satisfactorias. En el caso de haber obtenido varios modelos mediante el uso de distintas
técnicas, se deben comparar los modelos en busca de aquel que se ajuste mejor al problema.
Si ninguno de los modelos alcanza los resultados esperados, debe alterarse alguno de los
pasos anteriores para generar nuevos modelos.
Técnicas
Hay muchas técnicas usadas en la minería de datos, a continuación les voy a enumerar las mas
importantes para que en caso de interesarle alguna puedan buscar mas información.
•
•
•
•
•
Redes Neuronales
Regresión lineal
Árboles de decisión
Modelos estadísticos
Agrupamiento o Clustering
A su vez se pueden clasificar según el objetivos de los datos en dos grandes grupos:
• Algoritmos supervisados, predicen un dato (o un conjunto de ellos) desconocido a priori, a
partir de otros conocidos.
• Algoritmos no-supervisados, se descubren patrones y tendencias en los datos.
Usos de la Minería de datos
El data Minning es utilizado en muchas ramas de empresas debido principalmente a que la
inversión realizada tiene un retorno muy rápido. Aún así, dependiendo del negocio en particular la
cantidad de modelos predictivos necesarios para cubrir todas las exigencias puede volverse enorme,
y además pueden crecer esa necesidad en el tiempo.
Ahora les voy a mostrar unas aplicaciones concretas de la minería de datos.
Hábitos de compra:
El ejemplo clásico de aplicación de la minería de datos tiene que ver con la detección
de hábitos de compra en supermercados. Un estudio muy citado detectó que los viernes había una
cantidad inusualmente elevada de
clientes que adquirían a la vez pañales y cerveza. Se detectó que se debía a que dicho día solían
acudir al supermercado padres
jóvenes cuya perspectiva para el fin de semana consistía en quedarse en casa cuidando de su hijo y
viendo la televisión con una
cerveza en la mano. El supermercado pudo incrementar sus ventas de cerveza colocándolas próximas a
los pañales para fomentar
las ventas compulsivas.
Patrones de fuga
Un ejemplo más habitual es el de la detección de patrones de fuga. En muchas industrias —como la
banca,
las telecomunicaciones, etc.— existe un comprensible interés en detectar cuanto antes aquellos
clientes que puedan estar pensando
en rescindir sus contratos para, posiblemente, pasarse a la competencia. A estos clientes —y en
función de su valor— se les podrían
hacer ofertas personalizadas, ofrecer promociones especiales, etc., con el objetivo último de
retenerlos. La minería de datos ayuda a
determinar qué clientes son los más proclives a darse de baja estudiando sus patrones de
comportamiento y comparándolos con
muestras de clientes que, efectivamente, se dieron de baja en el pasado.
Fraudes
Un caso análogo es el de la detección de transacciones de lavado de dinero o de fraude en el uso de
tarjetas de
crédito o de servicios de telefonía móvil e, incluso, en la relación de los contribuyentes con el
fisco. Generalmente, estas operaciones
fraudulentas o ilegales suelen seguir patrones característicos que permiten, con cierto grado de
probabilidad, distinguirlas de las
legítimas y desarrollar así mecanismos para tomar medidas rápidas frente a ellas.
Terrorismo
La minería de datos ha sido citada como el método por el cual la unidad Able Danger del Ejército de
los EE. UU.
había identificado al líder de los atentados del 11 de septiembre de 2001, Mohammed Atta, y a otros
tres secuestradores del "11-S"
como posibles miembros de una célula de Al Qaeda que operan en los EE. UU. más de un año antes del
ataque. Se ha sugerido que
tanto la Agencia Central de Inteligencia y sus homóloga canadiense, Servicio de Inteligencia y
Seguridad Canadiense, también han
empleado este método.
Bueno esto ha sido todo, espero que les haya gustado y se hayan dado al menos una idea de lo que
consiste esta disciplina. Toda esta información es la suma de material de diversas fuentes con
producción personal. Los que quieran leer más sobre Data Minning, les recomiendo este artículo:
"Data Mining: Torturando a los datos hasta que confiesen"
Problemas servidor vulnerable
(Cibergolen, respuesta de PeterPunk77)
Estube practicando algo de Buffer Overflow con 11Sep, y decidimos crear un servidor vulnerable a
éste.
El problema está en que, "misteriosamente", el buffer de 80 bytes, no llega a desbordarse...
No logramos encontrar solución, ya que parece estar todo en orden
Les dejo el código del servidor "vulnerable":
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <winsock.h>
#define PUERTO 6000
#define IP "127.0.0.1"
int main(int argc, char *argv[])
{
WORD winsock;
WSADATA datos;
SOCKET escucha;
SOCKET comunicacion;
struct sockaddr_in servidor;
int tam_sockaddr=sizeof(struct sockaddr);
char Mensaje[512];
char TomaVuln[80];
winsock=MAKEWORD(1,1);
if(WSAStartup(winsock, &datos))
printf("Error: Problemas al inicializar winsock \n");
else
{
escucha=socket(AF_INET, SOCK_STREAM, 0);
if(escucha==-1)
printf("Error: Problemas al crear el socket \n");
else
{
servidor.sin_family=AF_INET;
servidor.sin_port=htons(PUERTO);
servidor.sin_addr.s_addr=inet_addr(IP);
if((bind(escucha, (struct sockaddr *)&servidor, sizeof(servidor)))==-1)
printf("Error: Problemas al asociar puerto e ip al socket \n");
else
{
listen(escucha, 1);
printf("Esperando conexiones entrantes... \n");
comunicacion=accept(escucha, (struct sockaddr *)&servidor, &tam_sockaddr);
close(escucha);
printf("Esperando datos... \n");
recv (comunicacion, (unsigned char*)&Mensaje, 512, 0);
strcpy(TomaVuln,Mensaje);
//Aquí la supuesta vulnerabilidad, pasamos un buffer de 512 a uno de 80
printf("Datos obtenidos: %s\nTamaño: %i\n", TomaVuln,strlen(TomaVuln));
closesocket(comunicacion);
}
}
WSACleanup();
}
system("PAUSE");
return (EXIT_SUCCESS);
}
¿Alguna idea, sugerencia, o amenaza de muerte?
Un saludo, y gracias!
Respuesta de PeterPunk77:
Cibergolen, si es lo que creo AMENAZA DE MUERTE XD.
¿De qué nos sirve la ingeniería inversa sino la usamos?
Acabo de compilar el programita igual que lo tienes tú, y cuando en el OllyDbg me llega a la línea
del strcpy(TomaVuln,Mensaje);
00401540
00401546
0040154A
00401550
00401553
|.
|.
|.
|.
|.
8D85 48FCFFFF
894424 04
8D85 F8FBFFFF
890424
E8 48090000
LEA EAX,[EBP-3B8]
MOV [ESP+4],EAX
LEA EAX,[EBP-408]
MOV [ESP],EAX
CALL <JMP.&msvcrt.strcpy>
;
;
;
;
;
||||
||||
||||
||||
|||\strcpy
¿qué me encuentro? Vemos la pila y ¡oh, sorpresa!
0022FB30
0022FB34
0022FB40
0022FB90
|dest = 0022FB40
\src = "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq>
Creo que el problema es evidente. Va a copiar de una zona de memoria a una justamente anterior
por lo que nunca va a poder reventar la pila, sino que se va a sobreescribir la segunda zona.
destino
origen
|-----------||-------------------------------------|
destino
basura
|-------------------------------------||-----------|
|origen desde marca
Probablemente con esta imagen os líe más pero no me importa porque soy un malvado.
La primera línea imita la zonas de memoria de origen y destino. Copiamos de origen a destino y
como origen es más grande sobrepasará los límites de destino. En esto se basa la vulnerabilidad que
funciona bien en el otro ejemplo. Pero como a continuación está la zona origen y como (memoria +
origen) nunca va a ser mayor que origen no se va a desbordar la pila.
Lo de basura depende de cómo este programado lo de copiar. Con un strcopy supongo que copiará
desde el punto de memoria origen al punto de memoria destino mientras char <> 0, por lo que
pondrá un 0 al acabar de copiar y entonces la cadena origen ahora será más corta.
Pero ¿por qué funciona bien el otro caso?. Evidentemente porque "Destino" está después que
"Origen". Y ¿por qué? Porque están declarados en otro orden:
char buffer[80];
char Nombre[512];
vs
char Mensaje[512];char TomaVuln[80];
Y en otro orden de cosas, la vulnerabilidad en este programa no funcionará exactamente igual que
en la local (por cierto 512 contra 80 no va a reventar por poco, prueba 512 contra 40), ya que el
servidor sale así de la función:
004015A4
004015A7
004015A8
004015AB
|.
|.
|.
\.
8B4D FC
C9
8D61 FC
C3
MOV ECX,[EBP-4]
LEAVE
LEA ESP,[ECX-4]
RET
mientras que el local lo hace así:
004014AE
004014AF
|.
\.
C9
C3
LEAVE
RET
Así que en local al modificar la pila, cuando llegue el RET intentará volver a lo que hayamos
sobreescrito. Mientras que en el servidor al modificar la pila, cambiará la pila por lo que hayamos
sobreescrito (debido al LEA ESP,[ECX-4]). Para entendernos: en ambos casos sobreescribimos la
pila con muchos caracteres "q" (0x71) pues en el local llegaré a un RET 0x71717171 intentando el
programa ejecutar el código que haya en 0x71717171, pero en el servidor voy a obtener ECX =
0x71717171 y luego modifica la pila dándole el valor 0x7171716D, así que el Ret sería adonde
apunta este 0x7171716D.
Saludos.
Desafío “Crackme de ESET para la Ekoparty 2011”
(PeterPunk77)
Descarga => http://blogs.eset-la.com/laboratorio/2011/08/15/crackme-de-eset-para-ekoparty-2011/
Primero debería haber abierto el crackme con el PEiD o cualquier otro programa, pero confiando en
la experiencia lo abrí sin más con el OllyDbg. Bien, parecía programado en MASM32, así que
seguro que iba a estar todo bastante claro, además es el lenguaje que normalmente utilizo para mis
crackmes y keygens.
Veo que no tiene mensaje de "chico bueno" y en seguida aprecio que lo primero que hace tras pulsar
el botón OK es poner un controlador de errores. Supongo el error que busca pero por el momento
no le hago caso. Luego lee el nombre introducido (mínimo 4 letras, máximo 19) y entra en un
procedimiento 0x401000 que parece la inicialización de un MD5, así que paso de las dos siguientes
llamadas y compruebo lo que hizo. Pues tenía razón, veo en el dump el hash MD5 de mi nick
"PeterPunk" (empieza por 8D y acaba en 9D). A continuación suma los 16 bytes (más exactamente
conjuntos de 8 bits) que componen el hash, y multiplica el resultado por 3. Así que para
"PeterPunk" obtengo 0x163E.
Unas imágenes para aclarar esto:
Vemos como el PEiD coincide conmigo tanto en el lenguaje de programación como en el uso del
hash MD5.
Esta es la parte de código que acabo de comentar.
Y en ésta apreciamos como en 0x404344 se encuentra el MD5 de "PeterPunk".
Lo siguiente que hace el crackme es leer el serial (número entero con signo). Al número introducido
como serial se le suma el resultado del cálculo anterior y se le resta 0x42B8. Luego divide 1 entre el
resultado anterior y muestra el mensaje de "Chico malo".
Obviamente y aunque el cracker en cuestión no entienda de excepciones va a suponer que lo único a
lo que aspira es a que esa división sea entre 0, y a ver que pasa. Así que probamos
17080 (0x42B8) - 5694 (0x163E) = 11386 (qué número más bonito, acaba en 386). Probamos con
la dupla "PeterPunk", "11386" y por arte de magia obtengo un mensaje de "chico bueno".
Otra tanda de imágenes:
Aquí vemos la parte de código que acabo de comentar y apreciamos que no hay comparación
posible del serial introducido. Y aparentemente obligatoriedad de mostrar el mensaje de "Chico
malo". Por lo que sólo parece posible forzar una división por 0.
Esta es mi dupla típica. "PeterPunk" y "81818181" que irremediablemente siempre me devuelve el
mensaje de error.
Si meto el valor que fuerza una división por 0 me muestra un mensajito de que soy bueno.
Por tanto vemos que cualquier persona que comience con el maravilloso mundo de la ingeniería
inversa va a poder resolver el crackme, pero igual no se dan cuenta de lo verdaderamente
interesante del mismo, el procedimiento programado para el control de excepciones.
Como he comentado con anterioridad en el primer vistazo del crackme reparé en que existía un
procedimiento para controlar las posibles excepciones. Está definido en:
00402353
00402358
00402359
00402360
|.
|.
|.
|.
BE 62224000
56
64:FF35 00000000
64:8925 00000000
MOV ESI,00402262
PUSH ESI
PUSH DWORD PTR FS:[0]
MOV FS:[0],ESP
y vemos que, por tanto, ese manejador está en 0x402262.
Lo voy a ir despiezando para comentar que es lo que hace cada cosa:
00402265
|.
8B5C24 08
MOV EBX,[ESP+8]
Con lo que logramos que EBX señale a la estructura EXCEPTION_RECORD
(http://msdn.microsoft.com/en-us/library/aa363082(v=VS.85).aspx).
A continuación:
00402269
0040226F
00402271
|.
|.
|.
813B 940000C0
75 43
E8 D6FFFFFF
CMP DWORD PTR [EBX],C0000094
JNZ SHORT 004022B4
CALL 0040224C
Si el código de la excepción es 0xC0000094 (EXCEPTION_INT_DIVID E_BY_ZERO) llamamos
al procedimiento 0x40224C que simplemente cambia el mensaje de "Bad boy!" por "Good boy" por
medio de unos xor.
00402276
00402279
|.
|.
8B7B 0C
83C7 16
MOV EDI,[EBX+C]
ADD EDI,16
Aquí, lo que hacemos es que EDI apunte a la instrucción 0x40241B (por si no os coinciden las
derecciones, va a ser siempre la siguiente a la llamada del MessageBox de "chico bueno", y ¿por
qué?, porque [EBX+C] (EXCEPTION_RECORD + 0Ch) apunta a la dirección que produjo el error
(la de DIV EBX) que en mi caso se trata de 0x402405, así que al sumarle 0x16 bytes vamos a
apuntar siempre a la instrucción siguiente al MessageBox.
0040227C
|.
8B4424 10
MOV EAX,[ESP+10]
Con esto logramos que EAX apunte a la estructura CONTEXT que contiene muchísima
información (http://msdn.microsoft.com/en-us/library/ms679284(v=VS.85).aspx).
00402280
00402286
|.
|.
C700 10000100
8108 07000100
MOV DWORD PTR [EAX],10010
OR DWORD PTR [EAX],10007
Esto nos cambia las banderas de la estructura (ContextFlags) que controlan la información que
guarda la estructura. Particularmente creo que no hace falta ya que por defecto nos va a aparecer
con un valor de 0x1003F (información de todo) pero el crackme lo cambia a 0x10017
(CONTEXT_CONTROL or CONTEXT_INTEGER or CONTEXT_EGMENTS or
DEBUG_REGISTERS).
0040228C
0040228F
|.
|.
8978 04
C740 18 01010000
MOV [EAX+4],EDI
MOV DWORD PTR [EAX+18],101
Aquí empieza lo bueno. Recordamos que EDI apuntaba a la instrucción siguiente al MessageBox.
Bien, pues ahora lo guardamos en [EAX+4] (CONTEXT + 4h) que es el Debug Register #0, y en
[EAX+18] (CONTEXT + 18h) que es el Debug Register 7, más conocido como DR7 o Debug
Control, guardamos 0x101. Pues lo que acabamos de hacer es poner un BreakPoint eXecution en la
dirección a la que apunta EDI. Si bajáis los PDFs de los manuales de desarrolladores de software
para arquitecturas Intel 64 e IA-32 de la web de Intel, veréis que de el Debug Register #0 al #3
hacen referencia a las direcciones de los 4 breakpoints que se pueden usar y el Debug Control
Register (DR7) controla la activación o desactivación de los mismos así como de sus condiciones.
En este caso en este DR7 sólo hemos marcado el bit #0 (bp local activado en el primer breakpoint,
que es el DR0) y el #8 (activado bp local exacto, que según Intel no está soportado desde el P6 pero
recomiendan su uso por retrocompatibilidad o futura reimplementación).
00402296
00402299
|.
|.
83EF 12
89B8 B8000000
SUB EDI,12
MOV [EAX+B8],EDI
Vale, ahora hacemos que EDI apunte en mi caso a 0x402409 que para todos va a ser tercer
parámetro del MessageBox (el título) y lo guardamos en [EAX+B8] (CONTEXT + 0B8h) que es el
EIP, bueno exactamente el EIP en el momento que se produjo la excepción, así que si os fijáis, el
valor que tiene [EAX+B8] antes de volcarle la nueva es el DIV EBX que produjo la división por 0.
¿Y para qué se cambia este valor? para que cuando se salga de este controlador de errores y el
sistema operativo devuelva el control del programa a su rutina normal siga ejecutándose desde aquí.
¡Pero nos comemos el primer parámetro del MessageBox (uType) que controla los botones e iconos
del mismo!. Tranquilos, el programador sabía lo que hacía:
0040229F
004022A6
004022AC
|.
|.
|.
83A8 C4000000 04
8B90 C4000000
C702 40000000
SUB DWORD PTR [EAX+C4],4
MOV EDX,[EAX+C4]
MOV DWORD PTR [EDX],40
Le resta 4 a [EAX+C4] (CONTEXT + 0C4h) que es el valor del ESP en el momento de la
excepción. O sea, que modificamos el valor de la pila, como si hubiésemos hecho un "push dword"
más y en esa dirección de la pila guardamos el valor 0x40 (MB_ICONINFORMATION) ya que lo
que estamos es creando el parámetro que nos faltaba para el MessageBox y ahora el programa
cuando siga su curso, ya no va a ejecutar el "PUSH 10h" como 4º parámetro del mensaje, que le
otorgaría el MB_ICONERROR, sino que ha sido sustituido por un ficticio "PUSH 40h"
(decrementando el valor de ESP y copiando ahí directamente el parámetro que queríamos).
Todo esto está muy bien, pero ¿para qué hemos creado un punto de ruptura en la instrucción
siguiente al mensaje? Pues porque al llegar a esa instrucción, va a saltar la excepción
STATUS_SINGLE_STEP (0x80000004) que también está controlada en el código manejador de
excepciones:
004022B4
004022BA
004022BC
004022C1
004022C5
004022CB
004022D1
004022D8
004022DF
004022E3
|> \813B 04000080
|. 75 37
|. E8 8BFFFFFF
|. 8B4424 10
|. C700 07000100
|. 8108 10000100
|. C740 04 00000000
|. C740 18 00000000
|. 8348 18 00
|. 8148 18 00040000
CMP DWORD PTR [EBX],80000004
JNZ SHORT 004022F3
CALL 0040224C
MOV EAX,[ESP+10]
MOV DWORD PTR [EAX],10007
OR DWORD PTR [EAX],10010
MOV DWORD PTR [EAX+4],0
MOV DWORD PTR [EAX+18],0
OR DWORD PTR [EAX+18],0
OR DWORD PTR [EAX+18],400
O sea, como hemos puesto el breakpoint, cuando el código llega a esa instrucción (tras mostrar el
mensaje de "Chico bueno"), nos salta una excepción, y con nuestro controlador de excepciones
volvemos al procedimiento 0x402262.Ahí primero va a comprobar, como hemos visto antes, que el
error sea 0xC0000094 (EXCEPTION_INT_DIVID E_BY_ZERO) y como no lo es ya nos salta a la
parte de código que acabo de pegar.
Al igual que antes vemos que EAX va a apuntar a la estructura CONTEXT.
Después vuelve a llamar al procedimiento que cambia el mensaje (esta vez el de "Chico bueno" por
el de "Chico malo") para que no quede el bueno fijo ya que sino, aunque a continuación metiésemos
un serial malo nos mostraría el bueno (eso sí, con el icono de error en el mensaje).
También vuelve a cambiar las banderas (ContextFlags) aunque sigo convencido de que esto no hace
falta y esta vez borra el contenido de [EAX+4] (Debug Register #0) y cambia el valor de [EAX+18]
(Debug Control o DR7) por 0x400. O sea que elimina el BPX que antes había puesto. Realmente
para esto bastaría con poner a 0 el bit #0 del DR7, pero de todas formas lo normal para eliminar los
breakpoints es poner a 0 ese DR7. Aquí, el crackme activa el bit #10 (0x400 = 100 0000 0000) pero
lo cierto es qué no sé el motivo ya que en el manual de Intel, los bits #10, #11, #12, #14 y #15 de
este Debug Control Register no están descritos, lo cual me hace suponer que no tienen ninguna
utilidad si bien es cierto que en la figura 16.1 de dicho manual el bit #10 aparece con un 1 mientras
que los otros cuatro con 0.
Este es el código del manejador de excepciones que realmente es el corazón del crackme.
Y eso es todo amigos, para cualquier duda u observación dejen un comentario a continuación.
Gracias a todos por leer este "ladrillo" y sobre todo gracias al programador del crackme por tomarse
su tiempo en la construcción del manejador de excepciones.
Saludos.
Programación recursiva (JAVA):
(WaesWaes)
El estilo de programacion mas habitual que solemos ver y/o programar se llama iterativa, los
algoritmos son iterativos porque son algoritmos reiteraticos (while,for, do/while).
un ejemplo del metodo factorial iterativo seria
public int Factorial( int n ) {
int i, res=1;
for(i=1; i<=n; i++ ) {
res = res*i;
}
return(res);
}
hablamos de recursividad cuando una funcion es llamada desde el algoritmo que esta contiene, se
compone del axioma y de la formula recursiva.
el axioma es cuando el algoritmo resuelve el problema para el cual fue programado y no recure mas
a la recursividad, se cortan las llamadas.
y la formula recursiva e cuando el algoritmo no logra resolver el problema para el cual fue
programado por lo tanto llama a la funcion que lo contiene una y otra ves hasta llegar al axioma
los tipos de recursividad pueden ser simples (se llaman 1 sola ves en un mimso algoritmo), multiple
(se llama 2 o mas veses en un mismo algoritmo)
recursividad anidada (en algunos de los argumentos de la llamada recursiva hay una nueva llamada
a si misma) y recursividad indirecta (la funcion se llama por medio de otra funcion)
un ejemplo de recursivaidad simple puede ser la funcion factorial que lo que hace es si, el
argumento es 4 el algoritmo ejecuta 4*3*2*1
public int Factorial( int n ) {
if(n==0) {
return(1);
}
return(n*Factorial(n-1));
}
un ejemplo de recursividad multiple seria un algoritmo que calcule un numero de la serie fibonacci
public int Fibonacci( int n ) {
if(n<=1) {
return(1);
}
return(Fibonacci(n-1) + Fibonacci(n-2));
}
un ejemplo de recursividad anidada seria la funcion de Ackermann
Ackerman
int Ack( int n, int m ) {
if(n==0 ) {
return(m+1);
}
else if(m==0) {
return(Ack(n-1,1));
}
return(Ack(n-1, Ack(n,m-1)));
}
un ejemplo de recursividad indirecta seria el algoritmo minimax
minimax
private int max(){
if (finPartida()){
if (ganaPartida()!=-1) return -1;
else return 0;
}
int v=Integer.MIN_VALUE;
int aux;
for (int n=0;n<TAM;n++){
for (int m=0;m<TAM;m++){
if (nTablero[n][m]==-1){
nTablero[n][m]=1;
aux=min();
if (aux>v) v=aux;
nTablero[n][m]=-1;
}
}
}
return v;
}
private int min(){
if (finPartida()){
if (ganaPartida()!=-1) return 1;
else return 0;
}
int v=Integer.MAX_VALUE;
int aux;
for (int n=0;n<TAM;n++){
for (int m=0;m<TAM;m++){
if (nTablero[n][m]==-1){
nTablero[n][m]=0;
aux=max();
if (aux<v) v=aux;
nTablero[n][m]=-1;
}
}
}
return v;
}
espero que les sirva
saludos
Envío de correo [JavaMail]
(Arobavx)
Como esta pregunta se hace cada vez mas frecuente en el foro dejo un breve resumen de como
hacerlo
El ide que usare sera el eclipse.
Para poder enviar los correos usaremos una librería externa llamada JavaMail(TM) API 1.4.4
La descargan de Aqui
y add la libreria externa al proyecto
para hacerlo deben ir a propiedades del proyecto > java build path y hacer click en AddExternal
Jars..
buscar mail.jar dentro del directorio de JavaMail descargado.. agregarlo. dar ok y ya...
si quieren hacerlo desde linea de comando es
java -cp mail.jar:. NOmbreDeMiMailer.ja va
luego tenemos que saber son los datos de los servidores que usaremos para enviar los correos por
ejemplo:
Hotmail
■Servidor POP: pop3.live.com
■Puerto POP: 995.
■POP SSL: Si.
■Usuario: Tu Windows Live ID (nombre:-com).
■Contraseña: Tu palabra clave habitual.
■Servidor SMTP: smtp.live.com
■Puerto SMTP: 587.
Gmail
Cuenta de Correo: [email protected]
Usuario: [email protected] (hay que poner el @gmail.com)
Datos POP:
Servidor: pop.gmail.com
Usar SSL: SÍ
Puerto: 995
Datos SMTP:
Servidor: smtp.gmail.com
Usar Autentificación: SÍ
Usar SSL (STARTTLS): SÍ
Puerto: 465 ó 587
las clases que usaremos serán:
java.util.Propertie s; >> para asignar las propiedades de la coneccion a la secion que se abrira con el
servidor
javax.mail.Session; >> la secion que enviara el mensaje
javax.mail.Message; >> para la construccion del mensaje
javax.mail.Transpor t; >> sera el que se conectara con el servidor y mandara el mensaje.
javax.mail.internet .InternetAddress; >> para construir las "Direcciones" de correo
javax.mail.internet .MimeMessage; >> es todo el mensaje..
empezamos..
yo enviare un correo de un gmail a otro correo:
asigno las propiedades del servidor (para encontrar todas las propiedades Consultar su javadocs)
Properties props = new Properties();
props.setProperty("mail.smtp.host", "smtp.gmail.com");
props.setProperty("mail.smtp.starttls.enable", "true"); //
Usar SSL: SÍ
props.setProperty("mail.smtp.port", "587");
props.setProperty("mail.smtp.user", "[email protected]");
props.setProperty("mail.smtp.auth", "true");//
Usar Autentificación: SÍ
crear una session con las propiedas que asigne
Session session = Session.getDefaultInstance(props);
crear el Mensaje a ser enviado
MimeMessage message = new MimeMessage(session);
espesificar Direccion de correo de la se enviara el correo
message.setFrom(new InternetAddress("[email protected]"));
asignar para quien ira dirigido
message.addRecipient(
Message.RecipientType.TO,
new InternetAddress("[email protected]"));
Tema o Asunto del Mensaje
message.setSubject("Prueba");
y el texto del mensaje
message.setText("MiMensajexD…");
una vez armado el mensaje solo queda "Transportarlo al servidor para que sea
enviado"
Transport tr = session.getTransport("smtp");//protocolo que se usara
tr.connect("[email protected]", "miContrasenha"); //conectarse con los datos de la cuenta
tr.sendMessage(message, message.getAllRecipients()); //envió el mensaje y con
//message.getAllRecipients extrae los A, CC y BCC
t.close(); // cierra la conexión
y eso es todo por el riesgo a que tire una excepción es recomendable usar try
catch.. el código armado seria el siguiente
import
import
import
import
import
import
public
java.util.Properties;
javax.mail.Message;
javax.mail.Session;
javax.mail.Transport;
javax.mail.internet.InternetAddress;
javax.mail.internet.MimeMessage;
class Mailer {
public static void main(String[] args) {
try {
Properties props = new Properties();
props.setProperty("mail.smtp.host", "smtp.gmail.com");
props.setProperty("mail.smtp.starttls.enable", "true");
props.setProperty("mail.smtp.port", "587");
props.setProperty("mail.smtp.user", "[email protected]");
props.setProperty("mail.smtp.auth", "true");
System.out.println("Enviando…");
// Preparamos la sesion
Session session = Session.getDefaultInstance(props);
// Construimos el mensaje
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress("[email protected]"));
message.addRecipient(
Message.RecipientType.TO,
new InternetAddress("[email protected]"));
message.setSubject("Prueba");
message.setText("Esto es una prueba…");
// Lo enviamos.
Transport t = session.getTransport("smtp");
t.connect("[email protected]", "miContrasenha");
t.sendMessage(message, message.getAllRecipients());
// Cierre.
t.close();
System.out.println("\n\n\nEmail Enviado!");
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
y eso es todo.. A DARLE UN BUEN USO..
Saludos
Forzar la Finalización y la Recolección de Basura en
Java
(Shevchenko)
Forzar la Finalización y la Recolección de Basura
El sistema de ejecución de Java realiza las tareas de manejo de memoria por tí. Cuando un
programa ha terminado de utilizar un objeto-- esto es, cuando ya no hay más referencias a ese
objeto- el objeto es finalizado y luego se recoge la basura.
Estas tareas suceden asíncronamente en segundo plano. Sin embargo, se puede forzar la finalización
de un objeto y la recolección de basura utilizando los métodos apropiados de la clase System.
Finalizar Objetos
Antes de recolectar la basura de un objeto, el sistema de ejecución de Java le da la oportunidad de
limpiarse a sí mismo. Este paso es conocido como finalización y se consigue mediante una llamada
al método finalize() del objeto. El objeto debe sobreescribir este método para realizar cualquier
tarea de limpieza final como la liberación de recursos del sistema como ficheros o conexiones. Para
más informaciónsobre el método finalize() puedes ver: Escribir un método finalize() .
Se puede forzar que ocurra la finalización de un objeto llamando al método runFinalization() de la
clase System.
System.runFinalizat ion();
Este método llama a los métodos finalize() de todos los objetos que están esperando para ser
recolectados.
Ejecutar el Recolector de Basura
Se le puede pedir al recolector de basura que se ejecute en cualquier momento llamando al método
gc() de la clase System.
System.gc();
Se podría querer ejecutar el recolector de basura para asegurarnos que lo hace en el mejor momento
para el programa en lugar de hacerlo cuando le sea más conveniente al sistema de ejecución.
Por ejemplo, un programa podría desear ejecutar el recolector de basura antes de entrar en un
cálculo o una sección de utilización de memoria extensiva, o cuando sepa que va a estar ocupado
algun tiempo. El recolector de basura requiere unos 20 milisegundos para realizar su tarea, por eso
un programa sólo debe ejecutarlo cuando no tenga ningún impacto en su programa -- esto es, que el
programa anticipe que el recolector de basura va a tener tiempo suficiente para terminar su trabajo.
Autor: Juan Antonio Palos (Ozito)
http://www.programacion.net/java/tutorial/java_basico/56/
Algoritmo CountingSort
(Kicasta)
Algoritmo: de Ordenamiento
EDA: Arreglo
Lenguaje: C#
CountingSort.
Está demostrado que la cota mínima para ordenar n elementos es O(nLog(n)), sin embargo
asumiendo algunas hipótesis sobre los datos de entrada, por ejemplo enteros pequeños, caracteres,
etc, se puede realizar un ordenamiento sin comparación (que al fin y al cabo es lo que da el Log(n)).
El algoritmo construye un vector auxiliar, con valor inicial cero en todas sus posiciones. Este vector
cuenta las incidencias del número (nos centramos en enteros para la explicación) en el vector
original. Luego coloca los números en el original recorriendo el auxiliar.
static int[] countingSort(int[] arr)
{
int min = arr.Min();
int max = arr.Max();
int[] aux = new int[max - min + 1];
int pos = 0;
for (int i = 0; i < arr.Length; i++)
aux[arr[i] - min]++;
for (int i = min; i <= max; i++)
while (aux[i - min]-- > 0)
{
arr[pos] = i;
pos++;
}
return arr;
}
El algoritmo se basa en la hipótesis que los elementos están en el rango 1..k, por lo que queda
O(n+k), si k es O(n) entonces el algoritmo queda lineal.
Otro algoritmo que sale directamente es el RaddixSort. Y es que suponiendo que todos los números
tienen la misma cantidad de dígitos (o los string tienen la misma longitud), se le hace un
CountingSort a cada dígito y queda ordenado el arreglo.
Saludos
Descargar