Skip to content

Instantly share code, notes, and snippets.

@bennydictor
Created April 12, 2017 09:55
Show Gist options
  • Save bennydictor/0d827b922960306c90a7da7680a2ef25 to your computer and use it in GitHub Desktop.
Save bennydictor/0d827b922960306c90a7da7680a2ef25 to your computer and use it in GitHub Desktop.
Proxy for one website and it injects javascript (and probably doesn't work)
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <netdb.h>
#include <poll.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#define BACKLOG 64
#define BUF_LEN (1024*1024)
#define CLIENTS_MAX 256
#define NFDS (2 * CLIENTS_MAX + 1)
#define LOCAL_PORT 8081
#define REMOTE "bash.im"
#define REMOTE_LEN (sizeof(REMOTE) - 1)
#define REMOTE_PORT 80
#define PAYLOAD "<script>alert(\"hOI!\")</script>"
#define PAYLOAD_LEN (sizeof(PAYLOAD) - 1)
#define HEADER_HOST "Host: localhost"
#define HEADER_HOST_LEN (sizeof(HEADER_HOST) - 1)
#define HEADER_ENC "Accept-Encoding: "
#define HEADER_ENC_LEN (sizeof(HEADER_ENC) - 1)
#define END_BODY "</head>"
#define END_BODY_LEN (sizeof(END_BODY) - 1)
void shit_happened(const char *s) {
if (s) {
fprintf(stderr, "%s\n", s);
} else {
fprintf(stderr, "%s (%d)\n", strerror(errno), errno);
}
exit(1);
}
int make_tcp_socket(const char *host, uint16_t port) {
int ret = socket(AF_INET, SOCK_STREAM, 0);
if (ret == -1) shit_happened(NULL);
struct sockaddr_in addr;
memset(&addr, 0, sizeof(struct sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
in_addr_t host_ip;
if (host) {
struct hostent *hostent = gethostbyname(host);
if (!hostent) shit_happened(NULL);
host_ip = *(in_addr_t *) hostent->h_addr_list[0];
} else {
host_ip = htonl(INADDR_ANY);
}
addr.sin_addr.s_addr = host_ip;
if (host) {
if (connect(ret, (struct sockaddr *) &addr,
sizeof(struct sockaddr_in)) == -1) shit_happened(NULL);
} else {
if (bind(ret, (struct sockaddr *) &addr,
sizeof(struct sockaddr_in)) == -1) shit_happened(NULL);
if (listen(ret, BACKLOG) != 0) shit_happened(NULL);
}
return ret;
}
void nonblock(int fd) {
int on = 1;
if (ioctl(fd, FIONBIO, (char *) &on) == -1) shit_happened(NULL);
}
struct pollfd fds[NFDS];
void close_all(void) {
for (int i = 0; i < NFDS; ++i) {
if (fds[i].fd != 0) {
close(fds[i].fd);
}
}
}
int main() {
atexit(close_all);
int sock_listen = make_tcp_socket(NULL, LOCAL_PORT);
nonblock(sock_listen);
memset(&fds, 0, sizeof(fds));
fds[0].fd = sock_listen;
fds[0].events = POLLIN;
char buf[BUF_LEN];
for (;;) {
int evs = poll(fds, NFDS, 3 * 60 * 1000);
if (evs == -1) shit_happened(NULL);
if (evs == 0) continue;
if (fds[0].revents == POLLIN) {
int new_client = accept(fds[0].fd, NULL, NULL);
if (new_client == -1) shit_happened(NULL);
int new_client_pos = -1;
for (int i = 1; i < NFDS; i += 2) {
if (fds[i].fd == 0) {
new_client_pos = i;
break;
}
}
if (new_client_pos == -1) {
shit_happened("Too many clients");
}
printf("client %d new\n", new_client_pos / 2 + 1);
fds[new_client_pos].fd = new_client;
fds[new_client_pos].events = POLLIN;
fds[new_client_pos + 1].fd = make_tcp_socket(REMOTE, REMOTE_PORT);
fds[new_client_pos + 1].events = POLLIN;
nonblock(fds[new_client_pos + 1].fd);
}
for (int i = 1; i < NFDS; i += 2) {
char closed = 0;
if (fds[i].revents & POLLIN) {
printf("client %d send\n", i / 2 + 1);
int len;
if ((len = read(fds[i].fd, buf, BUF_LEN)) == -1)
shit_happened(NULL);
if (len == 0)
goto close_conn;
buf[len] = 0;
char modbuf[BUF_LEN * 2];
int modbuf_ptr = 0;
for (int p = 0; p < len;) {
if (strncmp(buf + p, HEADER_HOST, HEADER_HOST_LEN) == 0) {
printf("client %d fixing Host\n", i / 2 + 1);
strcpy(modbuf + modbuf_ptr, "Host: " REMOTE);
modbuf_ptr += strlen("Host: " REMOTE);
p += HEADER_HOST_LEN;
} else if (strncmp(buf + p, HEADER_ENC,
HEADER_ENC_LEN) == 0) {
printf("client %d fixing Accept-Encoding\n", i / 2 + 1);
strcpy(modbuf + modbuf_ptr, HEADER_ENC "identity");
modbuf_ptr += strlen(HEADER_ENC "identity");
modbuf[modbuf_ptr++] = '\r';
for (; buf[p] != '\n'; ++p);
} else {
modbuf[modbuf_ptr++] = buf[p++];
}
}
if (write(fds[i + 1].fd, modbuf, modbuf_ptr) == -1)
shit_happened(NULL);
}
if (fds[i + 1].revents & POLLIN) {
int len;
printf("client %d recv\n", i / 2 + 1);
if ((len = read(fds[i + 1].fd, buf, BUF_LEN)) == -1)
shit_happened(NULL);
buf[len] = 0;
if (len == 0)
goto close_conn;
char modbuf[BUF_LEN + PAYLOAD_LEN + 1];
int modbuf_ptr = 0;
for (int p = 0; p < len;) {
if (strncmp(buf + p, END_BODY, END_BODY_LEN) == 0) {
printf("client %d injecting payload\n", i / 2 + 1);
strcpy(modbuf + modbuf_ptr, PAYLOAD);
modbuf_ptr += PAYLOAD_LEN;
}
modbuf[modbuf_ptr++] = buf[p++];
}
if (write(fds[i].fd, modbuf, modbuf_ptr) == -1)
shit_happened(NULL);
}
if (closed) {
close_conn:
close(fds[i].fd);
close(fds[i + 1].fd);
memset(fds + i, 0, 2 * sizeof(struct pollfd));
printf("client %d term\n", i / 2 + 1);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment