unix4fun

Aller au contenu | Aller au menu | Aller à la recherche

mardi 12 février 2013

Trill et private vlans

Je bosse chez gandi.net, et bien que je n'aime pas trop l'autopromotion : il se trouve qu'on est en train de sortir quelque chose d'assez sympa. Trill (L2 routing) pour les intimes... mais aussi et surtout Private vlans over Trill. L'implémentation linux sera opensource (date pas encore définie puisque très dépendante de la kernel team linux). Un document sera bien mieux que mes babillages.

mardi 2 octobre 2012

Le stockage flash pour les nuls

L'autre jour je suis allé à l'une des trop rares conférences sur le kernel linux. Et l'une de ces conférences était claire précise et assez bien expliquée. Cette conférence est donnée par un des monsieur qui gèrent les fs flash et une partie du sous-systeme mtd du kernel linux : david woodcombe. Bref ça se passe par ici.

samedi 15 septembre 2012

Et voici MoisiFS !

Salut les gens !

Oui oui, vous l'aurez deviné, je présente (façon de parler) ici un truc que je viens de coder : un filesystem FUSE au-dessus des fichiers au format ELF.

Bon alors là, tout de suite, logiquement vous me dites "euh ok c'est bien gentil ton truc mais ça sert à quoi ?", ce à quoi je réponds "rien !". Plus sérieusement, ça sert à se faire un peu la main sur FUSE (donc vous pouvez regarder le code pour vous faire une idée, j'ose espérer qu'il n'est pas trop cracra). Ça peut également servir à des fins pédagogiques : voir la structure d'un fichier ELF, tout ça...

Bon, le but avoué, c'est qu'à terme, on puisse modifier un binaire, ou carrément un processus en cours via le point de montage. Par exemple en faisant un truc du genre :


echo 0x424242 > /mnt/elf/entrypoint
sed -i "s:generic_func:myhook_func:g" /mnt/elf/symbols

Ou autres trucs du genre ! Amusant non ? Non ? Bon.. ok... j'retourne coder d'autres crottes en silence...

Sinon pour l'instant on peut juste faire 2-3 trucs en read-only:

  • monter un binaire sur disque ou un process en cours d'exécution (expérimental, tout ça...)

$ elfs /usr/bin/screen /mnt/elf
ou
$ sudo elfs -p $(pidof screen) /mnt/elf

  • lister les lib (répertoire /mnt/elf/libs/)

$ ls -l /mnt/elf/libs
total 0
-rwxrwxrwx 0 root root  9 1970-01-01 01:00 libc.so.6
-rwxrwxrwx 0 root root  9 1970-01-01 01:00 libm.so.6
-rwxrwxrwx 0 root root 11 1970-01-01 01:00 libX11.so.6
-rwxrwxrwx 0 root root 11 1970-01-01 01:00 libXaw.so.7
-rwxrwxrwx 0 root root 11 1970-01-01 01:00 libXft.so.2
-rwxrwxrwx 0 root root 15 1970-01-01 01:00 libxkbfile.so.1
-rwxrwxrwx 0 root root 11 1970-01-01 01:00 libXmu.so.6
-rwxrwxrwx 0 root root 15 1970-01-01 01:00 libXrender.so.1
-rwxrwxrwx 0 root root 10 1970-01-01 01:00 libXt.so.6

  • visualiser le header ELF à-la readelf -h (fichier /mnt/elf/info)

$ cat /mnt/elf/info
Ident:                             7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
Version:                           1
Class:                             64
Type:                              EXEC (Executable file)
Version:                           1
ELF Header size:                   64 bytes
Entry point:                       0x402550
Program Header offset:             64 bytes
Program Header entry size:         56 bytes
Number of Program Header entries:  9
Section Header offset:             40768 bytes
Section Header entry size:         64 bytes
Number of Section Header entries:  28
SH string table index:             27

  • lister les sections, dans /mnt/elf/sections : bss, data, symtab, dynsym, etc

$ ls -l /mnt/elf/sections/
total 0
drw------- 1 root root 0 1970-01-01 01:00 bss
drw------- 1 root root 0 1970-01-01 01:00 ctors
drw------- 1 root root 0 1970-01-01 01:00 data
drw------- 1 root root 0 1970-01-01 01:00 dtors
drw------- 1 root root 0 1970-01-01 01:00 dynamic
dr-------- 1 root root 0 1970-01-01 01:00 dynstr
dr-------- 1 root root 0 1970-01-01 01:00 dynsym
[...]

  • lister les symboles dans /mnt/elf/sections/symtab et /mnt/elf/sections/dynsym

$ ls -l /mnt/elf/sections/dynsym/|tail -5
d--------- 1 root root 0 1970-01-01 01:00 XtStrings
d--------- 1 root root 0 1970-01-01 01:00 XtWidgetToApplicationContext
d--------- 1 root root 0 1970-01-01 01:00 XtWindow
d--------- 1 root root 0 1970-01-01 01:00 XtWindowOfObject
d--------- 1 root root 0 1970-01-01 01:00 XUnionRectWithRegion

  • pour chaque symbole, lire ses infos (STT_FUNC, etc) et son code, au format binaire ou asm (code.bin et code.asm)... mieux vaut que le binaire soit compilé en debug, ou du moins avec les symboles, et non stripé, sinon vous allez vous retrouvez en galère d'infos

$ ls -l /mnt/elf/sections/symtab/dup_regex_free/
total 0
---------- 0 root root 363 1970-01-01 01:00 code.asm
---------- 0 root root  78 1970-01-01 01:00 code.bin
---------- 0 root root  69 1970-01-01 01:00 info

$ cat /mnt/elf/sections/symtab/dup_regex_free/code.asm
push rbp
mov rbp, rsp
sub rsp, 0x10
mov [rbp-0x8], rdi
mov rax, [rbp-0x8]
mov rax, [rax+0x48]
test rax, rax
jz 0x35
mov rax, [rbp-0x8]
mov rax, [rax+0x48]
mov rdi, rax
call dword 0xfffffd9c
mov rax, [rbp-0x8]
mov qword [rax+0x48], 0x0
mov rax, [rbp-0x8]
mov eax, [rax+0x50]
test eax, eax
jz 0x4c
mov rax, [rbp-0x8]
mov rdi, rax
call dword 0xfffffeac
leave 
ret 

Ouala pour l'instant c'est tout....

J'essaie d'ajouter des trucs quand j'ai le temps mais bon, d'une part j'suis pas mal occupé à faire des trucs pas intéressants, et en plus je code comme une buse et à la lenteur d'un cloporte arthritique, c'est pas gagné...

Le code : c'est par ici !

Bref, see ya dudes!

Ah j'oubliais un truc important : c'est Linux-only... hey ouais, j'ai pas trouvé de truc plus malin que checker /proc/pid/exe pour avoir l'adresse de mapping du binaire depuis le PID. On me souffle dans l'oreille de faire des trucs sioux avec ptrace() + les registres, qui donnent un emplacement dans le code, puis checker en arrière les adresses modulo _sysconf(_SC_PAGESIZE) pour essayer de retomber sur les 4 bytes ELF_MAGIC du header. Plus tard plus tard... déjà on va essayer de faire en sorte que ça SIGSEGV pas trop :P

EDIT: hop, apparemment maintenant ça compile/tourne sous freebsd (j'ai pas pu tester mais le bon sbz m'a envoyé un patch qui fait le taff)

jeudi 7 octobre 2010

Pwnage par libpcap

Yo. Dans ce post je vais expliquer comment je me suis battu pour faire un truc assez simple avec la libpcap sous linux.

Au début était un sniffer, je voulais écouter sur une interface à grands coups de SOCK_RAW + recvfrom(). À l'ancienne, quoi. L'idée était de ne pas utiliser de handler pcap (pcap_t *). Au bout d'un moment je me dis "tiens, ça serait sympa d'ajouter les filtres BPF comme dans tcpdump". Brillante idée, non ? Non, ok. Bref, le code de départ est le suivant :

// -*- c-basic-offset: 4; indent-tabs-mode: nil -*-
// vim:sw=4 ts=4 sts=4 expandtab
#include <limits.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <linux/if_ether.h>
#include <arpa/inet.h>
#include <netpacket/packet.h>
#include <poll.h>
#include <linux/types.h>
#include <errno.h>
#include <pcap.h>
#include <linux/filter.h>

#define FRAME_SIZE 65536

/* iface_setprom() sets "device" in promiscuous mode */
static int
iface_setprom(int sock_fd, const char *device)
{
    struct ifreq ifr;

    memset(&ifr, 0, sizeof ifr);
    snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", device);

    if (ioctl(sock_fd, SIOCGIFFLAGS, &ifr) == -1) {
        printf("[%s] ioctl: %s.\n", device, strerror(errno));
        return -1;
    }

    ifr.ifr_flags |= (IFF_PROMISC | IFF_UP);

    if (ioctl(sock_fd, SIOCSIFFLAGS, &ifr) == -1) {
        printf("[%s] ioctl: %s.\n", device, strerror(errno));
        return -1;
    }

    printf("[%s] enter in promiscuous mode\n", device);
    return 0;
}



À partir d'une chaîne de caractère entrée, par exemple "tcp and port 22", on veut obtenir une structure comprise par pcap_compile*(). Comme dit précédemment, je ne veux pas de pcap_t* à manipuler, je vais donc utiliser pcap_compile_nopcap() (non mentionné dans le man de pcap_compile sous linux, évidemment).

/* iface_setfilter() applies a LSF filter to the file descriptor */
static int
iface_setfilter(int sock_fd, const char * const device, const char * const filter)
{
    if (!filter || !*filter) {
        printf("[%s] no filter to install\n", device);
        return 0;
    }

    struct bpf_program bpf;
    memset(&bpf, 0, sizeof bpf);

    char errbuf[PCAP_ERRBUF_SIZE = "";

    if (-1 == pcap_compile_nopcap(FRAME_SIZE, DLT_RAW, &bpf, filter, 1, 0)) {
        printf("[%s] pcap_compile_nopcap failed for '%s'\n", device, filter);
        return -1;
    }

    if (-1 == setsockopt(sock_fd, SOL_SOCKET, SO_ATTACH_FILTER, &bpf, sizeof bpf)) {
        printf("[%s] setsockopt: %s (filter '%s')\n", device, strerror(errno), filter);
        return -1;
    }

    printf("[%s] filter '%s' successfully installed\n", device, filter);
    return 0;
}

/* iface_init() is the main device initialization function */
static int
iface_init(struct pollfd *fds, const char * const device, const char * const filter)
{
    printf("Initializing interface %s (filter '%s')\n", device, filter);

    fds->fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
    if (fds->fd == -1) {
        printf("[%s] socket: %s. Exiting...\n", device, strerror(errno));
        exit(EXIT_FAILURE);
    }

    fds->events = POLLIN | POLLPRI;

    if (0 != iface_setprom(fds->fd, device)) return -1;
    if (0 != iface_bind(fds->fd, device)) return -1;
    if (0 != iface_setfilter(fds->fd, device, filter)) return -1;

    return 0;
}

static void
frame_manager(const char * const device, struct pollfd *fd, struct timeval const *now)
{
    uint32_t i;

    if ((fd->revents & (POLLIN | POLLPRI)) == 0)
        return;

    unsigned char buf[1500] = "";
    ssize_t n = recvfrom(fd->fd, buf, sizeof buf, MSG_DONTWAIT, NULL, NULL);
    if (n < 0) {
        printf("[%s] recvfrom: %s (i=%d, fd=%d)\n", device, strerror(errno), i, fd->fd);
        return;
    }

    printf("[%d,%d] packet received\n", (int)now->tv_sec, (int)now->tv_usec);
}

int main(int ac, char **av)
{
    char *filter = "";
    char *device = "dummy0";

    if (ac > 1) {
        filter = av[1];
    }

    struct pollfd fd;
    (void)iface_init(&fd, device, filter);

    while (/*CONSTCOND*/ 1) {
        if (poll(&fd, 1, -1) > 0) {
            struct timeval now;
            gettimeofday(&now, NULL);
            frame_manager(device, &fd, &now);
        }
    }

    close(fd.fd);
    return EXIT_SUCCESS;
}



Tout d'abord, je monte une interface virtuelle pour éviter le bruit généré par les paquets circulants sur mes vraies interfaces :

$ sudo modprobe dummy
$ sudo ifconfig dummy0 mtu 1600 up



Maintenant, si je compile et j'exécute le code, et que je balance du ssh sur dummy0, j'ai ça :

$ cc -o cap cap.c -lpcap
$ sudo ./cap "tcp and port 22"
[...]



Et dans un autre terminal :

$ sudo tcpreplay -i dummy0 ssh.pcap



Mais aucun "packet received" ne s'affiche. Damned ! En inspectant un peu le code, on voit ça :

    if (-1 == setsockopt(sock_fd, SOL_SOCKET, SO_ATTACH_FILTER, &bpf, sizeof bpf)) {



Ça a l'air bien comme ça, hein. Malheureusement, le 'struct bpf_program' n'est pas compris sous linux, qui, ne voulant pas faire comme ses potes *BSD attend un 'struct sock_fprog *' en avant dernier argument. Bon, ici je me dis "il doit bien y avoir une fonction qui fait la conversion, cherchons dans le source de libpcap". En jetant un coup d'oeil rapide, on tombe sur ça :

libpcap-0.9.8/pcap-linux.c:215 static int       fix_program(pcap_t *handle, struct sock_fprog *fcode);



Je suis content, mais visiblement je dois passer par un pcap_t. Du coup, je reprends le code en l'adaptant pour taper directement dans la structure interne du handler pcap, et j'écris la fonction suivante :

#define SLL_HDR_LEN 16
static int lcc = 0; // linux cooked capture

static int
fix_offset(struct bpf_insn *p)
{
    if (p->k >= SLL_HDR_LEN) {
        p->k -= SLL_HDR_LEN;
    } else if (p->k == 14) {
        p->k = SKF_AD_OFF + SKF_AD_PROTOCOL;
    } else {
        return -1;
    }
    return 0;
}

static int
fix_code(struct bpf_program *bpf, struct sock_fprog *fcode)
{
    size_t prog_size;
    register int i;
    register struct bpf_insn *p;
    struct bpf_insn *f;
    int len;

    len = bpf->bf_len;
    prog_size = sizeof(bpf->bf_insns) * len;
    f = malloc(prog_size);
    if (f == NULL) {
        printf("malloc: %s\n", strerror(errno));
        return -1;
    }
    memcpy(f, bpf->bf_insns, prog_size);
    fcode->len = len;
    fcode->filter = (struct sock_filter *)f;

    for (i = 0; i < len; ++i) {
        p = &f[i];
        switch (BPF_CLASS(p->code)) {

        case BPF_RET:
            if (BPF_MODE(p->code) == BPF_K) {
                if (p->k != 0)
                    p->k = 65535;
            }
            break;

        case BPF_LD:
        case BPF_LDX:
            switch (BPF_MODE(p->code)) {

            case BPF_ABS:
            case BPF_IND:
            case BPF_MSH:
                if (lcc) {
                    if (fix_offset(p) < 0) {
                        return 0;
                    }
                }
                break;
            }
            break;
        }
    }
    return 1;       /* success! */
}



Maintenant je réécris ma fonction iface_setfilter() pour convertir le code BPF :

static int
iface_setfilter(int sock_fd, const char * const device, const char * const filter)
{
    if (! filter || ! *filter) {
        printf("[%s] no filter to install\n", device);
        return 0;
    }

    struct bpf_program bpf;
    memset(&bpf, 0, sizeof bpf);

    if (-1 == pcap_compile_nopcap(FRAME_SIZE, DLT_RAW, &bpf, filter, 1, 0)) {
        printf("[%s] pcap_compile_nopcap failed for '%s'\n", device, filter);
        return -1;
    }

    struct sock_fprog fcode;
    memset(&fcode, 0, sizeof fcode);
    int ret = fix_code(&bpf, &fcode);

    if (1 != ret) {
        printf("[%s] fix_code failed (rcode = %d) for filter '%s'\n", device, ret, filter);
        return -1;
    } else {
        printf("[%s] fix_code worked (rcode = %d) for filter '%s'\n", device, ret, filter);
    }

    if (-1 == setsockopt(sock_fd, SOL_SOCKET, SO_ATTACH_FILTER, &fcode, sizeof fcode)) {
        printf("[%s] setsockopt: %s (filter '%s')\n", device, strerror(errno), filter);
        return -1;
    }

    printf("[%s] filter '%s' successfully installed\n", device, filter);
    return 0;
}



Là, logiquement je me dis "Youpi les knakis¸ ça va marcher !". Mais si je reteste, toujours rien. Rien ne s'affiche. La blague est même que si j'invoque :

$ sudo ./cap "not port 80"



... et que je joue du traffic http (sur le port 80 bien sûr), mon outil logue qu'il a vu un paquet ! Par contre avec "port 80" il n'affiche rien. Bon je me suis pas mal gratté la tête ici, j'avoue. Du coup j'appelle mon copain strace à la rescousse, et je compare le raw des filtres passés à setsockopt() entre mon code et l'appel tcpdump :

$ sudo strace -s 256 -f -v ./cap "port 80" 2>&1 | grep ATTACH_FILTER
setsockopt(3, SOL_SOCKET, SO_ATTACH_FILTER, "\33\0\0\0\0\0\0\0\20\240\363\0\0\0\0\0", 16) = 0
^C
$ sudo strace -s 256 -f -v tcpdump -ni dummy0 port 80 2>&1 | grep ATTACH_FILTER
setsockopt(3, SOL_SOCKET, SO_ATTACH_FILTER, "\1\0\0\0\0\0\0\0h\303\315E(\177\0\0", 16) = 0
setsockopt(3, SOL_SOCKET, SO_ATTACH_FILTER, "\30\0\0\0\0\0\0\0\360V1G(\177\0\0", 16) = 0
^C



Les outputs ne sont pas les mêmes. La génération du filtre est donc foireuse, je vérifie maintenant comme suit :

$ sudo tcpdump -nd port 80
(000) ldh      [12]
(001) jeq      #0x86dd          jt 2    jf 10
(002) ldb      [20]
(003) jeq      #0x84            jt 6    jf 4
(004) jeq      #0x6             jt 6    jf 5
(005) jeq      #0x11            jt 6    jf 23
(006) ldh      [54]
(007) jeq      #0x50            jt 22   jf 8
(008) ldh      [56]
(009) jeq      #0x50            jt 22   jf 23
(010) jeq      #0x800           jt 11   jf 23
(011) ldb      [23]
(012) jeq      #0x84            jt 15   jf 13
(013) jeq      #0x6             jt 15   jf 14
(014) jeq      #0x11            jt 15   jf 23
(015) ldh      [20]
(016) jset     #0x1fff          jt 23   jf 17
(017) ldxb     4*([14]&0xf)
(018) ldh      [x + 14]
(019) jeq      #0x50            jt 22   jf 20
(020) ldh      [x + 16]
(021) jeq      #0x50            jt 22   jf 23
(022) ret      #96
(023) ret      #0



Et j'invoque

    if (-1 == pcap_compile_nopcap(FRAME_SIZE, DLT_RAW, &bpf, filter, 1, 0)) {
        printf("[%s] pcap_compile_nopcap failed for '%s'\n", device, filter);
        return -1;
    }
    bpf_dump(&bpf, 0);



J'ai en sortie :

Initializing interface dummy0 (filter 'port 80')
[dummy0] enter in promiscuous mode
[dummy0] bind succeed: index 1634 <--> dummy0
(000) ldb      [0]
(001) and      #0xf0
(002) jeq      #0x60            jt 3    jf 11
(003) ldb      [6]
(004) jeq      #0x84            jt 7    jf 5
(005) jeq      #0x6             jt 7    jf 6
(006) jeq      #0x11            jt 7    jf 26
(007) ldh      [40]
(008) jeq      #0x50            jt 25   jf 9
(009) ldh      [42]
(010) jeq      #0x50            jt 25   jf 26
(011) ldb      [0]
(012) and      #0xf0
(013) jeq      #0x40            jt 14   jf 26
(014) ldb      [9]
(015) jeq      #0x84            jt 18   jf 16
(016) jeq      #0x6             jt 18   jf 17
(017) jeq      #0x11            jt 18   jf 26
(018) ldh      [6]
(019) jset     #0x1fff          jt 26   jf 20
(020) ldxb     4*([0]&0xf)
(021) ldh      [x + 0]
(022) jeq      #0x50            jt 25   jf 23
(023) ldh      [x + 2]
(024) jeq      #0x50            jt 25   jf 26
(025) ret      #65536
(026) ret      #0
[dummy0] fix_code worked (rcode = 1) for filter 'port 80'
[dummy0] filter 'port 80' successfully installed
^C



On voit bien que c'est différent au début. Le reste est plutôt cohérent

(016) jeq      #0x6             jt 18   jf 17  # 0x06 c'est l'IPPROTO_TCP (6)
(017) jeq      #0x11            jt 18   jf 26  # 0x11 = 17 = IPPROTO_UDP



Si on n'est dans aucun des deux cas, on saute en 26 (jf 26), soit la fin. Sinon, on regarde si le port vaut 80 (0x50) :

(022) jeq      #0x50            jt 25   jf 23
(023) ldh      [x + 2]
(024) jeq      #0x50            jt 25   jf 26



Le problème est vraiment le prologue. Et là je on me souffle à l'oreille que c'est peut-être le datalink type. Réaction: "bon dieu de !#@@!#@!# mais c'est bien sûr, ça doit être mon datalink (DLT) qui est moisi !" Si j'écris :

    if (-1 == pcap_compile_nopcap(FRAME_SIZE, DLT_IEEE802, &bpf, filter, 1, 0)) {



J'obtiens en sortie :

$ cc -o cap cap.c -lpcap && sudo ./cap "port 80" 
Initializing interface dummy0 (filter 'port 80')
[dummy0] enter in promiscuous mode
[dummy0] bind succeed: index 1634 <--> dummy0
(000) ldh      [20]
(001) jeq      #0x86dd          jt 2    jf 10  # 0x86dd est l'ethertype IPv6
(002) ldb      [28]
(003) jeq      #0x84            jt 6    jf 4
(004) jeq      #0x6             jt 6    jf 5
(005) jeq      #0x11            jt 6    jf 23
(006) ldh      [62]
(007) jeq      #0x50            jt 22   jf 8
(008) ldh      [64]
(009) jeq      #0x50            jt 22   jf 23
(010) jeq      #0x800           jt 11   jf 23  # 0x800 est l'ethertype IPv4
[...]



Mais toujours rien n'est logué si je joue du http ! En remplaçant DLT_IEEE802 par DLT_EN10MB en revanche...

[...]
[dummy0] enter in promiscuous mode
[dummy0] bind succeed: index 1634 <--> dummy0
[dummy0] fix_code worked (rcode = 1) for filter 'port 80'
[dummy0] filter 'port 80' successfully installed
[1286457559,615193] packet received



Hallelujah ! Hosanna hosanna !

Enfin bon, c'est quand même moche d'écrire le DLT en dur dans le code, donc je l'ai récupéré via la libpcap (mais on est obligé de passer par un handler pcap_t *, ce que je ne voulais pas trop au début...)

    char errbuf[256] = "";
    pcap_t *p = pcap_open_live(device, FRAME_SIZE, 1, 0, errbuf);
    if (! p) {
        printf("[%s] pcap_open_live failed: %s\n", device, errbuf);
        return -1;
    }

    int dlt = pcap_datalink(p);
    pcap_close(p);

    if (-1 == pcap_compile_nopcap(FRAME_SIZE, dlt, &bpf, filter, 1, 0)) {
        printf("[%s] pcap_compile_nopcap failed for '%s'\n", device, filter);
        return -1;
    }



En fait, comme on dispose du handler pcap_t, on peut même dégager pcap_compile_nopcap() et utiliser pcap_compile(), qui lui n'a même pas besoin d'un DLT en paramètre... Tout ça parce que j'ai voulu me passer de ce foutu handler, en somme. Bref le code est disponible ici

jeudi 31 décembre 2009

Vas-y, montre moi tes doigts ?!

Tu aimes Netfilter mais voilà, tu voudrais bien aussi faire... de l'OS fingerprinting ? C'est possible depuis la version 2.6.31, grâce au module xt_osf qui a été inclu officiellement. Donc voilà comment ça marche, un petit exemple :

  1. insmod ./xt_osf.ko
  2. ./nfnl_osf -f ./pf.os
  3. iptables -I INPUT -j ACCEPT -p tcp -m osf log 0 ttl 2

Tout d'abord un commentaire sur pf.os, c'est le fichier utilisé par packet filter, donc le fichier de définition de p0f, le tool de mister Zalewski. Ensuite on fait un test de connexion, et on voit dans les logs :

Windows 2000:SP4 : 192.168.028.131:2007 -> 192.168.028.124:22 hops=0

L'archive pour le programme userland (nfnl_osf) et les infos sont sur le bleurg de l'auteur du patch initial : http://ioremap.net/projects/osf

vendredi 6 novembre 2009

meme vieux on continue d'apprendre

Je rentre dans ma 65 eme annee et je continue encore d'apprendre de nouvelles choses.. Au cours d'une discussion avec un pote sur "l'intrawebz" (tm) j'ai appris l'existence des register_printf_functions.. comme decrit dans les liens suivants:

Et au passage qqqes docs sur les attributes GCC et des ptits examples:

Edit de poz:

  • on note au passage que dans le premier lien, l'auteur ne sait pas comment virer un warning gênant à la compilation (dû à -Wformat, lui-même inclu dans -Wall) ; pour s'en débarrasser, il suffit de passer l'option -Wno-format à gcc. Ceci dit, il faut faire attention, parce qu'il ne râlera plus quand vous utiliserez le mauvais /specifier/ (genre %s au lieu de %zu), donc méfiance...
  • bon alors bien sûr c'est quand on migre son code que la merde arrive par tombereaux entiers :). Alors, register_printf_function() est deprecated à partir de glibc 2.10, il faut donc utiliser register_printf_specifier() à la place. Un coup de #if __GLIBC_PREREQ(2,10) sous linux devrait faire l'affaire... je mets au conditionnel parce que chez moi le printf() segfault :)

mercredi 13 août 2008

pthread pour les NULL

Je code comme un boulet et en ce moment j ai pleins de blems de "scheduling" et de "concurrence", mon code n'est pas thread safe et je dois jongler avec differentes conditions plus ou moins synchro mais qui sont hyper importantes.

bref comme je galerais un peu, nitrouze m'a montre ce petit reminder sympa pour me rappeler les bases des POSIX threads... y a pas a dire je suis un boulet et y a pas de secret si on pratique pas, ca reste pas..

HTH, ++

jeudi 17 juillet 2008

bon je vais me recycler dans le pressing, un truc facile...

\_0< COIN!

http://piotrbania.com/all/kon-boot/

tout est dit!. (mais ca ressemble tres tres fortement au concept de eeye bootroot/sysrq2)

mercredi 2 juillet 2008

Linux, Cisco, Poils!

C'est peut etre "vieux" (y'en a qui aiment dire ca le plus souvent possible pour bien souligner qu'il sont tres contemporains), en tout cas, moi je connaissais pas et je trouve ca fun, fendart meme, mouahhahah j'en ris :)

uClinux sur du cisco muah!

Y a des gens qui commencent des trucs sexy, je suis sur qu'il y a ou va y avoir une suite c'est pas possible! ca date de 2001! (je faisais des avions en papier en disant que j'etais trop fort a cet epoque).

Et puis y a ca aussi.

have fun..

mercredi 25 juin 2008

TCP on steroids et encore d'autres trucs

Si toi aussi tu fais du code reseau en ce moment et que tu cherches toute sortes d'idees, tips et ce genre de choses Il n'y a pas longtemps la grande, la celebre USENIX conference a eu lieu avec son lots d'idees a reflechir-o-pompaz.

Peut etre que tu trouvera ce trucs interessant:

http://www.usenix.org/events/usenix08/tech/full_papers/menon/menon_html/index.html

Sinon y a ca qui traine aussi...

enjoy!

vendredi 23 mai 2008

Sexy Ksplice (girls ?)

Booon, alors je suis tombé sur un petit truc rigolo. Un petit soft, qui fait la modification de code à runtime dans le noyau linux, c'est persistant, qui plus est ! Au prochain reboot ça restera en place. Idéal par exemple pour faire des patches de sécurité sans engendrer un reboot. Les esprits vifs (et pervers ?) feront tout de suite des remarques du genre "haaaan, et pis comme ça c'est plus propre que d'écrire dans /dev/kmem", euh, certes, certes. Petits canaillous.

Le lien, par ici (sponsorisé par le MIT).

mardi 13 mai 2008

Le gros débit du long bidon du débit d'eau de Bobby.

Alors eau et moi là, on bosse tous les deux sur de la capture de paquets, et suite à une n-ième et instructive conversation sur LSF/BPF/Prout/Whatever, je suis tombé sur un site intéressant, pour la comparaison de performances pour les gros, GROS trafics (de l'ordre du Gigabit).

On y trouve une comparaison entre FreeBSD et Linux, un patch (douteux ?) de libpcap, des benches quant au processeur utilisé (apparemment AMD Opteron > Intel Xeon), et même un .config tout fait. Il y a également des articles intéressants sur ce sujet, soumis à des confs.

Pour voir tout ça, il faut jeter un oeil par ici.

lundi 26 novembre 2007

TPM, TCPA et pleins d'acronymes comme ca!

C'est vaguement lie au post precedent, le Filesystem cryptographique est capable d'interagir avec l'architecture TCPA bla

le project TPM implemente une TCG Software stack (Trusted Computing Group Software Stack), ca vous permet (quand ca marche) d'utiliser votre chipset TCPA , via une API ouverte et documentee et donc de "potentiellement-avec-un-sacrifice-de-poulet" faire des application qui serait "potentiellement-blablabla" "trusted" (hanlanannaa le raccourci!!) :

enfin en gros c'est un driver et une API pour TCPA.

le project enforcer est une sorte de veriexec(4) qui utiliserait TPM/TCPA avec qqes features en plus :

OpenTC est une tentative de federation avec pour but d'arriver a un "framework" unifie et open source (soit disant, on verra avec le temps..)

en passant j'ai decouvert ca :

En prime la spec TSS

encore un filesystem chiffre

Je ne le connaissais pas, eCryptfs utilise FIST et se veut "solide" (je ne sais pas vraiment ce qu'il en est), il rajoute des meta-data au files du FS pour que chaque fichier soit stockes avec ses params d'encryption etc.. enfin voyez par vous meme, je n'ai pas teste..

http://ecryptfs.sourceforge.net/

vendredi 14 septembre 2007

Week-end food #4

Hey un peu de retard pour le quick post des week-end food :

  1. How To Write Shared Libraries by Ulrich Drepper
  2. Object Oriented Programming with ANSI-C by Axel Tobias Schreiner

Hopla boum bon app', la semaine prochaine ça n'est plus moi mais Mr ppr qui devrait être de retour avec de la stuff !

Enjoy your week-end!

vendredi 7 septembre 2007

ubuntu jacky security

Un p'tit truc fait sympa et utile :

http://kernelsec.cr0.org/

Hope it helps.

vendredi 31 août 2007

le ps est en déroute

Alors là je suis fier de mon jeu de mot. Vraiment, hein..

Bon bah juste une petite news de rien : on remarque souvent qu'avec ps on a des résultats un peu chelous, voire parfois carrément aberrants, en terme d'utilisation de la mémoire. Y'a plusieurs raisons à ça. On regarde l'occupation mémoire d'un process via ps puis pmap :

$ ps -FC Thunar
UID        PID  PPID  C    SZ   RSS PSR STIME TTY          TIME CMD
poz       5426  5414  0  3409  4720   0 Aug26 ?        00:00:00 Thunar --sm-client-id 117f000101000118510838300000138390002 --daemon

Soit en gros 4M de RAM utilisée

$ pmap -d `pidof Thunar`
Address   Kbytes Mode  Offset           Device    Mapping
08048000     480 r-x-- 0000000000000000 008:00002 Thunar
080c0000       8 rw--- 0000000000077000 008:00002 Thunar
080c2000     260 rw--- 00000000080c2000 000:00000   [ anon ]
b727d000      64 r---- 0000000000000000 008:00002 Thunar.mo
b728d000      28 r---- 0000000000000000 008:00002 libexo-0.3.mo
[...]
b7eed000     100 r-x-- 0000000000000000 008:00001 ld-2.5.so
b7f06000       8 rw--- 0000000000019000 008:00001 ld-2.5.so
bff52000      84 rw--- 00000000bff52000 000:00000   [ stack ]
ffffe000       4 r-x-- 0000000000000000 000:00000   [ anon ]
mapped: 13640K    writeable/private: 792K    shared: 84K
$

On remarque que des segments de code sont comptés plusieurs fois (un segment pour la lecture, un pour l'exec, avec recouvrement). Bref, ça confirme juste ce qu'on sait déjà : ps se contente paresseusement d'afficher la quantité théorique maximale de mémoire utilisée (avec certains bouts de code en double, qui plus est), alors que les libs partagées sont pas exclusivement réservées à ce process... Bref, la "vraie" mémoire est indiquée en bas de l'output, "writeable/private: 792K".

$ cat > ~/bin/mem.sh
#!/bin/bash

function usage()
{
        echo "Usage: $(basename $0) PROCESS..."
        echo "display the (real) memory usage of processes"
}

if [ "$#" = "0" ]
then    usage
        exit 0
fi

OUT=
echo "memory usage:"

for i in $*
do
        OUT=$(pidof $i | cut -d' ' -f1)
        if [ "$OUT" = "" ]
        then    echo "[-] process '$i' does not exist"
        else    OUT2=$(pmap -d $OUT | grep private | awk '{print $4}')
                echo "[+] ${i} (pid ${OUT}): $OUT2"
        fi
done
^D
$ chmod +x ~/bin/mem.sh
$ shebang.sh ~/bin/mem.sh
$ mem.sh X firefox-bin ssh prout
memory usage:
[+] X (pid 4965): 415736K
[+] firefox-bin (pid 5582): 295068K
[+] ssh (pid 5580): 796K
[-] process 'prout' does not exist
$

Pour shebang.sh, cf. un commentaire ailleurs :)

Je sais pas trop sur les *BSD si pmap est dispo... feedback ? Pfff, 3:05 du mat', je vais être frais au taff, encore.

mardi 28 août 2007

Chiffrer sa box entièrement et proprement

Bon mes disques ont partiellement crashé. Du coup j'ai dû backuper ce que je pouvais, je me suis mis à tout refaire après avoir changé le disque qui se chiait dessus et pour le plaisir je me suis dit que j'allais être un peu parano.

Hein, vu que je cache les sources de ls(1) et objdump(1) fallait bien encrypter tout ça au cas ou l'OpenSouce (c)(tm)(r) devienne une propagande illégale en Europe, un danger pour l'informatique propriétaire et ses nobles destriers (et leurs piscines en argent massif, bon ok c'est de la provoc' a 2frc, mais c'est relou j'ai pas encore de piscine :/)

Alors j'ai lu ça :

http://gentoo-wiki.com/SECURITY_System_Encryption_DM-Crypt_with_LUKS

Et now je boot sur une jolie clef USB avec une random key encrypted. C'est bien convi, je prépare la même chose sur mon laptop Linux, à voir si c'est possible avec une clef USB et un NetBSD, ce qui serait bien classieux, huhuhu :)

Bref je foutrai des updates si j'ai le temps de faire/tester une version NetBSD, sinon c'est que j'ai été trop fainéant alors voilà...