ระบบรับข้อมูลหนึ่ง ถูก แ+ฮ+ก ด้วย script

process of solution
process of solution

วันนี้ได้รับแจ้งว่าระบบเก่า ถูก post h-a-c-k_e-d
จึงเข้าไปแกะ script แบบค่อย ๆ ไล่ไปทีละแฟ้ม
เพราะเขียนไว้นาน และหลายคน จำอะไรไม่ได้เลย

1. ดู source ซึ่งเป็นผลลัพธ์ พบว่า
script ไม่ได้เสียหาย แต่มีการ post script เข้ามาเป็นข้อมูล

2. ในข้อมูลมี script จริง แสดงว่าไม่มีการ convert ข้อมูลก่อน insert

3. เข้าไปดูระบบรับข้อมูลพบว่าติด captcha แต่เป็น plain text แบบง่าย
แสดงว่า script ที่เข้ามาในระบบเป็นขั้นเทพ ถึงแกะ captcha ออกได้

4. เพิ่มการป้องกันใน form รับข้อมูล
โดยกำหนดเงื่อนไขว่า form ต้องถูกเรียกจาก script ที่กำหนด
ถ้าเรียกจากที่ไหน ๆ ก็จะไม่เปิดฟอร์ม

5. อันที่จริงควรเปลี่ยนข้อมูลด้วย stripslashes เข้าฐานข้อมูล
เพื่อล้าง script แต่นั่นเป็นการแก้ปลายเหตุ
จึงแก้ต้นเหตุ คือ ไม่ให้ข้อมูลเข้า จากขั้นตอนที่ 4
หรือเพิ่มการตรวจสอบก่อน insert ซึ่งมีอีกหลายวิธี

เปลี่ยนรุ่นของ PHP จาก 4 เป็น 5 แล้ว script ใช้งานไม่ได้

เล่าสู่กันฟัง เรื่องปัญหาการปรับเปลี่ยนรุ่นของ server

URL กับ REQUEST_URIURL กับ REQUEST_URI
URL กับ REQUEST_URI

เนื่องจาก script ที่ใช้เคย สามารถใช้งานได้ปกติ
แต่เกิดปัญหาหลัง upgrade server
ที่ต้องใช้ PHP version ใหม่ ก็พบว่า script เดิมใช้งานไม่ได้
ตรวจดูก็พบว่าค่าของระบบ _SERVER ที่เคยส่งให้กับ script ภาษา PHP
ไม่ยอมส่งค่าให้ตามปกติ คือ ไม่ส่งอะไรคืนมาเลย
ต้องแก้ไขโดยกำหนดการรับค่าจากระบบ เป็นค่าใหม่

เดิมรับค่า “URL” ก็ต้องเปลี่ยนเป็นรับค่า “REQUEST_URI”

ซึ่งเหตุการแบบนี้เกิดขึ้นได้ในปัจจุบัน และเกิดขึ้นอีกอย่างแน่นอนในอนาคต
เมื่อต้องมีการ upgrade server ในปีต่อ ๆ ไป

ค่าใน _SERVER[“REQUEST_URI”] เปลี่ยนไปใน PHP 5.2.6

PHP 5.2.6 & PHP 4.4.9
PHP 5.2.6 & PHP 4.4.9

พบปัญหาใน script : managefile.php ที่ให้บริการจัดการแฟ้มแบบออนไลน์ หลัง upgrade server ตัวหนึ่ง แบบย้ายเครื่องแล้ว clone ข้อมูล มีการติดตั้ง webserver version ใหม่ พบว่าความสามารถในการกำหนดรหัสผ่านใหม่ ซึ่งใช้เทคนิคการ encrypt + password embedded + replace script โดยใช้ค่าที่รับจากตัว script เอง .. กลับใช้งานไม่ได้ แล้ว script ตอบมาว่าติดปัญหา security ไปตรวจดูก็พบว่าค่าของ  $_SERVER[“REQUEST_URI”] ของ PHP 5.2.6 ต่างไปจากเดิม แก้ไขโดยเปลี่ยนจาก $_SERVER[“REQUEST_URI”] เป็น  $_SERVER[“SCRIPT_NAME”]

http://thaiwebsearch.hypermart.net/perlphpasp/source.pl?9102

ปล.ต้องหาเวลาเข้า upgrade script แล้ว

มูดเดิ้ลล้ม แล้วย้ายเครื่อง ออกอาการสตาร์ทไม่ติด

can not start moodle
can not start moodle
การติดตั้ง moodle 2.1 ขึ้นไป
ต้องใช้ PHP 5.3.2 เป็นขั้นต่ำ
อย่างเครื่องที่ใช้ PHP 5.2.6 ถ้ามีการปิดระบบ หรือย้ายเครื่อง
อาจพบปัญหานี้ได้ ก็แก้ไขโดยเปลี่ยนรุ่นของ php
Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM
in C:\Appserv\www\_class\lib\accesslib.php on line 5288
แล้วอย่าลืมว่า mysql ก็ต้อง MySQL 5.0.25 ขึ้นไป
อย่างเครื่องบริการเครื่องหนึ่งเป็น php 4 + mysql 4
ก็ต้องเลือก moodle 1.9 เพราะ 2.2 ต้องการมากกว่าที่มี
แต่ถ้าเป็นเครื่องที่ควบคุมได้ ก็ลงไปเลย php5.3 + mysql5.0
แล้วการใช้ appserv ก็เป็นอะไรที่สะดวกสบายยิ่ง
.. confirm

การตรวจรหัสผ่านใน ldap server

apache directory studio : ldap server & client
apache directory studio : ldap server & client

http://directory.apache.org/studio/

ได้รับโอกาสจากคุณหนึ่งให้หาวิธีการตรวจสอบรหัสผ่านกับ ldap server ด้วย php
ซึ่งรหัสผ่านในเครื่องบริการถูกเข้ารหัสแบบ {SHA} ซึ่งเป็นการเข้ารหัสทางเดียว แบบคงที่
การตรวจสอบทำโดยเข้ารหัสผ่านของเรา แล้วส่งไปเปรียบเทียบรหัสที่ถูกเข้ารหัสไว้ว่าตรงกันหรือไม่
หากใน shell ของ linux สามารถใช้ # slappasswd -h {SHA} -s mypassword
สร้างรหัสผ่านที่ได้รับการเข้ารหัส
แต่ถ้าเป็น PHP ต้องใช้ $e =  base64_encode( pack( “H*”, sha1(“mypassword”)));
ตัวอย่าง code นี้เข้าไป scan ใน directory ต่าง ๆ เพราะไม่ทราบว่า user นี้อยู่ในกลุ่มใด

// verify user & password in ldap server
$ldap = ldap_connect(“127.0.0.1”,389);
$b = ldap_bind($ldap,”uid=sombat”,”loveyou”) or die(“bind died”);
//
$arr = array(
“ou=LAMPANG,ou=STAFF,ou=TEAM_A”,
“ou=LAMPANG,ou=MANAGER,ou=TEAM_A”,
“ou=BANGKOK,ou=STAFF,ou=TEAM_A”,
“ou=BANGKOK,ou=MANAGER,ou=TEAM_A”,
“ou=LAMPANG,ou=STAFF,ou=TEAM_B”,
“ou=LAMPANG,ou=MANAGER,ou=TEAM_B”,
“ou=BANGKOK,ou=STAFF,ou=TEAM_B”,
“ou=BANGKOK,ou=MANAGER,ou=TEAM_B”);
foreach ($arr as $key => $value) {
$dn = ‘uid=’. $_REQUEST[“uid”] .’,’.$value.’,dc=abc,dc=com’;
$result = ldap_search($ldap, $dn,”(uid=*)”,array(“uid”,”userpassword”));
$rec = ldap_get_entries($ldap,$result);
$encoded = “{SHA}” . base64_encode( pack( “H*”, sha1($_REQUEST[“pass”]) ) );
if (isset($rec[0][“userpassword”][0]) && $rec[0][“userpassword”][0] == $encoded) {
echo “<meta http-equiv=’refresh’ content=’0;url=http://www.abc.com/pass.php’ />“;
exit;
}
}
ldap_unbind($ldap);
header(“location: http://www.abc.com/login.php“);

การแสดงรายชื่อตารางทั้งหมดใน MSSQL

EMS : MSSQL Manager
EMS : MSSQL Manager

มีโอกาสเข้าใช้ MSSql หรือ SQL Server แต่ผู้ดูแลไม่ได้แจ้งว่าตารางที่ผมเข้าถึงได้ คือ ตารางชื่ออะไร
จึงเขียน 2 โปรแกรม สำหรับตรวจสอบข้อมูล
เพื่อจัดทำโปรแกรม insert, delete, update, select ต่อไป

1. โปรแกรมแสดงรายการตารางทั้งหมด

$strSQL = “SELECT * FROM sys.Tables”; // order by name”;
$strQuery =  mssql_query($strSQL);
while($result = mssql_fetch_array($strQuery)) { echo $result[0]  . “<br/>”; }

2. โปรแกรมแสดงรายการเขตข้อมูลทั้งหมด
$strSQL = “SELECT * FROM sys.columns”;
$strQuery =  mssql_query($strSQL);
$f0 = “”;
while($result = mssql_fetch_array($strQuery)) {
if ($f0 != $result[0]) echo “<hr/>”;
echo $result[0]  . ” ” . $result[1]  . “<br/>”;
$f0 = $result[0];
}

ปล. อันที่จริงถ้าใช้ SQL Manager จะดีกว่านั่งเขียน Script เพราะ host กับ user ก็รู้หมดแล้ว

EMS : MSSQL Manager
http://www.sqlmanager.net/en/downloads

Microsoft SQL Server  2008 Management Studio Express
http://www.microsoft.com/en-us/download/details.aspx?id=7593

รวมทิป ของ PHP

ftp test
ftp test

tip หมายถึง ข้อแนะนำ เกร็ดความรู้

– มีการเขียนทิป หรือหลักการ ของ php ไว้ไม่น้อย เขียนกันต่างบ้าง เหมือนกันบ้าง ล้วนระดมมาจากความรู้ และประสบการณ์
แล้วนำมาเรียบเรียงกันใหม่ .. ผมว่าอ่านดีครับ
– สังเกตเห็นว่า ปัจจุบันมีการเขียนกันไว้ใน blog แสดงว่า ความรู้ มักอยู่ใน blog ดังนั้นในกระบวนการ KM จึงมากใช้เป็นเครื่องมือในขั้นตอนหนึ่งของการจัดการความรู้
– สิ่งหนึ่งที่ทุกคนเหมือนกัน ถึงได้เขียนกันออกมา คือ อยากแบ่งปันความรู้ที่ได้จากการรวบรวม เรียบเรียง หรือผลทดสอบ นั่นเอง

http://www.thaiall.com/php/

http://mashable.com/2010/10/21/php-tips-for-beginners/

http://www.phpbuilder.com/columns/vaska20050722.php3

http://www.htmlgoodies.com/beyond/php/article.php/3907521/Top-10-PHP-Tips-for-Developers.htm

http://net.tutsplus.com/tutorials/php/quick-tip-7-super-handy-php-functions-for-beginners/

http://www.wmtips.com/php/tips-optimizing-php-code.htm

http://www.webdesigndev.com/programming/15-top-php-coding-tutorials-tips-and-tricks

http://coding.smashingmagazine.com/2008/11/18/10-advanced-php-tips-to-improve-your-progamming/
http://programming-4-u.blogspot.com/2012/05/10-php-tips-to-improve-your-programming.html

http://www.phpbuilder.com/columns/vaska20050812.php3

http://net.tutsplus.com/tutorials/php/10-principles-of-the-php-masters/

http://hungred.com/useful-information/php-micro-optimization-tips/

http://www.nerdparadise.com/tech/php/10tips/

ระบบช่วย sign on ชั้นที่ 2 หลังผ่านชั้นแรก

php sign on code
php sign on code

28 มี.ค.55 มีเพื่อนในทีมพัฒนาระบบตรวจสอบสมาชิก หรือยืนยันตัวตน ขึ้นอีกระบบหนึ่ง ซึ่งใช้ user และ password ต่างไปจากชุดเดิม เป็นแบบกำหนดเฉพาะบางคนที่มีสิทธิ หากผ่านการตรวจสอบจากระบบแรก ผมจึงเขียน script ด้วย php ตรวจว่ามีค่า session ส่งมาจากระบบแรกหรือไม่ ถ้ามีและอยู่ในรายการที่กำหนด ก็จะส่งรหัสให้กับฟอร์ม เพื่อให้ผู้ใช้คลิ๊กเข้าระบบที่สอง ซึ่งระบบที่สองตรวจสอบผู้ใช้ผ่าน post โดย javascript ถูกเขียนอย่างหลวม ๆ ให้สามารถปรับแต่งต่อได้
โดยต้นแบบมาจากระบบ submit search จาก http://www.thaiall.com/search.htm

<?
session_start();
$page = "http://www.hot.com/login.php";
$user = "your username"; 
$passwd = "your password";
$u = array("101","102");
$pass = 0;
foreach ($u as $v) {
  if (isset($_SESSION["id"]) && $_SESSION["id"] == $v) { $pass = 1;}
}
if ($pass == 0) {
foreach ($u as $v) { echo $v. "<br/>"; }
echo "<br/><a href='http://www.thaiall.com'>back</a>";
exit;
}
?>
<html><head><title>admin login</title></head>
<script language="JavaScript"> 
function newpage() {
page = "<?=$page;?>";
u = document.f.username.value;
p = document.f.passwd.value;
o = window.open('blank.htm','y',"toolbar=yes");
o.document.open();
o.document.write("<body><form name='y' action='" +  page + "' method='post'>");
o.document.write("<input name='u' value=''><input name='p' value=''></form>");
o.document.close();
o.document.y.u.value = u;
o.document.y.p.value = p;
o.document.y.submit();
} 
</script>
<body>
<form name="f">
<input type=button value="click to open in new page" onclick="newpage()">
<input type=hidden name=username value="<?=$user;?>">
<input type=hidden name=passwd value="<?=$passwd;?>">
</form>
</body></html>

สร้างบริการตรวจข้อมูลบน ldap

ldap checking
ldap checking
29 ก.ย.54 มีโอกาสต้องสืบค้นข้อมูลบน ldap server เดิมทีจะใช้ ldap client ติดต่อเข้าไป ซึ่งเป็นซอฟท์แวร์ที่ต้องมีการติดตั้ง หากต้องการตรวจสอบผ่านเว็บเพจก็ต้องเขียน script ขึ้น เพื่อให้สามารถใช้บริการจากเครื่องใดก็ได้ในระบบ LAN ที่มีไอพีขึ้นต้นด้วย 172 (ตาม script)
มีตัวอย่าง php script ดังนี้
<?
// config
$host = "ldap://xxx.xxx.xxx";
$domain = "xxxxx";
$pass = "xxx";
// form
if (!isset($_POST["act"]) && substr($_SERVER["REMOTE_ADDR"],0,3) == "172"){
?>
<form action="" method="post">uid <input name=uid><br>
<select name=ou size=8>
<option value="ou=MANAGER,ou=SALE">Manager</option>
<option value="ou=STAFF,ou=SALE">Staff</option>
</select>
<br>form password <input name=fpass type=password>
<br><input type=submit name=act value=check>
</form>
<? exit; }
if ($_POST["fpass"] != "xxxx") { echo "invalid"; exit; }
//
$baseDn2 = 'uid='.$_POST["uid"].','.$_POST["ou"].',dc='.$domain.',dc=com';
$baseDn1 = 'cn=Manager,dc='.$domain.',dc=com';
//
$ldap = ldap_connect($host);
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
$b = ldap_bind($ldap,$baseDn1,$pass) or die("bind died");
if($b) echo "<pre>{$_POST["uid"]} \n";
$result = ldap_search($ldap, $baseDn2,"(cn=*)");
$rec = ldap_get_entries($ldap,$result);
if (!isset($rec[0]["data"][0]))
echo "not found"; else echo $rec[0]["data"][0];
ldap_unbind($ldap);
?>

php code สำหรับติดต่อ ldap server

22 ก.ย.54 มีโอกาสเรียนรู้การเขียนโปรแกรมด้วยภาษา PHP ติดต่อกับ LDAP Server โดยมี engineer ติดตั้ง server ตัวนี้ไว้ แล้วผมมีหน้าที่เข้าไปใช้งาน ก็คิดว่าจะใช้ php (ใช้ phpinfo ตรวจแล้วพบว่า php สามารถใช้ ldap ได้) เข้าไปอ่านข้อมูลผู้ใช้ เพื่อทำ authentication ตรวจผู้ใช้งานระบบ และ code ชุดนี้เป็นตัวอย่างที่ผมใช้ติดต่อกับ ldap server การติดต่อนั้นอาจใช้ browser

พิมพ์ ldap://www.domain.com:389
/uid=BURIN_R,ou=CLERK,ou=OFFICE1,dc=domain,dc=com

ก็จะเปิดด้วยโปรแกรม Windows Contact ขึ้นมาอัตโนมัติ

<?
$host = “ldap://www.domain.com“;
$baseDn1 = ‘cn=Manager,dc=domain,dc=com‘;
$baseDn2 = ‘uid=BURIN_R,ou=CLERK,ou=OFFICE1,dc=domain,dc=com‘;
$password = “your password“;
$ldap = ldap_connect($host);
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
$b = ldap_bind($ldap,$baseDn1,$password) or die(“bind died”);
echo “<pre>bind :”;
if($b) echo “pass”; else echo “fail”;
$result = ldap_search($ldap, $baseDn2,”(cn=*)”);
$rec = ldap_get_entries($ldap,$result);
echo ldap_count_entries($ldap,$result);
echo $rec[0][“cn”][0];
echo $rec[0][“userpassword”][0];
echo $rec[0][0][0];
print_r($rec);
ldap_unbind($ldap);
?>