Skip to content

Commit

Permalink
Finishing SWF refactoring...but maybe breaking JS payload capacity?
Browse files Browse the repository at this point in the history
  • Loading branch information
BaronWolfenstein committed May 25, 2014
1 parent ee1f957 commit 8a58a31
Show file tree
Hide file tree
Showing 11 changed files with 141 additions and 171 deletions.
2 changes: 1 addition & 1 deletion COPYING
2 changes: 1 addition & 1 deletion INSTALL
2 changes: 1 addition & 1 deletion Makefile.am
Expand Up @@ -11,7 +11,7 @@ AM_CXXFLAGS = -Werror -Wall -Wextra -Wno-missing-field-initializers -Wformat=2 -
AM_CPPFLAGS = -I. -I$(srcdir)/src -I$(srcdir)/src/steg -I$(srcdir)/src/steg/http_steg_mods $(lib_CPPFLAGS) -I$(srcdir)/src/test/gtest -I$(srcdir)/src/test/gtest/include

noinst_LIBRARIES = libstegotorus.a
noinst_PROGRAMS = unittests g_unittests tltester tester_proxy webpage_tester
noinst_PROGRAMS = unittests tltester tester_proxy webpage_tester
bin_PROGRAMS = stegotorus

PROTOCOLS = \
Expand Down
2 changes: 1 addition & 1 deletion config-aux/depcomp
2 changes: 1 addition & 1 deletion config-aux/install-sh
2 changes: 1 addition & 1 deletion config-aux/missing
13 changes: 7 additions & 6 deletions src/steg/http.cc
Expand Up @@ -65,6 +65,7 @@ void http_steg_config_t::init_file_steg_mods()
file_steg_mods[HTTP_CONTENT_JPEG] = new JPGSteg(payload_server, noise2signal);
file_steg_mods[HTTP_CONTENT_PNG] = new PNGSteg(payload_server, noise2signal);
file_steg_mods[HTTP_CONTENT_GIF] = new GIFSteg(payload_server, noise2signal);
file_steg_mods[HTTP_CONTENT_SWF] = new SWFSteg(payload_server, noise2signal);

}
http_steg_config_t::http_steg_config_t(config_t *cfg)
Expand Down Expand Up @@ -558,9 +559,9 @@ http_steg_t::transmit(struct evbuffer *source)
int rval = -1;
switch(type) {

case HTTP_CONTENT_SWF:
rval = http_server_SWF_transmit(config->payload_server, source, conn);
break;
//case HTTP_CONTENT_SWF:

This comment has been minimized.

Copy link
@vmon

vmon May 27, 2014

Contributor

Don't be shy, delete lines, git will keep record if we need to go back.

// rval = http_server_SWF_transmit(config->payload_server, source, conn);
// break;

case HTTP_CONTENT_JAVASCRIPT:
rval = http_server_JS_transmit(config->payload_server, source, conn, HTTP_CONTENT_JAVASCRIPT);
Expand Down Expand Up @@ -693,9 +694,9 @@ http_steg_t::http_client_receive(evbuffer *source, evbuffer *dest)
log_debug(conn, "sur1.5.1");

switch(type) {
case HTTP_CONTENT_SWF:
rval = http_handle_client_SWF_receive(this, conn, dest, source);
break;
//case HTTP_CONTENT_SWF:
//rval = http_handle_client_SWF_receive(this, conn, dest, source);
//break;

case HTTP_CONTENT_JAVASCRIPT:
case HTTP_CONTENT_HTML:
Expand Down
217 changes: 71 additions & 146 deletions src/steg/http_steg_mods/swfSteg.cc
Expand Up @@ -3,11 +3,14 @@
*/
#include "util.h"
#include "../payload_server.h"
#include "file_steg.h"
#include "swfSteg.h"
#include "compression.h"
#include "connections.h"


#include <event2/buffer.h>
#include <assert.h>

static const char http_response_1[] =
"HTTP/1.1 200 OK\r\n"
Expand All @@ -17,17 +20,16 @@ static const char http_response_1[] =
"Content-Type: application/x-shockwave-flash\r\n"
"Content-Length: ";

unsigned int
swf_wrap(PayloadServer* pl, char* inbuf, int in_len, char* outbuf, int out_sz) {
//unsigned int
//swf_wrap(PayloadServer* pl, char* inbuf, int in_len, char* outbuf, int out_sz) {
int SWFSteg::encode(uint8_t* data, size_t data_len, uint8_t* cover_payload, size_t cover_len) {

char* swf;
int in_swf_len;


char* tmp_buf;
int out_swf_len;

char* resp;
int resp_len;


char hdr[512];
unsigned int hdr_len;
Expand All @@ -36,47 +38,41 @@ swf_wrap(PayloadServer* pl, char* inbuf, int in_len, char* outbuf, int out_sz) {



if (!pl->get_payload(HTTP_CONTENT_SWF, -1, &resp, &resp_len)) {

This comment has been minimized.

Copy link
@BaronWolfenstein

BaronWolfenstein May 31, 2014

Author Contributor

Should this be added back to file_steg?

log_warn("swfsteg: no suitable payload found\n");
return -1;
}

swf = strstr(resp, "\r\n\r\n") + 4;
in_swf_len = resp_len - (swf - resp);


if (headless_capacity((char*)cover_payload, cover_len) < (int) data_len) {

log_warn("not enough cover capacity to embed data");


if (out_sz - in_len < (SWF_SAVE_FOOTER_LEN + SWF_SAVE_HEADER_LEN + 8 + 512)) {

This comment has been minimized.

Copy link
@vmon

vmon May 27, 2014

Contributor

I think it is good to keep this output buffer size check. It is part of hardening the code.

Just out_sz doesn't mean much because we can be as big as c_HTTP_MSG_BUF_SIZE, so compare with this instead

This comment has been minimized.

Copy link
@BaronWolfenstein

BaronWolfenstein Jun 3, 2014

Author Contributor

OK I'll add it back

fprintf(stderr, "swfsteg: outbuf too small %d \n", out_sz - in_len);
return -1; //not enough capacity is an error because you should have check

log_warn("swfsteg: outbuf too small\n");
return -1;
//before requesting
}


tmp_buf = (char *)xmalloc(in_len + SWF_SAVE_HEADER_LEN + SWF_SAVE_FOOTER_LEN);
tmp_buf2 = (char *)xmalloc(in_len + SWF_SAVE_HEADER_LEN + SWF_SAVE_FOOTER_LEN + 512);
tmp_buf = (char *)xmalloc(data_len + SWF_SAVE_HEADER_LEN + SWF_SAVE_FOOTER_LEN);
tmp_buf2 = (char *)xmalloc(data_len + SWF_SAVE_HEADER_LEN + SWF_SAVE_FOOTER_LEN + 512);

memcpy(tmp_buf, swf+8, SWF_SAVE_HEADER_LEN);
memcpy(tmp_buf+SWF_SAVE_HEADER_LEN, inbuf, in_len);
memcpy(tmp_buf+SWF_SAVE_HEADER_LEN+in_len, swf + in_swf_len - SWF_SAVE_FOOTER_LEN, SWF_SAVE_FOOTER_LEN);
memcpy(tmp_buf, cover_payload + extract_appropriate_respones_body((evbuffer*)cover_payload) + 4+8, SWF_SAVE_HEADER_LEN); //why is 8 hardcoded? 4 is from former swf variable.

This comment has been minimized.

Copy link
@vmon

vmon May 27, 2014

Contributor

You don't need to skip the header, the cover_payload that comes to encode is headless (doesn't contain the http response header, it is just the file) so basically there is nothing to extract because it is all body. That is why we call headless_capacity instead of capacity function to find out about the capacity of the payload.

But I'm curious to know why did you write it this way.

We also don't need to store the data length, because the HEADER and FOOTER have constant length, anything else is our datat.

I don't know what that swf + 8 is coming from

Ok it's the compressed length that should be stored there, but it is funny not to copy everything and then overwrite it

memcpy(tmp_buf+SWF_SAVE_HEADER_LEN, data, data_len);
memcpy(tmp_buf+SWF_SAVE_HEADER_LEN+data_len, cover_payload+ extract_appropriate_respones_body((char*)cover_payload, cover_len) - SWF_SAVE_FOOTER_LEN, SWF_SAVE_FOOTER_LEN);

This comment has been minimized.

Copy link
@vmon

vmon May 27, 2014

Contributor

same here, don't extract, it is already extracted.

out_swf_len =
compress((const uint8_t *)tmp_buf,
SWF_SAVE_HEADER_LEN + in_len + SWF_SAVE_FOOTER_LEN,

This comment has been minimized.

Copy link
@BaronWolfenstein

BaronWolfenstein Jun 4, 2014

Author Contributor

int in_len -> size_t data_len? Problems?

SWF_SAVE_HEADER_LEN + data_len + SWF_SAVE_FOOTER_LEN,
(uint8_t *)tmp_buf2+8,
in_len + SWF_SAVE_HEADER_LEN + SWF_SAVE_FOOTER_LEN + 512-8,
data_len + SWF_SAVE_HEADER_LEN + SWF_SAVE_FOOTER_LEN + 512-8,
c_format_zlib);

hdr_len = gen_response_header((char*) "application/x-shockwave-flash", 0, out_swf_len + 8, hdr, sizeof(hdr));

// fprintf(stderr, "hdr = %s\n", hdr);

memcpy(tmp_buf2, swf, 4);
memcpy(tmp_buf2, cover_payload, 4);
((int*) (tmp_buf2))[1] = out_swf_len;

memcpy(outbuf, hdr, hdr_len);
memcpy(outbuf+hdr_len, tmp_buf2, out_swf_len + 8);
memcpy(data, hdr, hdr_len);
memcpy(data+hdr_len, tmp_buf2, out_swf_len + 8);

free(tmp_buf);
free(tmp_buf2);
Expand All @@ -86,15 +82,14 @@ swf_wrap(PayloadServer* pl, char* inbuf, int in_len, char* outbuf, int out_sz) {



unsigned int
swf_unwrap(char* inbuf, int in_len, char* outbuf, int out_sz)
ssize_t SWFSteg::decode(const uint8_t *cover_payload, size_t cover_len, uint8_t* data)
{
int inf_len;
size_t tmp_len = in_len * 32;
size_t tmp_len = cover_len * 32; //asset later?
char* tmp_buf = (char *)xmalloc(tmp_len);

This comment has been minimized.

Copy link
@vmon

vmon May 27, 2014

Contributor

so no assert needed on xmalloc, it kills the program on failure right away.


for (;;) {
inf_len = decompress((const uint8_t *)inbuf + 8, in_len - 8,
inf_len = decompress(cover_payload + 8, cover_len - 8,
(uint8_t *)tmp_buf, tmp_len);
if (inf_len != -2)
break;
Expand All @@ -103,140 +98,70 @@ swf_unwrap(char* inbuf, int in_len, char* outbuf, int out_sz)
}

if (inf_len < 0 ||
out_sz < inf_len - SWF_SAVE_HEADER_LEN - SWF_SAVE_FOOTER_LEN) {
sizeof(data) < c_HTTP_MSG_BUF_SIZE) {

This comment has been minimized.

Copy link
@vmon

vmon May 27, 2014

Contributor

you already figured this out :)

fprintf(stderr, "inf_len = %d\n", inf_len);
free(tmp_buf);
return -1;
}

memcpy(outbuf, tmp_buf + SWF_SAVE_HEADER_LEN,
memcpy(data, tmp_buf + SWF_SAVE_HEADER_LEN,
inf_len - SWF_SAVE_HEADER_LEN - SWF_SAVE_FOOTER_LEN);
return inf_len - SWF_SAVE_HEADER_LEN - SWF_SAVE_FOOTER_LEN;
}

int
http_server_SWF_transmit(PayloadServer* pl, struct evbuffer *source, conn_t *conn)
{

struct evbuffer *dest = conn->outbound();
size_t sbuflen = evbuffer_get_length(source);
char* inbuf;
char* outbuf;
int outlen;

inbuf = (char *)xmalloc(sbuflen);

if (evbuffer_remove(source, inbuf, sbuflen) == -1) {
log_debug("evbuffer_remove failed in http_server_SWF_transmit");
return -1;
}

outbuf = (char *)xmalloc(4*sbuflen + SWF_SAVE_FOOTER_LEN + SWF_SAVE_HEADER_LEN + 512);

// fprintf(stderr, "server wrapping swf len %d\n", (int) sbuflen);
outlen = swf_wrap(pl, inbuf, sbuflen, outbuf, 4*sbuflen + SWF_SAVE_FOOTER_LEN + SWF_SAVE_HEADER_LEN + 512);

if (outlen < 0) {
log_warn("swf_wrap failed\n");
// fprintf(stderr, "swf_wrap failed\n");
free(inbuf);
free(outbuf);
return -1;
}


if (evbuffer_add(dest, outbuf, outlen)) {
log_debug("SERVER ERROR: http_server_transmit: evbuffer_add() fails for jsTemplate");
free(inbuf);
free(outbuf);
return -1;
}
tmp_len= inf_len - SWF_SAVE_HEADER_LEN - SWF_SAVE_FOOTER_LEN; //reassigned to existing variable

free(inbuf);
free(outbuf);
return 0;
return (ssize_t)tmp_len; //added for new return type
}

ssize_t SWFSteg::headless_capacity(char *cover_body, int body_length)
{
return static_headless_capacity((char*)cover_body, body_length);
}

/**
compute the capcaity of the cover by getting a pointer to the
beginig of the body in the response
@param cover_body pointer to the begiing of the body
@param body_length the total length of message body
*/
unsigned int SWFSteg::static_headless_capacity(char *cover_body, int body_length)
{


if (body_length <= 0)
return 0;

(void)cover_body; //to get around warning

This comment has been minimized.

Copy link
@vmon

vmon May 27, 2014

Contributor

Delete these if you don't need them

//int from = starting_point((uint8_t*)cover_body, (size_t)body_length);
//if (from < 0) //invalid format
//return 0;

ssize_t hypothetical_capacity = ((ssize_t)body_length) - (SWF_SAVE_FOOTER_LEN + SWF_SAVE_HEADER_LEN + 8 + 512);

int
http_handle_client_SWF_receive(steg_t *, conn_t *conn, struct evbuffer *dest, struct evbuffer* source) {
struct evbuffer_ptr s2;
unsigned int response_len = 0, hdrLen;
char outbuf[HTTP_MSG_BUF_SIZE];
int content_len = 0, outbuflen;
char *httpHdr, *httpBody;



s2 = evbuffer_search(source, "\r\n\r\n", sizeof ("\r\n\r\n") -1 , NULL);
if (s2.pos == -1) {
log_warn("CLIENT Did not find end of HTTP header %d", (int) evbuffer_get_length(source));
fprintf(stderr, "client did not find end of HTTP header\n");

// evbuffer_dump(source, stderr);
return RECV_INCOMPLETE;
}

log_debug("CLIENT received response header with len %d", (int)s2.pos);

response_len = 0;
hdrLen = s2.pos + strlen("\r\n\r\n");
response_len += hdrLen;

httpHdr = (char *) evbuffer_pullup(source, s2.pos);
if (httpHdr == NULL) {
log_warn("CLIENT unable to pullup the complete HTTP header");
return RECV_BAD;
}

content_len = find_content_length(httpHdr, hdrLen);



if (content_len < 0) {
log_warn("CLIENT unable to find content length");
return RECV_BAD;
}
log_debug("CLIENT received Content-Length = %d\n", content_len);



response_len += content_len;

if (response_len > evbuffer_get_length(source))
return RECV_INCOMPLETE;


return max(hypothetical_capacity, (ssize_t)0);

httpHdr = (char *) evbuffer_pullup(source, response_len);
httpBody = httpHdr + hdrLen;
}

ssize_t SWFSteg::capacity(const uint8_t *cover_payload, size_t len)
{
return static_capacity((char*)cover_payload, len);
}

outbuflen = swf_unwrap(httpBody, content_len, outbuf, HTTP_MSG_BUF_SIZE);
//Temp: should get rid of ASAP
unsigned int SWFSteg::static_capacity(char *cover_payload, int len)
{
ssize_t body_offset = extract_appropriate_respones_body(cover_payload, len);
if (body_offset == -1) //couldn't find the end of header
return 0; //useless payload

return static_headless_capacity(cover_payload + body_offset, len - body_offset);
}

if (outbuflen < 0) {
fprintf(stderr, "swf_unwrap failed\n");
log_debug("CLIENT ERROR: swf_unwrap failed\n");
return RECV_BAD;
}

// fprintf(stderr, "CLIENT unwrapped data of length %d:", outbuflen);
// buf_dump(outbuf, outbuflen, stderr);

if (evbuffer_add(dest, outbuf, outbuflen)) {
log_debug("CLIENT ERROR: evbuffer_add to dest fails\n");
return RECV_BAD;
}
SWFSteg::SWFSteg(PayloadServer* payload_provider, double noise2signal)
:FileStegMod(payload_provider, noise2signal, HTTP_CONTENT_SWF)

// log_debug("Drained source for %d char\n", response_len);
if (evbuffer_drain(source, response_len) == -1) {
log_debug("CLIENT ERROR: failed to drain source\n");
return RECV_BAD;
}
{

// downcast_steg(s)->have_received = 1;
conn->expect_close();
return RECV_GOOD;
}

1 comment on commit 8a58a31

@vmon
Copy link
Contributor

@vmon vmon commented on 8a58a31 May 27, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

overl looks good. it should work IMHO except for those extra extract_body. Thanks.

Please sign in to comment.