作者:
litao3rd
·
2015/03/24 11:51
level 0
這一關就是一個簡單的遊戲介紹,當然,還有明文的賬號密碼。開啟網頁就能看到,不再敘述。
level 0 -> 1
使用上一關得到的賬號和密碼,ssh
登陸到目標機器。
在主目錄下面,我們可以發現一個.backup
資料夾,進入資料夾,發現了一個html
檔案,看樣子是瀏覽器收藏夾檔案。我猜測密碼應該是在檔案中以明文形式出現,用關鍵字leviathan
進行搜尋,立刻就能得到密碼。the password for leviathan1 is rioGegei8m
。這道題應該就是讓你熟悉命令的。
level 1 -> 2
使用上一個level得到的密碼,ssh到下一個level。在這關的home
目錄裡面,我們看到一個名為check
的set-uid
程式,執行程式,看看程式執行結果。
程式要求我們輸入一個密碼,好吧。我不知道該輸入什麼,猜想程式應該是將我們的輸入和某個密碼做比較,然後再執行。隨便輸入一個,觀察結果。
開啟GDB
神器,看看它內部到底是個什麼東西。
從圖中我們可以看看出來,程式三次呼叫getchar()
,猜想,password
應該是三個字元。strcmp()
函式的一個引數是我們輸入的字元的儲存起始地址,另一個地址是0x18(%esp)
,程式一開始在這裡儲存了一個值0x786573
,然後將兩個地址作為實參送入strcmp()
,所以猜想,這裡0x18(%esp)
就是我們需要的密碼。這個值正好是sex
的十六進位制格式,於是,得到密碼是sex
。輸入程式,得到下一個level的密碼。
level 2 -> 3
在這個level的home
目錄裡面,依然是一個set-uid
的程式,執行程式得到如下結果,還是要使用神器gdb
。
使用gdb
開啟程式,這個程式主函式反彙編出來的結果有點長,不過貌似沒有看到子函式呼叫,只有一個主函式。
這個程式首先進行了引數檢查,如果沒有命令列引數輸入,則列印出錯資訊,然後退出。之後使用access()
進行檔案許可權檢查,如果沒有許可權,則列印出錯資訊,然後退出。然後再使用system()
函式執行/bin/cat fileinput
這個命令。
- 根據
access()
的手冊,access() checks whether the calling process can access the file pathname. If **pathname** is a symbolic link, it is dereferenced.
這就意味著我們不能利用符號連結
來過這個許可權檢查。
從gdb
的反彙編程式碼,我們可以得到,程式使用輸入的命令列引數構造了/bin/cat argv[1]
這個字串,然後送入system()
這個函式執行。於是我猜想到構造這麼一個字串/bin/cat < /etc/leviathan_pass/leviathan2
。這樣就可以透過許可權檢查,然後得到密碼了。
- 構造一個檔案,名為
<file
- 構造一個符號連結,
file->/etc/leviathan_pass/leviathan2
這樣,系統進行許可權檢查的時候,則檢查的是<file
這個檔案的許可權,但是執行命令的時候卻是/bin/cat < file
這個命令。
level 3 -> 4
還是一個set-uid
程式,老流程走起,開啟程式,看看它是那個小怪。
還是要gdb
走起啊。
這裡的strcmp()
函式為什麼呼叫我沒有理解,或許是為了干擾吧,在main()
函式中有一個do_stuff()
函式呼叫,整個程式的邏輯應該在這個函式里面。
可以看到,在do_stuff()
函式中有strcmp()
和system()
等比較,strcmp()
的其中一個實參來自於fgets()
函式的返回結果,另一個引數儲存在-0x117(%ebp)
,從圖中可以看出來,儲存在-0x117(%ebp)
的引數就是待匹配的密碼。
將密碼輸入到程式中,就可以得到一個shell,進而得到下一個level的密碼。
level 4 -> 5
好吧,這一個level的檔案在.trash
資料夾中了,依舊是熟悉的流程。
從程式輸出看,應該是密碼被轉換成二進位制輸出了,或者是加密之後轉換成二進位制輸出,這個還是得要祭起gdb
神器來幫忙了。
從這個迴圈過程中,我們可以看到,程式對密碼的每個字元,從最高位(符號位)開始計算,每次輸出一個字元0
或者字元1
,所以可以得到,該bin
程式是將密文的每個字元轉換成二進位制格式輸出。單步除錯的時候,程式在呼叫fopen("/etc/leviathan_pass/leviathan5", "r")
的時候返回錯誤,導致除錯無法進行。看來,直接檢視記憶體獲得密碼的方法是行不通了,只能寫指令碼,處理程式的輸出了。
#!python
#!/usr/bin/env python
#coding=utf-8
if __name__ == "__main__":
try:
fp = open("log.txt", "r")
except:
print "file open error"
for i in range(12):
byte = fp.read(9).strip()
value = (int(byte, 2)) & 0xFF
#print value
char = chr(value)
print char,
python
程式碼寫得不是一丁點的醜,實在是因為用得不多!
把密碼中的空格剔除就是正確的密碼了。
level 5 -> 6
還是熟悉的流程,熟悉的味道。
似乎/tmp/file.log
這個路徑被硬編碼到了程式中了,還是要看看這個程式到底做了什麼事情。
確實是被硬編碼到了程式中去了,嘗試著在該路徑下建立一個指向密碼檔案的符號連結檔案,發現居然成功了。
好吧,這一個level實在是有點開玩笑啊。。。。
level 6 -> 7
哈哈,這個level似乎有不一樣的味道,雖然還是熟悉的流程。
這裡,這個set-uid
程式需要輸入一個4 digit code
,懶得再去用gdb
反彙編了,我估計也不太好反,做了混淆應該。乾脆就來個爆破吧。
#!python
#!/usr/bin/env python
#coding=utf-8
import os
for pincode in range(10000):
cmd = "~/leviathan6 %04d" %(pincode)
# for debug
#print "test %s" %(cmd)
ret = os.popen(cmd).read()
if ret.find("Wrong") == -1:
print "maybe success in %s" %(cmd)
程式在7123
那裡停止了,我猜想是跑到了shell
裡面去了。嘗試了一下,果然是這樣的。
level 7
ssh
登陸到level 7
好吧,我純粹是為了混一個邀請碼,才寫這個writeup
的。要不然我肯定遵守這個規則!
end
Bingo!這個wargame
就這樣結束了,題目確實挺簡單的,完全是為了新手學習,知道怎麼玩wargames
。
更多關於wargames
的資訊,請參考這裡!
本文章來源於烏雲知識庫,此映象為了方便大家學習研究,文章版權歸烏雲知識庫!