minimal-raw-netcat

Adapt attack.sh to use it instead of OS netcat and fox various bugs that
exposed.
This commit is contained in:
Andy Green 2018-05-02 08:46:16 +08:00
parent f1c56bc233
commit da0be64f68
15 changed files with 496 additions and 74 deletions

View file

@ -897,6 +897,9 @@ lws_cancel_service(struct lws_context *context)
struct lws_context_per_thread *pt = &context->pt[0];
short m = context->count_threads;
if (context->being_destroyed1)
return;
lwsl_info("%s\n", __func__);
while (m--) {

View file

@ -23,16 +23,10 @@
#include <private-libwebsockets.h>
static int
elops_destroy_context1_poll(struct lws_context *context)
{
return 1;
}
struct lws_event_loop_ops event_loop_ops_poll = {
/* name */ "poll",
/* init_context */ NULL,
/* destroy_context1 */ elops_destroy_context1_poll,
/* destroy_context1 */ NULL,
/* destroy_context2 */ NULL,
/* init_vhost_listen_wsi */ NULL,
/* init_pt */ NULL,

View file

@ -91,15 +91,8 @@ signed char char_to_hex(const char c)
void
__lws_free_wsi(struct lws *wsi)
{
#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
struct lws_context_per_thread *pt;
#endif
if (!wsi)
return;
#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
pt = &wsi->context->pt[(int)wsi->tsi];
#endif
/*
* Protocol user data may be allocated either internally by lws
@ -116,35 +109,16 @@ __lws_free_wsi(struct lws *wsi)
if (wsi->vhost && wsi->vhost->lserv_wsi == wsi)
wsi->vhost->lserv_wsi = NULL;
#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
// lws_peer_dump_from_wsi(wsi);
/* we may not have an ah, but may be on the waiting list... */
lwsl_info("ah det due to close\n");
__lws_header_table_detach(wsi, 0);
{
struct allocated_headers *ah = pt->http.ah_list;
while (ah) {
if (ah->in_use && ah->wsi == wsi) {
lwsl_err("%s: ah leak: wsi %p\n", __func__, wsi);
ah->in_use = 0;
ah->wsi = NULL;
pt->http.ah_count_in_use--;
break;
}
ah = ah->next;
}
}
#endif
if (wsi->role_ops->destroy_role)
wsi->role_ops->destroy_role(wsi);
#if defined(LWS_WITH_PEER_LIMITS)
lws_peer_track_wsi_close(wsi->context, wsi->peer);
wsi->peer = NULL;
#endif
if (wsi->role_ops->destroy_role)
wsi->role_ops->destroy_role(wsi);
/* since we will destroy the wsi, make absolutely sure now */
#if defined(LWS_WITH_OPENSSL)
@ -847,8 +821,7 @@ just_kill_connection:
if (!wsi->protocol)
pro = &wsi->vhost->protocols[0];
//lwsl_notice("%s: est %d told %d cbin %d %s\n", __func__, lwsi_state_est_PRE_CLOSE(wsi), !wsi->told_user_closed,
// wsi->role_ops->close_cb[lwsi_role_server(wsi)], pro->name);
pro->callback(wsi,
wsi->role_ops->close_cb[lwsi_role_server(wsi)],
wsi->user_space, NULL, 0);

View file

@ -1527,7 +1527,10 @@ enum lws_callback_reasons {
/**< RAW mode file was adopted (equivalent to 'wsi created') */
LWS_CALLBACK_RAW_RX_FILE = 64,
/**< RAW mode file has something to read */
/**< This is the indication the RAW mode file has something to read.
* This doesn't actually do the read of the file and len is always
* 0... your code should do the read having been informed there is
* something to read now. */
LWS_CALLBACK_RAW_WRITEABLE_FILE = 65,
/**< RAW mode file is writeable */

View file

@ -199,6 +199,26 @@ lws_peer_add_wsi(struct lws_context *context, struct lws_peer *peer,
lws_context_unlock(context); /* ====================================> */
}
void
lws_peer_dump_from_wsi(struct lws *wsi)
{
struct lws_peer *peer;
if (!wsi || !wsi->peer)
return;
peer = wsi->peer;
#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
lwsl_notice("%s: wsi %p: created %llu: wsi: %d/%d, ah %d/%d\n", __func__,
wsi, (unsigned long long)peer->time_created, peer->count_wsi, peer->total_wsi,
peer->http.count_ah, peer->http.total_ah);
#else
lwsl_notice("%s: wsi %p: created %llu: wsi: %d/%d\n", __func__,
wsi, (unsigned long long)peer->time_created, peer->count_wsi, peer->total_wsi);
#endif
}
void
lws_peer_track_wsi_close(struct lws_context *context, struct lws_peer *peer)
{

View file

@ -1715,6 +1715,8 @@ lws_get_or_create_peer(struct lws_vhost *vhost, lws_sockfd_type sockfd);
void
lws_peer_add_wsi(struct lws_context *context, struct lws_peer *peer,
struct lws *wsi);
void
lws_peer_dump_from_wsi(struct lws *wsi);
#endif

View file

@ -469,6 +469,7 @@ try_pollout:
fail:
lwsl_notice("%s: fail: closing\n", __func__);
lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS, "server socket svc fail");
return LWS_HPI_RET_WSI_ALREADY_DIED;
@ -616,6 +617,32 @@ rops_alpn_negotiated_h1(struct lws *wsi, const char *alpn)
return 0;
}
static int
rops_destroy_role_h1(struct lws *wsi)
{
struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi];
struct allocated_headers *ah;
/* we may not have an ah, but may be on the waiting list... */
lwsl_info("%s: ah det due to close\n", __func__);
__lws_header_table_detach(wsi, 0);
ah = pt->http.ah_list;
while (ah) {
if (ah->in_use && ah->wsi == wsi) {
lwsl_err("%s: ah leak: wsi %p\n", __func__, wsi);
ah->in_use = 0;
ah->wsi = NULL;
pt->http.ah_count_in_use--;
break;
}
ah = ah->next;
}
return 0;
}
struct lws_role_ops role_ops_h1 = {
/* role name */ "h1",
/* alpn id */ "http/1.1",
@ -636,7 +663,7 @@ struct lws_role_ops role_ops_h1 = {
/* close_via_role_protocol */ NULL,
/* close_role */ NULL,
/* close_kill_connection */ NULL,
/* destroy_role */ NULL,
/* destroy_role */ rops_destroy_role_h1,
/* writeable cb clnt, srv */ { LWS_CALLBACK_CLIENT_HTTP_WRITEABLE,
LWS_CALLBACK_HTTP_WRITEABLE },
/* close cb clnt, srv */ { LWS_CALLBACK_CLOSED_CLIENT_HTTP,

View file

@ -503,6 +503,26 @@ rops_tx_credit_h2(struct lws *wsi)
static int
rops_destroy_role_h2(struct lws *wsi)
{
struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi];
struct allocated_headers *ah;
/* we may not have an ah, but may be on the waiting list... */
lwsl_info("%s: ah det due to close\n", __func__);
__lws_header_table_detach(wsi, 0);
ah = pt->http.ah_list;
while (ah) {
if (ah->in_use && ah->wsi == wsi) {
lwsl_err("%s: ah leak: wsi %p\n", __func__, wsi);
ah->in_use = 0;
ah->wsi = NULL;
pt->http.ah_count_in_use--;
break;
}
ah = ah->next;
}
if (wsi->upgraded_to_http2 || wsi->http2_substream) {
lws_hpack_destroy_dynamic_header(wsi);

View file

@ -1729,7 +1729,7 @@ lws_http_transaction_completed(struct lws *wsi)
return 1;
if (wsi->http.connection_type != HTTP_CONNECTION_KEEP_ALIVE) {
lwsl_info("%s: %p: close connection\n", __func__, wsi);
lwsl_notice("%s: %p: close connection\n", __func__, wsi);
return 1;
}
@ -1961,10 +1961,10 @@ lws_adopt_descriptor_vhost(struct lws_vhost *vh, lws_adoption_type type,
/* non-SSL */
if (!(type & LWS_ADOPT_HTTP)) {
if (!(type & LWS_ADOPT_SOCKET))
lws_role_transition(new_wsi, 0, LRS_UNCONNECTED,
lws_role_transition(new_wsi, 0, LRS_ESTABLISHED,
&role_ops_raw_file);
else
lws_role_transition(new_wsi, 0, LRS_UNCONNECTED,
lws_role_transition(new_wsi, 0, LRS_ESTABLISHED,
&role_ops_raw_skt);
}
#if defined(LWS_ROLE_H1)

View file

@ -54,12 +54,17 @@ rops_handle_POLLIN_raw_skt(struct lws_context_per_thread *pt, struct lws *wsi,
buffered = lws_buflist_aware_read(pt, wsi, &ebuf);
switch (ebuf.len) {
case 0:
lwsl_info("%s: read 0 len a\n",
__func__);
lwsl_info("%s: read 0 len\n", __func__);
wsi->seen_zero_length_recv = 1;
lws_change_pollfd(wsi, LWS_POLLIN, 0);
goto try_pollout;
//goto fail;
/*
* we need to go to fail here, since it's the only
* chance we get to understand that the socket has
* closed
*/
// goto try_pollout;
goto fail;
case LWS_SSL_CAPABLE_ERROR:
goto fail;
@ -127,7 +132,7 @@ try_pollout:
fail:
lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS, "raw svc fail");
return LWS_HPI_RET_PLEASE_CLOSE_ME;
return LWS_HPI_RET_WSI_ALREADY_DIED;
}

View file

@ -3,5 +3,6 @@
minimal-raw-adopt-tcp|Shows how to have lws adopt an existing tcp socket something else had connected
minimal-raw-adopt-udp|Shows how to create a udp socket and read and write on it
minimal-raw-file|Shows how to adopt a file descriptor (device node, fifo, file, etc) into the lws event loop and handle events
minimal-raw-netcat|Writes stdin to a remote server and prints results on stdout
minimal-raw-vhost|Shows how to set up a vhost that listens and accepts RAW socket connections

View file

@ -0,0 +1,76 @@
cmake_minimum_required(VERSION 2.8)
include(CheckCSourceCompiles)
set(SAMP lws-minimal-raw-netcat)
set(SRCS minimal-raw-netcat.c)
# If we are being built as part of lws, confirm current build config supports
# reqconfig, else skip building ourselves.
#
# If we are being built externally, confirm installed lws was configured to
# support reqconfig, else error out with a helpful message about the problem.
#
MACRO(require_lws_config reqconfig _val result)
if (DEFINED ${reqconfig})
if (${reqconfig})
set (rq 1)
else()
set (rq 0)
endif()
else()
set(rq 0)
endif()
if (${_val} EQUAL ${rq})
set(SAME 1)
else()
set(SAME 0)
endif()
if (LWS_WITH_MINIMAL_EXAMPLES AND NOT ${SAME})
if (${_val})
message("${SAMP}: skipping as lws being built without ${reqconfig}")
else()
message("${SAMP}: skipping as lws built with ${reqconfig}")
endif()
set(${result} 0)
else()
if (LWS_WITH_MINIMAL_EXAMPLES)
set(MET ${SAME})
else()
CHECK_C_SOURCE_COMPILES("#include <libwebsockets.h>\nint main(void) {\n#if defined(${reqconfig})\n return 0;\n#else\n fail;\n#endif\n return 0;\n}\n" HAS_${reqconfig})
if (NOT DEFINED HAS_${reqconfig} OR NOT HAS_${reqconfig})
set(HAS_${reqconfig} 0)
else()
set(HAS_${reqconfig} 1)
endif()
if ((HAS_${reqconfig} AND ${_val}) OR (NOT HAS_${reqconfig} AND NOT ${_val}))
set(MET 1)
else()
set(MET 0)
endif()
endif()
if (NOT MET)
if (${_val})
message(FATAL_ERROR "This project requires lws must have been configured with ${reqconfig}")
else()
message(FATAL_ERROR "Lws configuration of ${reqconfig} is incompatible with this project")
endif()
endif()
endif()
ENDMACRO()
set(requirements 1)
require_lws_config(LWS_WITHOUT_SERVER 0 requirements)
if (requirements)
add_executable(${SAMP} ${SRCS})
if (websockets_shared)
target_link_libraries(${SAMP} websockets_shared)
add_dependencies(${SAMP} websockets_shared)
else()
target_link_libraries(${SAMP} websockets)
endif()
endif()

View file

@ -0,0 +1,38 @@
# lws minimal raw netcat
This example shows to to create a "netcat" that copies its stdin to
a remote socket and prints what is returned in stdout.
It has some advantage over the real netcat, it will wait 1s after stdin closes
to print results that are in flight.
## build
```
$ cmake . && make
```
## usage
```
$ echo -e -n "GET / http/1.1\r\n\r\n"| ./lws-minimal-raw-netcat
[2018/05/02 08:53:53:2665] USER: LWS minimal raw netcat [--server ip] [--port port]
[2018/05/02 08:53:53:2667] NOTICE: Creating Vhost 'default' (no listener), 1 protocols, IPv6 off
[2018/05/02 08:53:53:2703] USER: Starting connect...
[2018/05/02 08:53:53:5644] USER: Connected to libwebsockets.org:80...
[2018/05/02 08:53:53:5645] USER: LWS_CALLBACK_RAW_ADOPT
[2018/05/02 08:53:53:5645] USER: LWS_CALLBACK_RAW_ADOPT_FILE
[2018/05/02 08:53:53:5646] USER: LWS_CALLBACK_RAW_RX_FILE
[2018/05/02 08:53:53:5646] USER: LWS_CALLBACK_RAW_CLOSE_FILE
[2018/05/02 08:53:53:8600] USER: LWS_CALLBACK_RAW_RX (186)
HTTP/1.1 301 Redirect
server: lwsws
Strict-Transport-Security: max-age=15768000 ; includeSubDomains
location: https://libwebsockets.org
content-type: text/html
content-length: 0
```
Note the example does everything itself, after 5s idle the remote server closes the connection
after which the example continues until you ^C it.

View file

@ -0,0 +1,254 @@
/*
* lws-minimal-raw-netcat
*
* Copyright (C) 2018 Andy Green <andy@warmcat.com>
*
* This file is made available under the Creative Commons CC0 1.0
* Universal Public Domain Dedication.
*
* This demonstrates sending stdin to a remote socket and printing
* what is returned to stdout.
*
* All the logging is on stderr, so you can tune it out with 2>log
* or whatever.
*/
#include <libwebsockets.h>
#include <string.h>
#include <signal.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <arpa/inet.h>
static struct lws *raw_wsi, *stdin_wsi;
static uint8_t buf[LWS_PRE + 4096];
static int waiting, interrupted;
static struct lws_context *context;
static int
callback_raw_test(struct lws *wsi, enum lws_callback_reasons reason,
void *user, void *in, size_t len)
{
switch (reason) {
/* callbacks related to file descriptor */
case LWS_CALLBACK_RAW_ADOPT_FILE:
lwsl_user("LWS_CALLBACK_RAW_ADOPT_FILE\n");
break;
case LWS_CALLBACK_RAW_CLOSE_FILE:
lwsl_user("LWS_CALLBACK_RAW_CLOSE_FILE\n");
/* stdin close, wait 1s then close the raw skt */
stdin_wsi = NULL; /* invalid now we close */
if (raw_wsi)
lws_set_timer_usecs(raw_wsi, LWS_USEC_PER_SEC / 10);
else {
interrupted = 1;
lws_cancel_service(context);
}
break;
case LWS_CALLBACK_RAW_RX_FILE:
lwsl_user("LWS_CALLBACK_RAW_RX_FILE\n");
waiting = read(0, buf, sizeof(buf));
lwsl_notice("raw file read %d\n", waiting);
if (waiting < 0)
return -1;
if (raw_wsi)
lws_callback_on_writable(raw_wsi);
lws_rx_flow_control(wsi, 0);
break;
/* callbacks related to raw socket descriptor */
case LWS_CALLBACK_RAW_ADOPT:
lwsl_user("LWS_CALLBACK_RAW_ADOPT\n");
lws_callback_on_writable(wsi);
break;
case LWS_CALLBACK_RAW_CLOSE:
lwsl_user("LWS_CALLBACK_RAW_CLOSE\n");
/*
* If the socket to the remote server closed, we must close
* and drop any remaining stdin
*/
interrupted = 1;
lws_cancel_service(context);
/* our pointer to this wsi is invalid now we close */
raw_wsi = NULL;
break;
case LWS_CALLBACK_RAW_RX:
lwsl_user("LWS_CALLBACK_RAW_RX (%d)\n", (int)len);
while (len--)
putchar(*((const char *)in++));
fflush(stdout);
break;
case LWS_CALLBACK_RAW_WRITEABLE:
lwsl_user("LWS_CALLBACK_RAW_WRITEABLE\n");
// lwsl_hexdump_info(buf, waiting);
if (stdin_wsi)
lws_rx_flow_control(stdin_wsi, 1);
if (lws_write(wsi, buf, waiting, LWS_WRITE_RAW) != waiting) {
lwsl_notice("%s: raw skt write failed\n", __func__);
return -1;
}
break;
case LWS_CALLBACK_TIMER:
lwsl_user("LWS_CALLBACK_TIMER\n");
interrupted = 1;
lws_cancel_service(context);
return -1;
default:
break;
}
return 0;
}
static struct lws_protocols protocols[] = {
{ "raw-test", callback_raw_test, 0, 0 },
{ NULL, NULL, 0, 0 } /* terminator */
};
void sigint_handler(int sig)
{
interrupted = 1;
}
int main(int argc, const char **argv)
{
const char *server = "libwebsockets.org", *port = "80";
struct lws_context_creation_info info;
lws_sock_file_fd_type sock;
struct addrinfo h, *r, *rp;
struct lws_vhost *vhost;
const char *p;
int n = 0, logs = LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE
/* for LLL_ verbosity above NOTICE to be built into lws,
* lws must have been configured and built with
* -DCMAKE_BUILD_TYPE=DEBUG instead of =RELEASE */
/* | LLL_INFO */ /* | LLL_PARSER */ /* | LLL_HEADER */
/* | LLL_EXT */ /* | LLL_CLIENT */ /* | LLL_LATENCY */
/* | LLL_DEBUG */;
signal(SIGINT, sigint_handler);
if ((p = lws_cmdline_option(argc, argv, "-d")))
logs = atoi(p);
lws_set_log_level(logs, NULL);
lwsl_user("LWS minimal raw netcat [--server ip] [--port port]\n");
memset(&info, 0, sizeof info); /* otherwise uninitialized garbage */
info.options = LWS_SERVER_OPTION_EXPLICIT_VHOSTS;
context = lws_create_context(&info);
if (!context) {
lwsl_err("lws init failed\n");
return 1;
}
info.port = CONTEXT_PORT_NO_LISTEN_SERVER;
info.protocols = protocols;
vhost = lws_create_vhost(context, &info);
if (!vhost) {
lwsl_err("lws vhost creation failed\n");
goto bail;
}
/*
* Connect our own "foreign" socket to libwebsockets.org:80
*
* Normally you would do this with lws_client_connect_via_info() inside
* the lws event loop, hiding all this detail. But this example
* demonstrates how to integrate an externally-connected "foreign"
* socket, so we create one by hand.
*/
memset(&h, 0, sizeof(h));
h.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
h.ai_socktype = SOCK_STREAM;
h.ai_protocol = IPPROTO_TCP;
if ((p = lws_cmdline_option(argc, argv, "--port")))
port = p;
if ((p = lws_cmdline_option(argc, argv, "--server")))
server = p;
n = getaddrinfo(server, port, &h, &r);
if (n) {
lwsl_err("%s: problem resolving %s: %s\n", __func__,
server, gai_strerror(n));
return 1;
}
for (rp = r; rp; rp = rp->ai_next) {
sock.sockfd = socket(rp->ai_family, rp->ai_socktype,
rp->ai_protocol);
if (sock.sockfd >= 0)
break;
}
if (!rp) {
lwsl_err("%s: unable to create INET socket\n", __func__);
freeaddrinfo(r);
return 1;
}
lwsl_user("Starting connect to %s:%s...\n", server, port);
if (connect(sock.sockfd, rp->ai_addr, sizeof(*rp->ai_addr)) < 0) {
lwsl_err("%s: unable to connect\n", __func__);
freeaddrinfo(r);
return 1;
}
freeaddrinfo(r);
signal(SIGINT, sigint_handler);
lwsl_user("Connected...\n");
/* our foreign socket is connected... adopt it into lws */
raw_wsi = lws_adopt_descriptor_vhost(vhost, LWS_ADOPT_SOCKET, sock,
protocols[0].name, NULL);
if (!raw_wsi) {
lwsl_err("%s: foreign socket adoption failed\n", __func__);
goto bail;
}
sock.filefd = 0;
stdin_wsi = lws_adopt_descriptor_vhost(vhost, LWS_ADOPT_RAW_FILE_DESC,
sock, protocols[0].name, NULL);
if (!stdin_wsi) {
lwsl_err("%s: stdin adoption failed\n", __func__);
goto bail;
}
while (n >= 0 && !interrupted)
n = lws_service(context, 1000);
bail:
lwsl_user("%s: destroying context\n", __func__);
lws_context_destroy(context);
return 0;
}

View file

@ -2,7 +2,11 @@
#
# attack the test server and try to make it fall over
#
# Requires the library to have been built with cmake .. -DCMAKE_BUILD_TYPE=DEBUG
# Requires the library to have been built with
#
# cmake .. -DCMAKE_BUILD_TYPE=DEBUG -DLWS_WITH_MINIMAL_EXAMPLES=1
#
# run it from the build dir
echo
echo "----------------------------------------------"
@ -19,6 +23,7 @@ INSTALLED=`dirname $A`
SHAREDIR=$INSTALLED/../share/libwebsockets-test-server
CORPUS=$SHAREDIR/test.html
LWS_NC=./bin/lws-minimal-raw-netcat
CPID=
LEN=0
@ -139,7 +144,7 @@ check
echo
echo "---- /cgi-bin/settingsjs?UPDATE_SETTINGS=1&Root_Channels_1_Channel_name_http_post=%3F&Root_Channels_1_Channel_location_http_post=%3F"
rm -f /tmp/lwscap
echo -n -e "GET /cgi-bin/settingsjs?UPDATE_SETTINGS=1&Root_Channels_1_Channel_name_http_post=%3F&Root_Channels_1_Channel_location_http_post=%3F HTTP/1.0\x0d\x0a\x0d\x0a" | nc $SERVER $PORT | sed '1,/^\r$/d'> /tmp/lwscap
echo -n -e "GET /cgi-bin/settingsjs?UPDATE_SETTINGS=1&Root_Channels_1_Channel_name_http_post=%3F&Root_Channels_1_Channel_location_http_post=%3F HTTP/1.0\x0d\x0a\x0d\x0a" | $LWS_NC --server $SERVER --port $PORT 2>/dev/null | sed '1,/^\r$/d'> /tmp/lwscap
cat /tmp/lwscap
check 1 "UPDATE_SETTINGS=1"
check 2 "Root_Channels_1_Channel_name_http_post=?"
@ -149,14 +154,14 @@ check
echo
echo "---- ? processing (/cgi-bin/settings.js?key1=value1)"
rm -f /tmp/lwscap
echo -n -e "GET /cgi-bin/settings.js?key1=value1 HTTP/1.0\x0d\x0a\x0d\x0a" | nc $SERVER $PORT | sed '1,/^\r$/d'> /tmp/lwscap
echo -n -e "GET /cgi-bin/settings.js?key1=value1 HTTP/1.0\x0d\x0a\x0d\x0a" | $LWS_NC --server $SERVER --port $PORT 2>/dev/null | sed '1,/^\r$/d'> /tmp/lwscap
check 1 "key1=value1"
check
echo
echo "---- ? processing (/t%3dest?key1%3d2=value1)"
rm -f /tmp/lwscap
echo -n -e "GET /t%3dest?key1%3d2=value1 HTTP/1.0\x0d\x0a\x0d\x0a" | nc $SERVER $PORT | sed '1,/^\r$/d'> /tmp/lwscap
echo -n -e "GET /t%3dest?key1%3d2=value1 HTTP/1.0\x0d\x0a\x0d\x0a" | $LWS_NC --server $SERVER --port $PORT 2>/dev/null | sed '1,/^\r$/d'> /tmp/lwscap
check 0 "/t=est"
check 1 "key1_2=value1"
check
@ -164,46 +169,46 @@ check
echo
echo "---- ? processing (%2f%2e%2e%2f%2e./xxtest.html?arg=1)"
rm -f /tmp/lwscap
echo -n -e "GET %2f%2e%2e%2f%2e./xxtest.html?arg=1 HTTP/1.0\x0d\x0a\x0d\x0a" | nc $SERVER $PORT | sed '1,/^\r$/d'> /tmp/lwscap
echo -n -e "GET %2f%2e%2e%2f%2e./xxtest.html?arg=1 HTTP/1.0\x0d\x0a\x0d\x0a" | $LWS_NC --server $SERVER --port $PORT 2>/dev/null | sed '1,/^\r$/d'> /tmp/lwscap
check 1 "arg=1"
check
echo
echo "---- ? processing (%2f%2e%2e%2f%2e./xxtest.html?arg=/../.)"
rm -f /tmp/lwscap
echo -n -e "GET %2f%2e%2e%2f%2e./xxtest.html?arg=/../. HTTP/1.0\x0d\x0a\x0d\x0a" | nc $SERVER $PORT | sed '1,/^\r$/d'> /tmp/lwscap
echo -n -e "GET %2f%2e%2e%2f%2e./xxtest.html?arg=/../. HTTP/1.0\x0d\x0a\x0d\x0a" | $LWS_NC --server $SERVER --port $PORT 2>/dev/null | sed '1,/^\r$/d'> /tmp/lwscap
check 1 "arg=/../."
check
echo
echo "---- spam enough crap to not be GET"
echo "not GET" | nc $SERVER $PORT
echo "not GET" | $LWS_NC --server $SERVER --port $PORT 2>/dev/null > /tmp/lwscap
check
echo
echo "---- spam more than the name buffer of crap"
dd if=/dev/urandom bs=1 count=80 2>/dev/null | nc -i1 $SERVER $PORT
dd if=/dev/urandom bs=1 count=80 2>/dev/null | $LWS_NC --server $SERVER --port $PORT 2>/dev/null > /tmp/lwscap
check
echo
echo "---- spam 10MB of crap"
dd if=/dev/urandom bs=1 count=655360 | nc -i1 $SERVER $PORT
dd if=/dev/urandom bs=1 count=655360 | $LWS_NC --server $SERVER --port $PORT 2>/dev/null > /tmp/lwscap
check
echo
echo "---- malformed URI"
echo "GET nonsense................................................................................................................" \
| nc -i1 $SERVER $PORT
| $LWS_NC --server $SERVER --port $PORT 2>/dev/null > /tmp/lwscap
check
echo
echo "---- missing URI"
echo -n -e "GET HTTP/1.0\x0d\x0a\x0d\x0a" | nc -i1 $SERVER $PORT >/tmp/lwscap
echo -n -e "GET HTTP/1.0\x0d\x0a\x0d\x0a" | $LWS_NC --server $SERVER --port $PORT 2>/dev/null >/tmp/lwscap
check
echo
echo "---- repeated method"
echo -n -e "GET blah HTTP/1.0\x0d\x0aGET blah HTTP/1.0\x0d\x0a\x0d\x0a" | nc $SERVER $PORT >/tmp/lwscap
echo -n -e "GET blah HTTP/1.0\x0d\x0aGET blah HTTP/1.0\x0d\x0a\x0d\x0a" | $LWS_NC --server $SERVER --port $PORT 2>/dev/null >/tmp/lwscap
check
echo
@ -225,7 +230,7 @@ echo -n -e "GET blah HTTP/1.0\x0d\x0a...........................................
"......................................................................................................................." \
"......................................................................................................................." \
"......................................................................................................................." \
| nc -i1 $SERVER $PORT
| $LWS_NC --server $SERVER --port $PORT 2>/dev/null
check
echo
@ -247,20 +252,20 @@ echo -n -e "GET ................................................................
"......................................................................................................................." \
"......................................................................................................................." \
"......................................................................................................................." \
| nc -i1 $SERVER $PORT
| $LWS_NC --server $SERVER --port $PORT 2>/dev/null
check
echo
echo "---- good request but http payload coming too (test.html served then forbidden)"
echo -n -e "GET /test.html HTTP/1.1\x0d\x0a\x0d\x0aILLEGAL-PAYLOAD........................................" \
| cat - /dev/zero | nc $SERVER $PORT | sed '1,/^\r$/d'> /tmp/lwscap
| $LWS_NC --server $SERVER --port $PORT 2>/dev/null | sed '1,/^\r$/d'> /tmp/lwscap
check defaultplusforbidden
check
echo
echo "---- nonexistent file"
rm -f /tmp/lwscap
echo -n -e "GET /nope HTTP/1.0\x0d\x0a\x0d\x0a" | nc $SERVER $PORT | sed '1,/^\r$/d'> /tmp/lwscap
echo -n -e "GET /nope HTTP/1.0\x0d\x0a\x0d\x0a" | $LWS_NC --server $SERVER --port $PORT 2>/dev/null | sed '1,/^\r$/d'> /tmp/lwscap
cat /tmp/lwscap
check notfound
check
@ -268,63 +273,63 @@ check
echo
echo "---- relative uri path"
rm -f /tmp/lwscap
echo -n -e "GET nope HTTP/1.0\x0d\x0a\x0d\x0a" | nc $SERVER $PORT | sed '1,/^\r$/d'> /tmp/lwscap
echo -n -e "GET nope HTTP/1.0\x0d\x0a\x0d\x0a" | $LWS_NC --server $SERVER --port $PORT 2>/dev/null | sed '1,/^\r$/d'> /tmp/lwscap
check forbidden
check
echo
echo "---- directory attack 1 (/../../../../etc/passwd should be /etc/passswd)"
rm -f /tmp/lwscap
echo -n -e "GET /../../../../etc/passwd HTTP/1.0\x0d\x0a\x0d\x0a" | nc $SERVER $PORT | sed '1,/^\r$/d'> /tmp/lwscap
echo -n -e "GET /../../../../etc/passwd HTTP/1.0\x0d\x0a\x0d\x0a" | $LWS_NC --server $SERVER --port $PORT 2>/dev/null | sed '1,/^\r$/d'> /tmp/lwscap
check notfound
check
echo
echo "---- directory attack 2 (/../ should be /)"
rm -f /tmp/lwscap
echo -e -n "GET /../ HTTP/1.0\x0d\x0a\x0d\x0a" | nc $SERVER $PORT | sed '1,/^\r$/d'> /tmp/lwscap
echo -e -n "GET /../ HTTP/1.0\x0d\x0a\x0d\x0a" | $LWS_NC --server $SERVER --port $PORT 2>/dev/null | sed '1,/^\r$/d'> /tmp/lwscap
check default
check
echo
echo "---- directory attack 3 (/./ should be /)"
rm -f /tmp/lwscap
echo -e -n "GET /./ HTTP/1.0\x0d\x0a\x0d\x0a" | nc $SERVER $PORT | sed '1,/^\r$/d'> /tmp/lwscap
echo -e -n "GET /./ HTTP/1.0\x0d\x0a\x0d\x0a" | $LWS_NC --server $SERVER --port $PORT 2>/dev/null | sed '1,/^\r$/d'> /tmp/lwscap
check default
check
echo
echo "---- directory attack 4 (/blah/.. should be /)"
rm -f /tmp/lwscap
echo -e -n "GET /blah/.. HTTP/1.0\x0d\x0a\x0d\x0a" | nc $SERVER $PORT | sed '1,/^\r$/d'> /tmp/lwscap
echo -e -n "GET /blah/.. HTTP/1.0\x0d\x0a\x0d\x0a" | $LWS_NC --server $SERVER --port $PORT 2>/dev/null | sed '1,/^\r$/d'> /tmp/lwscap
check default
check
echo
echo "---- directory attack 5 (/blah/../ should be /)"
rm -f /tmp/lwscap
echo -e -n "GET /blah/../ HTTP/1.0\x0d\x0a\x0d\x0a" | nc $SERVER $PORT | sed '1,/^\r$/d'> /tmp/lwscap
echo -e -n "GET /blah/../ HTTP/1.0\x0d\x0a\x0d\x0a" | $LWS_NC --server $SERVER --port $PORT 2>/dev/null | sed '1,/^\r$/d'> /tmp/lwscap
check default
check
echo
echo "---- directory attack 6 (/blah/../. should be /)"
rm -f /tmp/lwscap
echo -e -n "GET /blah/../. HTTP/1.0\x0d\x0a\x0d\x0a" | nc $SERVER $PORT | sed '1,/^\r$/d'> /tmp/lwscap
echo -e -n "GET /blah/../. HTTP/1.0\x0d\x0a\x0d\x0a" | $LWS_NC --server $SERVER --port $PORT 2>/dev/null | sed '1,/^\r$/d'> /tmp/lwscap
check default
check
echo
echo "---- directory attack 7 (/%2e%2e%2f../../../etc/passwd should be /etc/passswd)"
rm -f /tmp/lwscap
echo -e -n "GET /%2e%2e%2f../../../etc/passwd HTTP/1.0\x0d\x0a\x0d\x0a" | nc $SERVER $PORT | sed '1,/^\r$/d'> /tmp/lwscap
echo -e -n "GET /%2e%2e%2f../../../etc/passwd HTTP/1.0\x0d\x0a\x0d\x0a" | $LWS_NC --server $SERVER --port $PORT 2>/dev/null | sed '1,/^\r$/d'> /tmp/lwscap
check notfound
check
echo
echo "---- directory attack 8 (%2f%2e%2e%2f%2e./.%2e/.%2e%2fetc/passwd should be /etc/passswd)"
rm -f /tmp/lwscap
echo -e -n "GET %2f%2e%2e%2f%2e./.%2e/.%2e%2fetc/passwd HTTP/1.0\x0d\x0a\x0d\x0a" | nc $SERVER $PORT | sed '1,/^\r$/d'> /tmp/lwscap
echo -e -n "GET %2f%2e%2e%2f%2e./.%2e/.%2e%2fetc/passwd HTTP/1.0\x0d\x0a\x0d\x0a" | $LWS_NC --server $SERVER --port $PORT 2>/dev/null | sed '1,/^\r$/d'> /tmp/lwscap
check notfound
check
@ -550,8 +555,9 @@ for i in \
/path/to/dir/../other/dir \
; do
R=`rm -f /tmp/lwscap ; echo -n -e "GET $i HTTP/1.0\r\n\r\n" | nc localhost 7681 2>/dev/null >/tmp/lwscap; head -n1 /tmp/lwscap| cut -d' ' -f2`
R=`rm -f /tmp/lwscap ; echo -n -e "GET $i HTTP/1.0\r\n\r\n" | $LWS_NC --server $SERVER --port $PORT 2>/dev/null > /tmp/lwscap; head -n1 /tmp/lwscap| cut -d' ' -f2`
#cat $LOG
#echo ==== $R