在Perl中发送伪造的系统日志消息

时间:2018-06-27 11:39:16

标签: perl sockets

TL; DR我正在尝试使用欺骗性的源IP将已经创建的syslog消息发送到syslog服务器,但我为此感到非常困难,可以采用简洁的方法 < / p>

有关syslog的大多数问题都不包含欺骗性的IP问题,因此我要重新询问。

我正在写(很好地更新)我很久以前写的一个脚本,该脚本生成欺骗的syslog消息(使用UDP)。它当前使用Net :: RawIP,它对可移植性很糟糕,而且我很久以前编写的传输代码已经决定停止在Perl 5中工作(我已经很长时间没有使用它了,我正在刷新它)。多年来,我一直在意摆脱Net :: RawIP,但这是我唯一会使用的方法!

鉴于我必须对其进行修复,因此我现在可能有一点时间想使用Socket功能,这就是我一直在使用的功能-使用SO或gist或我可以找到的其他地方的代码-而不是类似IO :: Socket之类的东西,因为我需要具有欺骗性的IPs权限,因为它具有较低的写套接字能力。

但是,我对此一直束手无策,现在我从头开始形成数据包,然后创建一个套接字并发送它,但是在处理过程中包装了一个多余的IPv4标头(我可以看到使用wireshark)和无需重新开始,我认为它会像这样卡住,因为它有一个基本缺陷,因此我不会共享旧代码。

基本上,我可以继续使用我拥有的过于复杂的代码,或者寻求帮助来简化它,因为我对套接字不了解,并且许多小时的搜索没有太大帮助。我一直在寻找的是可以运行的代码,但是在某种程度上不符合要求-可能不是DDOS或syn攻击或其他原因通常所要解决的问题。

关键要求是(我所做的每一次尝试都以某种形式失败了!):

  • 必须来自伪造的源IP并转到已知的目标IP (因此,我正在使用UDP)(两者都在config变量中),以便syslog服务器上的许多不同设备生成的日志都由
  • 必须从固定端口进入固定端口(我都拥有这两个端口) 现有的配置变量)
  • 必须包含一条我已经形成的消息,其中包括所有系统日志内容(PRI和系统日志消息内容)
  • 收到后必须完全抱怨校验和和数据包长度等
  • 尽可能地可移植(我可能会将其嵌入到主脚本中,以将其全部保存在一个可以与他人共享的文件中)。

我只是觉得必须有一种简单的方法来完成此操作,因为我所拥有的一切都过于灵活和复杂,并且是一场噩梦。

NB这在Sourceforge中被共享为“ must syslog”,因此您可以看到我曾经做过的事情,但是请注意它已停止工作,因此如果您当前运行它将无法工作!解决此问题后,我将上传新版本。

干杯,-克里斯

1 个答案:

答案 0 :(得分:0)

实际上,我刚刚取得了突破,我已经在代码中链接了源代码,但是我发现了一个非常基本的测试工具,以及一些UDP校验和代码,这些代码经过一点点的配合工作,wireshark确认了所有正确的方法

发布,以防其他人需要它,这花了我几天的时间才能实现

#!/usr/bin/perl
use Socket;
use List::Util qw(sum);


sub udp_checksum {
    # thanks to ikegami in post https://stackoverflow.com/questions/46181281/udp-checksum-function-in-perl
    my $packed_src_addr = shift;  # As 4-char string, e.g. as returned by inet_aton.
     my $packed_dst_addr = shift;  # As 4-char string, e.g. as returned by inet_aton.
    my $udp_packet      = shift;  # UDP header and data as a string.

    my $sum = sum(
    IPPROTO_UDP,
    length($udp_packet),
    map({ unpack('n*', $_) }
        $packed_src_addr,
        $packed_dst_addr,
        $udp_packet."\0",  # Extra byte ignored if length($udp_packet) is even.
        ),
    );

    while (my $hi = $sum >> 16) {
        $sum = ($sum & 0xFFFF) + $hi;
    }

    return ~$sum & 0xFFFF;
}

#this was found and adapted from http://rhosted.blogspot.com/2009/08/creating-udp-packetip-spoofing-through.html

$src_host = $ARGV[0];
$dst_host = $ARGV[1];
$src_port = 33333;
$dest_port = 514;
$cksum = 0; #initialise, we will sort this later

#$udp_len is the udp packet length in the udp header. Its just 8 plus the length of the data
#for this test harness we will set the data here too
$data = "<132> %FWSM-3-106010: Deny inbound tcp src outside:215.251.218.222/11839 dst inside:192.168.1.1/369";
$udp_len = 8+length($data);

$udp_proto = 17; #17 is the code for udp


#Prepare the udp packet, needed for the checksum to happen, then get the checksum (horrifically complicated, just google it)
$udp_packet = pack("nnnna*", $src_port,$dest_port,$udp_len, $cksum, $data);
$cksum = udp_checksum(inet_aton($src_host),inet_aton($dst_host),$udp_packet);

$zero_cksum = 0; 

#test harness checks about host IPs
my $dst_host = (gethostbyname($dst_host))[4]; my $src_host = (gethostbyname($src_host))[4];

# Now lets construct the IP packet
my $ip_ver = 4;
my $ip_len = 5;
my $ip_ver_len = $ip_ver . $ip_len;
my $ip_tos = 00;
my ($ip_tot_len) = $udp_len + 20;
my $ip_frag_id = 19245;
my $ip_frag_flag = "010";
my $ip_frag_oset = "0000000000000";
my $ip_fl_fr = $ip_frag_flag . $ip_frag_oset;
my $ip_ttl = 30;

#H2H2nnB16C2na4a4 for the IP Header part#nnnna* for the UDP Header part.
#To understand these, see the manual of pack function and IP and UDP Header formats
#IP checksum ($zero_cksum is calculated by the kernel. Dont worry about it.)

my ($pkt) = pack('H2H2nnB16C2na4a4nnnna*',
$ip_ver_len,$ip_tos,$ip_tot_len,$ip_frag_id,
$ip_fl_fr,$ip_ttl,$udp_proto,$zero_cksum,$src_host,
$dst_host,$src_port,$dest_port,$udp_len, $cksum, $data);

#bit that makes the socket and sends the packet
socket(RAW, AF_INET, SOCK_RAW, 255) || die $!; setsockopt(RAW, 0, 1, 1);
my ($destination) = pack('Sna4x8', AF_INET, $dest_port, $dst_host);
send(RAW,$pkt,0,$destination);