Espacio de tecnologia, software libre y sus derivados. Una horda de monos entrenados escriben de vez en cuando por aqui algunas noticias, opiniones e incluso alguna que otra cosa fuera del tema. Maqueros, favor de abstenerse que no somos lo suficientemente guapos.
March 28, 2010 a las 2:08 pm por Edwin Plauchu · Archivado en Linux
Durante una transaccion SSL sobre TCP/IP… la parte cliente inicia el intercambio de informacion (conocida como handshake tcp/ip), la parte servidor entonces… mandara el certificado que inclulle la llave publica a la parte cliente, entonces la parte cliente utilizara este certificado para mandar sus mensajes cifrados hacia el servidor….
Para atrapar este certificado y ejecutar el ataque de el middle man (y asi enterarnos de la informacion nos interesa colocandonos en medio de la transmision cliente servidor). Requerimos 3 cosas…
* Hacer un Destiny NAT sobre algun sistema linux o bsd * Un sniffer de red que soporte SSL * Hacer ARP spoofing al host que deseamos espiar , ya sea manualmente con algun unix script o bien utilizando alguna utileria que te consigas por ahi en la red
Este video lo tome de un amigo de la comunidad tucancunix ( Gracias a ROA )
November 18, 2009 a las 5:06 pm por Edwin Plauchu · Archivado en Ubuntu, FreeBSD, Linux
Yo fui un usuario de Slackware
Y solia compilarme todas las fuentes de lo que requeria… y estas siempre usaban el configure.
Aqui ya te puedes dar cuenta como fregados se puede generar una aplicacion con su configure.. para que la puedas distribuir..
Me pidieron un programita hecho en C residente en memoria. Un demonio pues!…
Aqui les dejo el codigo base del daemon unix tradicional.
El daemon lo hice para un IBM AIX 5.3 sobre arquitectura power pc.
Y poco despues lo compile en linux, y no hubo nada de problema.. codigo 2000% porciento guapo y portable.
/**********************************
* UNIX Daemon Server Programming *
* Written by Edwin Plauchu *
* mailto:pianodaemon@gmail.com *
**********************************/
#include stdio.h
#include stdlib.h
#include fcntl.h
#include signal.h
#include unistd.h
#include string.h
#define RUNNING_DIR "/tmp"
#define LOCK_FILE "cacherd.lock"
#define LOG_FILE "cacherd.log"
void log_message(filename,message)
char *filename;
char *message;
{
FILE *logfile;
logfile=fopen(filename,"a");
if(!logfile) return;
fprintf(logfile,"%sn",message);
fclose(logfile);
}
void signal_handler(sig)
int sig;
{
switch(sig) {
case SIGHUP:
log_message(LOG_FILE,"Senal de hangup cachada");
break;
case SIGTERM:
log_message(LOG_FILE,"Senal de Terminacion cachada");
exit(0);
break;
}
}
void daemonize(){
int i,lfp;
char str[10];
// Primero obtenemos el indentificador de Proceso
if( getppid() == 1 ) return;
// Ahora generamos un proceso hijo y obtenemos su PID
// mediante la variable i
i=fork();
// Comprobamos que el proceso hijo este lanzado de manera correcta
// Verificando los posibles ERRORES de lanzamiento
// En caso de existir un error de lanzamiento en el proceso hijo
// procedemos a la finalizacion del proceso padre
if (i<0) { exit(1); } // fork error, el proceso hijo no pudo ser creado
if (i>0) { exit(0); } /* Padre existe */
// Proceso hijo (Demonio) continua
setsid(); // Crea una sesión y define el ID de grupo del proceso
/* Cerrar todos los descriptores de archivo
OJO: Esto evita que el hijo use los mismos decriptores de fichero que el padre*/
for (i=getdtablesize();i>=0;–i) close(i);
i=open(”/dev/null”,O_RDWR); dup(i); dup(i); /* handle standart I/O */
umask(027); /* Establece los permisos que le seran dados a los nuevos archivos a crear */
chdir(RUNNING_DIR); /* Cambia el directorio de ejecucion */
/* Abre el archivo de bloqueo en modo lectura/escritura, pero
si el archivo no existiece, lo crea con el permiso 640 */
lfp=open(LOCK_FILE,O_RDWR|O_CREAT,0640);
if (lfp<0) { exit(1); } /* No puede ser abierto */
if (lockf(lfp,F_TLOCK,0)<0) exit(0); /* No puede ser bloqueado el fichero para este proceso*/
/* Primera instancia continua */
sprintf(str,"%dn",getpid());
// Escribimos el PID al fichero de bloqueo
write(lfp,str,strlen(str));
signal(SIGCHLD,SIG_IGN); /* Ignora hijo */
signal(SIGTSTP,SIG_IGN); /* Ignora Senales tty */
signal(SIGTTOU,SIG_IGN);
signal(SIGTTIN,SIG_IGN);
signal(SIGHUP,signal_handler); /* Cacha Senal hangup (kill -1 PID)*/
signal(SIGTERM,signal_handler); /* Cacha Senal de Terminacion (kill -15 PID)*/
}
int main(){ daemonize(); while(1) sleep(1); }
July 8, 2009 a las 9:27 am por Edwin Plauchu · Archivado en Microsoft, FreeBSD, Linux
Navegando hace unos instantes, encontré este “humor gráfico” en el cual podemos apreciar los distintos puntos de vista de los diferentes sistemas operativos, unos contra otros, como por ejemplo; como ve un “maquero” a un “linuxero” y viceversa. Espero que les guste.
#include "stdio.h"
#include "stdlib.h"
#include "errno.h"
#include "unistd.h"
int main(){
//Aqui se define STDIN como el elemento 0 del arreglo pfds
//Aqui se define STDOUT como el elemento 1 del arreglo pfds
//Aqui se define STDERR como el elemento 2 del arreglo pfds
int pfds[2];
// Establecemos un buffer de 30 bytes
char buf[30];
//Creamos la tuberia
if (pipe(pfds) == -1) {
perror("pipe");
exit(1);
}
printf("Escribiendo sobre el file descriptor de STDOUT");
write(pfds[1], "Edwin", 5);
printf("Lellendo sobre el file descriptor de STDIN");
read(pfds[0], buf, 5);
printf("Valor transportado en nuestra tuberia: \"%s\"n", buf);
}
Basicamente, una llamada a pipe() retorno un par de file descriptors.
Cada no es representado por pg_data_t, el cual es un tipo definido para la estructura pglist_data. Cuando se asigna una pagina, Linux usa una politica de asignar memoria del nodo mas cercano a la CPU. A razon de que el proceso corre sobre la misma CPU,
es mas razonable que la memoria del actual nodo(o banco de memoria) sea la que se use. La estructura es declara como sigue en
:
typedef struct pglist_data {
zone_t node_zones[MAX_NR_ZONES];
zonelist_t node_zonelists[GFP_ZONEMASK+1];
int nr_zones;
struct page *node_mem_map;
unsigned long *valid_addr_bitmap;
struct bootmem_data *bdata;
unsigned long node_start_paddr;
unsigned long node_start_mapnr;
unsigned long node_size;
int node_id;
struct pglist_data *node_next;
} pg_data_t;
Bien, ahora describiremos cada uno de los nodos de esta estructura:
node_zones : La zonas para este nodo son ZONE HIGHMEM, ZONE NORMAL, ZONE DMA.
node_zonelists : Este es el orden de las zonas asignadas proveniente de build_zonelists() en mm/page alloc.c , este orden se establece cuando se llamo a free_area_init_core(). Una asignacion fallida en ZONE HIGHMEM puede mandar de regreso a ZONE NORMAL o de regreso a ZONE DMA.
nr_zones : Este es el numero de zonas sobre este nodo, entre uno y tres. No todos los nodos llegaran a tener 3.
node_mem_map Esta es la primera pagina del arreglo de structuras page que representan cada cuadro fisico en el nodo. Es sera acomodado en algun lugar dentro del global mem_map_array.
valid_addr_bitmap : Este es un mapa de bits que describe huecos en el nodo de memoria. En realidad este solo es usado para SPARC.
node_size : Numero total de paginas en esta zona.
node_id : Esta es la ID del nodo (NID).
node_next : Puntero a el siguiente nodo sobre una lista terminada en NULL.
bdata : Este es solo del interes del asignado de memoria de arranque ( boot memory ), hablaremos de el despues.
node_start_paddr : Esta es la principal direccion fisica del nodo.
node_start_mapnr : Este otorga el offset de la pagina dentro del mapa global de memoria (mem_map). Este es calculado en free_area_init_core() , el cual calcula el numero de paginas entre mem_ map y el mem_map local para este nodo llamado lmem_map.
Todos los nodos en el sistema son mantenidos sobre una lista llamada pgdat_list. Los nodos son albergados sobre una lista, como estos van siendo inicializados por la funcion init_bootmem_core().
En los nucleos de linux mas recientes a 2.2, un macro for_each_pgdat(), el cual es trivialmente definido como un loop for, es puesto para mejorar la legilbilidad del codigo.
May 26, 2009 a las 5:24 pm por Edwin Plauchu · Archivado en Programacion, Linux
Aqui les muestro como compilo un programita para ejemplificar el uso de hilos
[j4nusx@localhost ~]$ gcc hilos.c -lpthread -Wall -o hilos
[j4nusx@localhost ~]$ ./hilos
En Funcion main: Creando el Hilo 0
En Funcion main: Creando el Hilo 1
En Funcion main: Creando el Hilo 2
En Funcion main: Creando el Hilo 3
En Funcion main: Creando el Hilo 4
Hola esto se ejecuta en el hilo #0!
Hola esto se ejecuta en el hilo #1!
Hola esto se ejecuta en el hilo #2!
Hola esto se ejecuta en el hilo #3!
Hola esto se ejecuta en el hilo #4!
Aqui el codigo fuente
#include "pthread.h"
#include "stdio.h"
#include "stdlib.h"
#define NUM_THREADS 5
// La funcion que es utilizada en un Hilo
// debera de retornar un puntero sin tipo
void *ImprimeSaludo(void *threadid){
long tid;
// Aqui se castea lo que le fue pasado
// al hilo como atributos
tid = (long)threadid;
printf("Hola esto se ejecuta en el hilo #%ld!n", tid);
pthread_exit(NULL);
}
// --- Aqui finaliza la funcion que
// sera llamada en el hilo
int main (int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];
int rc;
long t;
for(t=0; t < NUM_THREADS; t++){
printf("En Funcion main: Creando el Hilo %ldn", t);
rc = pthread_create(&threads[t], NULL, ImprimeSaludo, (void *)t);
if (rc){
printf("ERROR; return code from pthread_create() is %dn", rc);
exit(-1);
}
}
pthread_exit(NULL);
}
La función que nos permite crear un un nuevo hilo de ejcución es pthread_create() que admite cuatro parámetros:
pthread_t * es un puntero a un identificador de thread. La función nos devolverá este valor relleno, de forma que luego podamos referenciar al hilo para “hacerle cosas”, como matarlo, esperar por él,etc. pthread_attr_t * son los atributos de creación del hilo. Hay varios atributos posibles, como por ejemplo la prioridad. Un hilo de mayor prioridad se ejecutará con preferencia (tendrá más rodajas de tiempo) que otros hilos de menor prioridad. Se puede pasar NULL, con lo que el hilo se creará con sus atributos por defecto y para nuestro ejemplo es suficiente. Si queremos un programa que cree y destruya hilos continuamente, no vale NULL, ya que con esta opción dejaremos memoria sin liberar cada vez que termine un hilo. void *(*)(void *) es un tipo la mar de raro. Aunque asuste, no es más que el tipo de una función que admite un puntero void * y que devuelve void *. Eso quiere decir que a este parámetro le podemos pasar el nombre de una función que cumpla lo que acabamos de decir. Esta función es la que se ejecutará como un hilo aparte. El hilo terminará cuando la función termine o cuando llame a la función pthread_exit() (o que alguien lo mate desde otra parte del código). Es bastante habitual hacer que esta función se meta en un bucle infinito y quede suspendida en un semáforo o a la espera de una señal para hacer lo que tenga que hacer y volver a quedar dormida. void * es el parámetro que se le pasará a la función anterior cuando se ejecute en el hilo aparte. De esta manera nuestro programa principal puede pasar un único parámetro (que puede ser cualquier cosa, como una estructura compleja) a la función que se ejecutará en el hilo. La función del hilo sólo tendrá que hacer el “cast” adecuado.
La función pthread_create() devuelve 0 si todo ha ido bien. Un valor distinto de 0 si ha habido algún problema y no se ha creado el thread.
Si deseas saber mas a detalle el asunto de los hilos en linux, te recomiendo la siguente liga