perl中的NTLM代理验证

时间:2013-02-18 06:25:07

标签: perl ntlm proxy-authentication

我需要通过代理访问网页。 我需要使用NTLM或Digest Auth Scheme

我用谷歌搜索的代码不起作用。

下面的代码是使用任何Auth标头发出Web请求。 请帮我通过NTLM代理验证获取网页。

GET (URL address blocked: See forum rules) HTTP/1.1
TE: deflate,gzip;q=0.3
Keep-Alive: 300
Connection: Keep-Alive, TE
Host: google.com
User-Agent: libwww-perl/6.02


my $ua = new LWP::UserAgent(keep_alive => 1);
$ua->proxy('http', $PROXY);
$ua->credentials('proxy', '', 'username','passwd');
ntlmv2(1);

my $req = GET  $url;
print "--Peforming request now...---------\n";

my $res = $ua->request($req);
if ($res->is_success) {
    print $res->content;
} else {
    print "Error: " . $res->status_line . "\n";
    print $res->headers()->as_string(), "\n";
}

2 个答案:

答案 0 :(得分:4)

从以下页面:http://www.perlmonks.org/?node_id=953031

use strict;
use warnings;
use Authen::NTLM;
use LWP::UserAgent;
use HTTP::Request::Common;

my $url = 'http://www.google.de';

my $ntlm = Authen::NTLM->new(
    host     => $url,
    user     => 'user',
    password => 'password',
);
my $reply = $ntlm->challenge;

my $ua = LWP::UserAgent->new(keep_alive => 1);
$ua->env_proxy;
$ua->protocols_allowed(['http']);

my $req = GET $url;
print "====Performing request now=========";

my $res = $ua->request($req);
if ($res->is_success) {
    print $res->content;
} else {
    print "Error: " . $res->status_line . "\n";
    print $res->headers()->as_string(), "\n";
}
print "====Done with request===============";
ntlm_reset;
exit;

答案 1 :(得分:0)

这是我设法从需要NTLM身份验证的Microsoft Proxy后面工作的唯一代码段。此代码改编自Cosine Security,并使用Authen::NTLM by Lee Man Chan

#!/usr/bin/perl -w

use strict;
use LWP::UserAgent;
use Authen::NTLM;
use Authen::NTLM::HTTP;

my $url         = 'http://www.google.com';
my $proxy       = 'http://proxy.foobar.com:8080'; # Required
my $user        = 'username';                     # Required
my $pass        = 'passw0rd';                     # Required
my $nt_domain   = 'DOMAIN';                       # Optional can be blank ''
my $host_domain = 'foobar.com';                   # NOT blank. At least 1 char 'x'
my $machine     = 'hostname';                     # Optional can be blank ''

# Creates the LWP User Agent, tells it to use the supplied proxy, and sends the
# initial HTTP GET request for the supplied URL and takes in a response
my $ua = new LWP::UserAgent(keep_alive=>1);
$ua->proxy('http', $proxy);

my $req = HTTP::Request->new(GET => $url);

# 1) code:'407', message='Proxy Authentication Required
# (Forefront TMG requires authorization to fulfill the request. Access to the
# Web Proxy filter is denied.)'
my $res = $ua->request($req);
print "1) " , $res->is_success? "It worked!->" : "It didn't work!->";
print "code:'". $res->code ."', message='". $res->message . "'\n";

# Once the initial request has been sent out, the proxy will send back an NTLM 
# negotiate message
# We set up the NTLM authentication client response by passing ntlm hashes of
# the username, password, domain, and workstation hostname
my $client = new_client Authen::NTLM::HTTP(
    Authen::NTLM::lm_hash($pass), 
    Authen::NTLM::nt_hash($pass),
    Authen::NTLM::HTTP::NTLMSSP_HTTP_PROXY, 
    $user, 
    $nt_domain, 
    $host_domain, 
    $machine);

# Here we set the NTLM protocol flags that we wish to be accepted
my $negotiate_flags = 
    Authen::NTLM::NTLMSSP_NEGOTIATE_ALWAYS_SIGN |
    Authen::NTLM::NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED |
    Authen::NTLM::NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED |
    Authen::NTLM::NTLMSSP_NEGOTIATE_NTLM |
    Authen::NTLM::NTLMSSP_NEGOTIATE_OEM;

# We then take the client data, and the flags and jam them into a header, and add
# it back to the original request, and resend it.
my $negotiate_msg = "Proxy-" . $client->http_negotiate($negotiate_flags);

my @pa = split(/:/,$negotiate_msg);

$req->header($pa[0] => $pa[1]);
# The proxy then sends back an NTLM challenge response, which we strip from the
# message and parse using the NTLM methods provided by the module

# 2) code:'407', message='Proxy Authentication Required ( Access is denied.  )'
$res = $ua->request($req);
print "2) " , $res->is_success? "It worked!->" : "It didn't work!->";
print "code:'". $res->code ."', message='". $res->message . "'\n";

my $challenge_msg = "Proxy-Authenticate: " . $res->header("Proxy-Authenticate");

my ($domain, $flags, $nonce, $ctx_upper, $ctx_lower)
    = $client->http_parse_challenge($challenge_msg);

# We set the next round of flags, take the Nonce which we gained from parsing the
# challenge message, and send back a final authentication message. Once the proxy
# recieves this, it processes the original GET request
my $auth_flags = 
    Authen::NTLM::NTLMSSP_NEGOTIATE_ALWAYS_SIGN | 
    Authen::NTLM::NTLMSSP_NEGOTIATE_NTLM | 
    Authen::NTLM::NTLMSSP_REQUEST_TARGET;
my $auth_msg = $client->http_auth($nonce, $auth_flags);

@pa = split(/:/,$auth_msg);
#print STDERR "pa[0] = '$pa[0]', pa[1] = '$pa[1]'\n";

$req->header($pa[0] => $pa[1]);

# 3) code:'200', message='OK'
$res = $ua->request($req);
print "3) " , $res->is_success? "It worked!->" : "It didn't work!->";
print "code:'". $res->code ."', message='". $res->message . "'\n";

if ($res->is_success) {
    print "##################################\n";
    print "Success: " . $res->status_line . "\n";
    print $res->headers()->as_string(), "\n";
    print "##################################\n";
    print $res->content;
} else {
    print "Error: " . $res->status_line . "\n";
    print $res->headers()->as_string(), "\n";
}

-hq