Wargama-leviathan Writeup

wyzsk發表於2020-08-19
作者: litao3rd · 2015/03/24 11:51

level 0


這一關就是一個簡單的遊戲介紹,當然,還有明文的賬號密碼。開啟網頁就能看到,不再敘述。

level 0 -> 1


使用上一關得到的賬號和密碼,ssh 登陸到目標機器。

ssh_level1.png

在主目錄下面,我們可以發現一個.backup資料夾,進入資料夾,發現了一個html檔案,看樣子是瀏覽器收藏夾檔案。我猜測密碼應該是在檔案中以明文形式出現,用關鍵字leviathan進行搜尋,立刻就能得到密碼。the password for leviathan1 is rioGegei8m。這道題應該就是讓你熟悉命令的。

leviathan_password_level1

level 1 -> 2


使用上一個level得到的密碼,ssh到下一個level。在這關的home目錄裡面,我們看到一個名為checkset-uid程式,執行程式,看看程式執行結果。

leviathan_check_level1

程式要求我們輸入一個密碼,好吧。我不知道該輸入什麼,猜想程式應該是將我們的輸入和某個密碼做比較,然後再執行。隨便輸入一個,觀察結果。

leviathan_check_failure_level1

開啟GDB神器,看看它內部到底是個什麼東西。

leviathan_gdb_level1.png

從圖中我們可以看看出來,程式三次呼叫getchar(),猜想,password應該是三個字元。strcmp()函式的一個引數是我們輸入的字元的儲存起始地址,另一個地址是0x18(%esp),程式一開始在這裡儲存了一個值0x786573,然後將兩個地址作為實參送入strcmp(),所以猜想,這裡0x18(%esp)就是我們需要的密碼。這個值正好是sex的十六進位制格式,於是,得到密碼是sex。輸入程式,得到下一個level的密碼。

leviathan_crack_level1

level 2 -> 3


在這個level的home目錄裡面,依然是一個set-uid的程式,執行程式得到如下結果,還是要使用神器gdb

leviathan_home_level2

使用gdb開啟程式,這個程式主函式反彙編出來的結果有點長,不過貌似沒有看到子函式呼叫,只有一個主函式。

leviathan_gdb_level2

這個程式首先進行了引數檢查,如果沒有命令列引數輸入,則列印出錯資訊,然後退出。之後使用access()進行檔案許可權檢查,如果沒有許可權,則列印出錯資訊,然後退出。然後再使用system()函式執行/bin/cat fileinput這個命令。

leviathan_error_level2

  • 根據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這個命令。

leviathan_pass_level2

level 3 -> 4


還是一個set-uid程式,老流程走起,開啟程式,看看它是那個小怪。

leviathan_home_level3

還是要gdb走起啊。

leviathan_gdb_main_level3

這裡的strcmp()函式為什麼呼叫我沒有理解,或許是為了干擾吧,在main()函式中有一個do_stuff()函式呼叫,整個程式的邏輯應該在這個函式里面。

leviathan_gdb_do_stuff_level3

可以看到,在do_stuff()函式中有strcmp()system()等比較,strcmp()的其中一個實參來自於fgets()函式的返回結果,另一個引數儲存在-0x117(%ebp),從圖中可以看出來,儲存在-0x117(%ebp)的引數就是待匹配的密碼。

leviathan_gdb_pass_level3

將密碼輸入到程式中,就可以得到一個shell,進而得到下一個level的密碼。

leviathan_pass_level3

level 4 -> 5


好吧,這一個level的檔案在.trash資料夾中了,依舊是熟悉的流程。

leviathan_home_level4

從程式輸出看,應該是密碼被轉換成二進位制輸出了,或者是加密之後轉換成二進位制輸出,這個還是得要祭起gdb神器來幫忙了。

leviathan_gdb_main_level4

從這個迴圈過程中,我們可以看到,程式對密碼的每個字元,從最高位(符號位)開始計算,每次輸出一個字元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程式碼寫得不是一丁點的醜,實在是因為用得不多!

leviathan_pass_level4

把密碼中的空格剔除就是正確的密碼了。

level 5 -> 6


還是熟悉的流程,熟悉的味道。

leviathan_home_level5

似乎/tmp/file.log這個路徑被硬編碼到了程式中了,還是要看看這個程式到底做了什麼事情。

leviathan_gdb_main_level5

確實是被硬編碼到了程式中去了,嘗試著在該路徑下建立一個指向密碼檔案的符號連結檔案,發現居然成功了。

leviathan_pass_level5

好吧,這一個level實在是有點開玩笑啊。。。。

level 6 -> 7


哈哈,這個level似乎有不一樣的味道,雖然還是熟悉的流程。

leviathan_home_level6

這裡,這個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裡面去了。嘗試了一下,果然是這樣的。

leviathan_pass_level6

level 7


ssh登陸到level 7

leviathan_home_level7

好吧,我純粹是為了混一個邀請碼,才寫這個writeup的。要不然我肯定遵守這個規則!

end


Bingo!這個wargame就這樣結束了,題目確實挺簡單的,完全是為了新手學習,知道怎麼玩wargames

更多關於wargames的資訊,請參考這裡!

本文章來源於烏雲知識庫,此映象為了方便大家學習研究,文章版權歸烏雲知識庫!

相關文章