Created
September 17, 2015 22:30
-
-
Save sh1n0b1/a4756afff5b6ab59441b to your computer and use it in GitHub Desktop.
pcap SSL packet dump for Wireshark to decrypt - https://supportforums.cisco.com/blog/154046
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl | |
#Author: Michal Garcarz @ cisco.com | |
#Date: 15.01.2013 | |
use Net::Frame::Simple; | |
use Net::Frame::Dump::Offline; | |
use Net::Frame::Layer::TCP; | |
use Net::Frame::Layer; | |
use Net::Frame::Layer::IPv4; | |
use Net::Frame::Dump::Writer; | |
use Net::Frame::IPv4; | |
use Net::Frame::Layer::ETH; | |
use Net::Frame::ETH; | |
use NetPacket::Ethernet; | |
my $DESTINATION_PCAP_FILE="ssl.pcap"; #result: SSL packets inside TCP | |
my $SOURCE_PCAP_FILE="eap-ssl.pcap"; #SSL packets inside other protocols | |
my $CLIENT_MAC="aa:aa:aa:aa:aa:aa"; | |
my $SERVER_MAC="aa:aa:aa:bb:bb:bb"; | |
my $CLIENT_IP="1.1.1.1"; | |
my $SERVER_IP="2.2.2.2"; | |
my $CLIENT_PORT=Net::Frame::Layer::TCP->getRandomHighPort(); | |
my $SERVER_PORT="443"; | |
my $CLIENT_SEQ=Net::Frame::Layer::TCP->getRandom32bitsInt(); | |
my $SERVER_SEQ=Net::Frame::Layer::TCP->getRandom32bitsInt(); | |
my $original_client_mac; | |
my $original_server_mac; | |
my $oDump = Net::Frame::Dump::Offline->new( | |
file => $SOURCE_PCAP_FILE, | |
filter => '', | |
isRunning => 0, | |
keepTimestamp => 0, | |
); | |
$oDump->start; | |
my $count = 1; | |
while (my $h = $oDump->next) { | |
my $f = Net::Frame::Simple->new( | |
raw => $h->{raw}, | |
firstLayer => $h->{firstLayer}, | |
timestamp => $h->{timestamp}, | |
); | |
my $len = length($h->{raw}); | |
print 'Frame number: '.$count." (length: $len)\n"; | |
#print 'Frame number: '.$count." RAW: ".$h->{raw}."\n"; | |
#searching for SSL | |
my $dump = $f->dump; | |
my $sslmarker1 = "16030100"; | |
my $sslmarker2 = "17030100"; | |
if ($dump =~ /.*$sslmarker1.*/ || $dump =~ /.*$sskmarker2.*/){ | |
print "Frame NUMBER $count SSL FOUND, preparing SSL payload and crafting TCP packet\n"; | |
$dump = $h->{raw}; | |
my $is16 = 0; | |
my $is17 = 0; | |
my $is14 = 0; | |
my $is14_offset=9999; | |
my $is16_offset=9999; | |
my $is17_offset=9999; | |
if ($dump =~ /\x14\x03\x01\x00\x01\x01\x16/){ | |
$is14 = 1; | |
$is14_offset = index($dump, "\x14\x03\x01\x00"); | |
} | |
if ($dump =~ /\x17\x03\x01\x00/){ | |
$is17 = 1; | |
$is17_offset = index($dump, "\x17\x03\x01\x00"); | |
} | |
if ($dump =~ /\x16\x03\x01\x00/){ | |
$is16 = 1; | |
$is16_offset = index($dump, "\x16\x03\x01\x00"); | |
} | |
#if first(index) is16 and then is14 to is16 | |
#if first(index) is14 and then is16 to is14 | |
#if is16 but not at the end then 16 | |
#if is17 then 17 | |
#else then frag | |
if ($is16==1 && $is14==1 && $is16_offset<$is14_offset){ | |
($payload = $dump) =~ s/^.*?(?=\x16\x03\x01\x00)//; | |
} | |
elsif ($is16==1 && $is14==1 && $is16_offset>$is14_offset){ | |
($payload = $dump) =~ s/^.*?(?=\x14\x03\x01\x00)//; | |
} | |
elsif ($is16==1 && $is16_offset+15<$len){ | |
($payload = $dump) =~ s/^.*?(?=\x16\x03\x01\x00)//; | |
} | |
elsif ($is17==1){ | |
($payload = $dump) =~ s/^.*?(?=\x17\x03\x01\x00)//; | |
} | |
else{ | |
($payload = $dump) =~ s/^.*?(?=\x19\x00)//; | |
($payload = $payload) =~ s/^\x19\x00//; | |
} | |
if ($count==1){ | |
#first packet, initiate handshaking | |
InitiateHandShaking(); | |
my $eth_obj = NetPacket::Ethernet->decode($h->{raw}); | |
#decode client/server mac address and track it | |
$original_client_mac = $eth_obj->{src_mac}; | |
$original_server_mac = $eth_obj->{dest_mac}; | |
print "Client mac:".$original_client_mac." server mac: ".$original_server_mac."\n"; | |
} | |
$eth_obj = NetPacket::Ethernet->decode($h->{raw}); | |
$current_client_mac = $eth_obj->{src_mac}; | |
$current_server_mac = $eth_obj->{dest_mac}; | |
if ( $current_client_mac =~ $original_client_mac){ | |
#packet from client to server | |
my $packet = PreparePacket($CLIENT_MAC,$SERVER_MAC,$CLIENT_IP,$SERVER_IP,$CLIENT_PORT, | |
$SERVER_PORT,$CLIENT_SEQ,$SERVER_SEQ,Net::Frame::Layer::TCP->NF_TCP_FLAGS_ACK,$payload); | |
WritePacket($packet); | |
$CLIENT_SEQ += length($payload); | |
} | |
else{ | |
#packet from server to client | |
my $packet = PreparePacket($SERVER_MAC,$CLIENT_MAC,$SERVER_IP,$CLIENT_IP,$SERVER_PORT, | |
$CLIENT_PORT,$SERVER_SEQ,$CLIENT_SEQ,Net::Frame::Layer::TCP->NF_TCP_FLAGS_ACK,$payload); | |
WritePacket($packet); | |
$SERVER_SEQ += length($payload); | |
} | |
break; | |
} | |
$count++; | |
} | |
$oDump->stop; | |
#END OF MAIN | |
sub PreparePacket | |
{ | |
my $eth_src = shift; | |
my $eth_dst = shift; | |
my $ip_src = shift; | |
my $ip_dst = shift; | |
my $port_src = shift; | |
my $port_dst = shift; | |
my $seq_src = shift; | |
my $seq_dst = shift; | |
my $flag = shift; | |
my $tcp_payload = shift; | |
my $tcplayer = Net::Frame::Layer::TCP->new( | |
src => $port_src, | |
dst => $port_dst, | |
seq => $seq_src, | |
ack => $seq_dst, | |
x2 => 0, | |
off => 0, | |
flags => $flag, | |
win => 0xffff, | |
checksum => 0, | |
urp => 0, | |
options => '', | |
payload => $tcp_payload, | |
); | |
my $iplayer = Net::Frame::Layer::IPv4->new( | |
version => 4, | |
tos => 0, | |
id => Net::Frame::Layer::IPv4->getRandom16bitsInt(), | |
length => Net::Frame::Layer::IPv4->NF_IPv4_HDR_LEN, | |
hlen => 0, | |
flags => 0, | |
offset => 0, | |
ttl => 128, | |
protocol => Net::Frame::Layer::IPv4->NF_IPv4_PROTOCOL_TCP, | |
checksum => 0, | |
src => $ip_src, | |
dst => $ip_dst, | |
options => '', | |
noFixLen => 0, | |
); | |
my $ethlayer = Net::Frame::Layer::ETH->new( | |
dst => $eth_dst, | |
src => $eth_src, | |
type => Net::Frame::Layer::ETH->NF_ETH_TYPE_IPv4, | |
); | |
my $packet = Net::Frame::Simple->new(layers=> | |
[ $ethlayer, $iplayer, $tcplayer ] | |
); | |
return $packet; | |
} | |
sub WritePacket | |
{ | |
my $packet = shift; | |
my $data = $packet->pack; | |
my $oDump = Net::Frame::Dump::Writer->new( | |
file => $DESTINATION_PCAP_FILE, | |
firstLayer => 'ETH', | |
overwrite => 'YES', | |
append => 'YES', | |
); | |
$oDump->start; | |
$oDump->write({ timestamp => '10.10', raw => $data }); | |
$oDump->stop; | |
} | |
sub InitiateHandShaking | |
{ | |
#SYN | |
my $packet = PreparePacket($CLIENT_MAC,$SERVER_MAC,$CLIENT_IP,$SERVER_IP,$CLIENT_PORT, | |
$SERVER_PORT,$CLIENT_SEQ++,0,Net::Frame::Layer::TCP->NF_TCP_FLAGS_SYN,""); | |
WritePacket($packet); | |
#SYN/ACK | |
$packet = PreparePacket($SERVER_MAC,$CLIENT_MAC,$SERVER_IP,$CLIENT_IP,$SERVER_PORT, | |
$CLIENT_PORT,$SERVER_SEQ++,$CLIENT_SEQ,Net::Frame::Layer::TCP->NF_TCP_FLAGS_SYN|Net::Frame::Layer::TCP->NF_TCP_FLAGS_ACK,""); | |
WritePacket($packet); | |
#ACK | |
$packet = PreparePacket($CLIENT_MAC,$SERVER_MAC,$CLIENT_IP,$SERVER_IP,$CLIENT_PORT, | |
$SERVER_PORT,$CLIENT_SEQ,$SERVER_SEQ,Net::Frame::Layer::TCP->NF_TCP_FLAGS_ACK,""); | |
WritePacket($packet); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment