#!/usr/bin/perl use strict; #---------------------------------------------------- # unchunk.pl - HTTP Chunked Response Decoder # Created: 02MAY10 # Programmer: dn1nj4 at shadowserver dot org # Purpose: Takes reassembled Chunked Encoded HTTP # responses and decodes them # Usage: perl unchunk.pl input_file output_file #---------------------------------------------------- # REV: #---------------------------------------------------- # #---------------------------------------------------- # GLOBALS #---------------------------------------------------- #---------------------------------------------------- # SUBS #---------------------------------------------------- #---------------------------------------------------- # MAIN #---------------------------------------------------- my $infile = shift; my $outfile = shift; my $byte = ""; my $last = ""; my $next_chunk = ""; my $final = ""; # Read the entire input file into memory open(INFILE,"<$infile"); binmode(INFILE); undef $/; my $buffer = ; # Scan for the first \x0d0a0d0a, signifying the end of the HTTP headers. my $prev_crlf = index($buffer,"\x0d\x0a\x0d\x0a") + 4; # Starting from the end of the HTTP headers, find the next \x0d0a. my $next_crlf = index($buffer,"\x0d\x0a",$prev_crlf)+2; # Through the rest of the file, get the chunk size, add that data to the # reconstructed buffer. while ($next_crlf > 1) { # The chunk size is going to be ASCII text representing the number of bytes # in this particular chunk. The chunk size is bound on either side by # \x0d0a. my $chunk_size = substr($buffer,$prev_crlf,$prev_crlf-$next_crlf-2); print "Reading " . hex($chunk_size) . " bytes from stream position $next_crlf.\n"; # Cut $chunk_size of data from the stream and append it to the reassembled # data buffer. $final .= substr($buffer,$next_crlf,hex($chunk_size)); # Calculate the starting point for the next chunk size. $prev_crlf = $next_crlf+2+hex($chunk_size); # Find the next \x0d\x0a. $next_crlf = index($buffer,"\x0d\x0a",$prev_crlf)+2; } open(OUTFILE,">$outfile"); binmode(OUTFILE); print OUTFILE $final; close(OUTFILE);