4周前 (09-18) 中國互聯安全響應中心  滲透注入
文章評分 2 次,平均分 4.5

0x01 misc


too young too simple

一個叫flag.bmp的文件,但是無法打開。文件頭42 4D確實是bmp文件的頭,但是文件尾?49 45 4E 44 AE 42 60 82卻是png文件的尾。

第五季極客大挑戰writeup

第五季極客大挑戰writeup

另外文件頭中的IHDR也能確信這是一個png圖片。將文件頭的?42 4D E3 BF 22 00 00 00修改為png頭?89 50 4E 47 0D 0A 1A 0A,順利打開得到一張圖片。

第五季極客大挑戰writeup

圖上是appleu0大神的blog地址,后面的提示意味不明。搜了下weichuncai并訪問blog才知道這是blog上的動漫人物。與之聊天輸入flag得到Flag。Flag貌似是海賊王里的。大神果然是十足的動漫控啊!

第五季極客大挑戰writeup

你喜不喜歡萌萌噠的姐姐

一張loli的圖,在jpg尾FF D9后還有很多可顯字符。

第五季極客大挑戰writeup

全部復制出來,看編碼應該是base64,放到hackbar里base64decode一下,卻得到很多不可顯字符,但是發現了JFIF標識,應該是base64encode了一張圖片得到的。

第五季極客大挑戰writeup

下面是解碼腳本。

#!/usr/bin/env python

import base64

f = open('1.jpg', 'rb')
pic = f.read()
index = pic.find('\xff\xd9')
flag = pic[index + 5:]
f.close()

f1 = open('flag.jpg', 'w')
f1.write(base64.decodestring(flag))
f1.close()

運行得到flag.jpg。

第五季極客大挑戰writeup

開胃小菜

題目要求修改參賽口號為Hacked by white god!。

在個人信息頁面http://hack.myclover.org/team_info的HTML注釋中發現提示:

第五季極客大挑戰writeup

更新口號翻譯為upvoice,簡直不忍直視,不能再low。 訪問?http://hack.myclover.org/team_info/upvoice?voice=Hacked+by+white+god!得到Flag。

第五季極客大挑戰writeup

白神的假期

一張jpg圖片,在文件尾FF D9后還有不少內容,而且是rar文件頭52 61 72 21

第五季極客大挑戰writeup

復制出剩下的部分成rar文件解壓得到flag.txt。

第五季極客大挑戰writeup

在base64decode一下就得到Flag:KEY:SYC{Y34h!Thi5_15_th3_jp9_r4r_K3Y}

reg

第五季極客大挑戰writeup

看到com啥的基本上就知道這肯定是個url了,再加上開始部分twi以及com之前的部分是從syclover中取,就能猜出是twitter.com,追加上后面的asdlalalalala得到url:twitter.com/asdlalalalala,訪問url得到Flag。

第五季極客大挑戰writeup

bilibili

最坑的題沒有之一。出題者喪心病狂居然要求通過bilibili的會員晉級考試,還得至少80分。好不容易通過修改HTML代碼弄出了一張通過圖,竟然還要關注出題者。無奈只好仔細百度做題,還好這時候只需要60就晉級成功,出題者也無法分辨我到底是60還是80。

0x02 pentest


HTTP Base1

Flag在HTTP response header中。

第五季極客大挑戰writeup

HTTP Base2

第五季極客大挑戰writeup

題目要求必須本機訪問,開始以為加上X-Forwarder-For: 127.0.0.1到request header中就能解決,后來才知道也有從Client-IP來判斷訪問者來路的,于是填上Client-IP: 127.0.0.1到request header中得到Flag。

第五季極客大挑戰writeup

HTTP Base3

第五季極客大挑戰writeup

題目顯示訪問者是普通用戶,所以思路是變成管理員,再加上cookie中發現有:userid=33; userlevel=2;于是將userid和userlevel都置為1,再次訪問得到Flag。

第五季極客大挑戰writeup

CrackPWD1

第五季極客大挑戰writeup

直接上ophcrack。Ophcrack基于彩虹表來破解hash口令,特別是針對XP的LM-NT hash,成功率很高。 下載地址:

http://sourceforge.jp/projects/ophcrack/releases/

http://sourceforge.net/projects/ophcrack/files/

第五季極客大挑戰writeup

CrackPWD2

第五季極客大挑戰writeup

提示口令起始為SYC#且長度為8,只需要生成一份包含所有可能性的字典交給工具跑。后4位每位上可見字符一共94個,字典大小為94的4次方行,約7800w。

第五季極客大挑戰writeup

再加上毛子強大的工具oclhashcat(http://hashcat.net/oclhashcat/),幾乎是秒破口令。oclhashcat是一款使用GPU顯卡來破密碼的工具,分為N卡版和A卡版,號稱世界上最快的密碼破解器。 運行命令:

cudaHashcat64.exe -t 32 -m 1000 NT.hash pass.dic

第五季極客大挑戰writeup

美男子

第五季極客大挑戰writeup

按提示需要認證為美男子。查看cookie發現是:?user=diaosi; isboy=0; pass=d93fa3b25f83f202cc51257eee2c9207;訪問者被設為diaosi了,不能忍,果斷修改user=meinanzi; isboy=1;刷新得到Flag。

第五季極客大挑戰writeup

Cookie中的md5解開是ds0,沒用上。

Login

第五季極客大挑戰writeup

username=appleU0&password=syclover登錄,發現一行提示 Tips: coverage login。 各種搜索不知道啥叫覆蓋登錄。各種亂想終于想到是覆蓋login,變量覆蓋漏洞。經歷ISCC2014的變量覆蓋題,猜變量名是一件頭大的事。我設想了幾個可能的變量名:

<code>admin\flag\key\KEY\user\login\submit
</code>

以及可能的值:?1\true\flag\key\admin\flag\login,爆破了下沒有結果,甚至連中文的值都試過,登錄\提交,無果。最終覺得既然是覆蓋login,變量名應該就是login,于是在GET的url后面添加上?login=1,嘗試了下得到Flag。

第五季極客大挑戰writeup

白神的shell

第五季極客大挑戰writeup

直接上代碼吧,多線程也不會,跑的慢點,不過也能出結果。

#!/usr/bin/env python

import httplib

s = 'zxcvbnmasdfghjklqwertyuiop'
length = len(s)
uri = '/pentest/findshell/white_god_s_webshell_'
conn = httplib.HTTPConnection("syc.myclover.org")

for i in range(length):
    for j in range(length):
        for k in range(length):
            conn.request("GET", uri + s[i] + s[j] + s[k] + ".php")
            response = conn.getresponse()
            response.read()
            if response.status == 200:
                print "white_god_s_webshell_%s%s%s" % (s[i], s[j], s[k]) + ".php"
                exit()

第五季極客大挑戰writeup

第五季極客大挑戰writeup

德瑪西亞

第五季極客大挑戰writeup

下載的dhs文件可以用7z解壓縮,打開解壓的文件發現內容是某用戶訪問baidu的cookie,于是可以用劫持到的cookie冒充該用戶登錄百度。

第五季極客大挑戰writeup

利用hackbar修改cookie,刷新登錄百度,該用戶的baidu id是dsploit_test。開始以為flag會在網盤、文庫等地方,找了下沒找到,回到個人中心,發現用戶有貼吧操作痕跡,果斷查看發帖和回帖發現Flag。

第五季極客大挑戰writeup

Web Base1

簡單的Get型注入。

python sqlmap.py –u http://syc.myclover.org/pentest/web1/read.php?id=1 --dbms mysql -D webbase1 -T flag --dump

第五季極客大挑戰writeup

Web Base2

Post搜索型注入。

python sqlmap.py –u http://syc.myclover.org/pentest/web2/search.php --data “key=my” --dbms mysql -D webbase2 -T #flag --dump

第五季極客大挑戰writeup

SQL注入

鏈接是sqlmap.org的山寨頁面,在http response header里發現提示,index.php?id=。分別取id=1/2/3/4,頁面與默認頁面均不同。id=4-1與id=3一樣,id=2%2B1與id=3也一樣,id應該就是所需要的注入點了。 如果直接上sqlmap的話,會發現有mysql的payload,但是sqlmap無法識別database類型。

第五季極客大挑戰writeup

在嘗試多個tamper之后,發現對關鍵字進行保護(對關鍵字添加/!/,如/!select/)的versionedmorekeywords.py能有斬獲,payload發生了變化,也可以跑出一個數據庫。

第五季極客大挑戰writeup

MySQL的表結構都存放在information_schema中,不能訪問這個庫,就無法知道sqli庫的結構,使用common-tables爆破表名也未果。下圖中無法獲取數據庫的個數,當時覺得可能是過濾了information_schema,也沒有想到好的繞過方法,至此暫時陷入了僵局。

第五季極客大挑戰writeup

兩天后,主辦方在頁面注釋中給出了新提示,

原來是吞掉了payload中的union,select和blank。可以用selselect和uniunionon來bypass。tamper中的nonrecursivereplacement.py剛好提供了此功能,但是需要對其稍作修改,keywords = ("UNION", "SELECT", "INSERT", "UPDATE", "WHERE", "FROM")中的后4項應去掉,只保留UNION和SELECT。這也是我之前使用versionedmorekeywords.py和nonrecursivereplacement.py的組合沒跑出來表的原因。 但是到這一步,能跑出information_schema,也能得出sqli庫的表名i_find_key,卻得不出列名,經比對count(tables)和count(column)的payload,發現count(column)多使用了一個關鍵字AND,于是把AND也加入到nonrecursivereplacement.py的keywords中,最終得到Flag。

第五季極客大挑戰writeup

PS:最后一步不知列名,也可以靠手注獲得Flag,前提是i_find_key表僅1列。

第五季極客大挑戰writeup

lfi

既然叫lfi,那就是Local File Inclusion了。

第五季極客大挑戰writeup

第一步要求從博客訪問lfi頁面,那就加上

<code>referer: http://syclover.sinaapp.com/
</code>

第五季極客大挑戰writeup

根據提示file變量有lfi漏洞,讀下readme.php

第五季極客大挑戰writeup

既然Flag is in your_heart,那就讀下your_heart.php,得到Flag。

第五季極客大挑戰writeup

Wireless

第五季極客大挑戰writeup

生成一個syc19800101-syc20001231的字典,用aircrack-ng跑下就有了。

第五季極客大挑戰writeup

F4ck

Jsfu*k編碼,復制所有編碼到瀏覽器console處運行,得到Flag。

第五季極客大挑戰writeup

CodeAudit1

下載附件,對其中index.php進行代碼審查。

<?php
    $id = isset($_GET['syc&amp;id']) ? $_GET['syc&amp;id'] : "";
    $sql = "SELECT id, title FROM news";
    if (!empty($id)) {
        $id = mysql_escape_string($id);
        $sql .= " WHERE id=$id";
    }
    //echo $sql; exit;
    $result = mysql_query($sql);
    $i = 0;
    while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) :
?>

參數syc&id僅僅使用mysql_escape_string進行了轉義而且還沒有引號保護,這就產生了注入點。我們可以使用union查詢把flag從數據庫中搜出來。從codeaudit1.sql中能獲取數據庫的結構。注意&和#需要編碼為%26和%23。

CodeAudit2

掃描codeaudit2的網頁發現存在首頁備份文件index.php.bak,下載下來看看源碼。

<?php
        $username = isset($_POST['username']) ? $_POST['username'] : "";
        $password = isset($_POST['password']) ? $_POST['password'] : "";
        $type = isset($_COOKIE['type']) ? $_COOKIE['type'] : "1";

        if (empty($username) || empty($password) || empty($type)) {
            echo "Credits Can not be empty!";
            exit;
        }

        $username = mysql_escape_string($username);
        $password = mysql_escape_string($password);
        $type = mysql_escape_string($type);

        $sql = "SELECT password FROM user WHERE username='${username}' and type=${type}";
        $result = mysql_query($sql);
        if (mysql_num_rows($result) !== 1) {
            echo "System error!";
            exit;
        }

        $row = mysql_fetch_row($result);
        if ($row[0] == md5(base64_encode($password))) {
            echo "FLAG: *****************";
        }
    ?>

頁面需要正常提供3個參數,username和password是POST型,type是cookie型。我們只需要保證查詢出來的result僅有1行,且輸入的password滿足md5(base64_encode($password))=數據庫中的password,頁面就會自動輸出Flag。

三個參數中username和password有單引號和轉義函數的保護,type參數沒有單引號,因此type是一個cookie型注入點。由于頁面訪問及其不穩定,請求頻率稍微快點服務器就返回502錯誤,而且是基于時間的盲注,即使加上—delay參數,sqlmap也沒能遠程跑出注入點(在本地倒是跑出來基于時間的盲注)。只能尋求手工注入,結合burpsuite,盲注出了username=admin和passoword=fdc4110d6d6612ced3faacd93ee01749。但是password破解不了…,只能另辟蹊徑。

再次審查代碼,發現可以輸入不存在的username,然后利用type的注入點union select任意的密碼,這里可以用concat(16進制的密碼)來bypass對引號的轉義。輸入$password=1,hex(md5(base64_encode($password))) = 0x 6364643936643363633733643164626461666661303363633663643733333962,只需要設置type = 1 union select concat(0x 6364643936643363633733643164626461666661303363633663643733333962)既可得到Flag。

第五季極客大挑戰writeup

來搞站了

第五季極客大挑戰writeup

打開鏈接,是myclover.org的一個分站,主辦方還特意提醒不要上“重型掃描器”…

第五季極客大挑戰writeup

沒啥東西,既然是博客就加上/blog,進了一個wordpress站點。

第五季極客大挑戰writeup

wordpress通常思路是先找出使用了哪些plugin,然后針對爆出過漏洞的plugin進行滲透。這個站點用wordpress專用掃描器wpscan掃了下,僅有一個插件akismet,是一個過濾垃圾留言的。上www.exploit-db.com搜了下該插件,上次出漏洞已經是7年前,心里頓時哇涼哇涼的。

第五季極客大挑戰writeup

接著用wpscan枚舉了下用戶名,僅有一個是admin,也順便使用了wpscan和wpbf(http://www.freebuf.com/tools/36904.html)爆破了下admin口令,感覺太慢,沒有結果。雖然后來得知確實是弱口令,而且在弱口令字典中,不知為毛沒有爆出來…

還有個想法就是社工了,本來自己社工就弱,blog的博主名LateRain基本上也是常見詞,毛都沒射出來。

思路陷入停滯狀態,持續了兩天。兩天后,依然沒人得分,我感覺在做的人不多,抱著死馬當活馬醫的想法,于是挑了個時間上了“重型掃描器”——AWVS。果然不負眾望,掃出了弱口令,我心里那個激動啊。

第五季極客大挑戰writeup

速度使用admin/abc123登進后臺管理。首先上傳插件拿webshell,對shell打了個包,上傳插件,系統提示需要輸入ftp密碼才能上傳,試了下abc123,不對,遂放棄此路,還有其他路子。第二條編輯插件,寫入一句話到頁面中,沒找到保存或更新按鈕,只能換最后一條路了。最后是編輯主題,我在/wp-content/themes/twentytwelve/header.php內插入了一句話,雖然瀏覽器訪問說是500錯誤,但用菜刀還是成功連接。

第五季極客大挑戰writeup

在站點根目錄下有個fd9c8263b299ee07656aa9e18ac0417a.php,Flag就在其中。

第五季極客大挑戰writeup

第五季極客大挑戰writeup

不知道什么情況主辦方回滾了一次,還把弱口令改了,幸好有前人留下的一句話在?http://pt1.myclover.org/blog/wp-content/themes/twentytwelve/content.php,密碼是wood。所以能復現成功。

0x03 reverse


VeryEasy_ELF

既然VeryEasy,直接strings一下,發現疑似flag字符串,拼起來輸入到程序中就是Flag。

第五季極客大挑戰writeup

如花姐姐

第五季極客大挑戰writeup

IDA Pro加載一下ruhua.exe,在sub_401410函數中可以看到注冊成功與否的判斷過程。

第五季極客大挑戰writeup

首先讀取用戶名到v3中,讀取密碼到v5中,用戶名和密碼的長度不能超過10,然后v3和v5分別經函數sub_401500和sub_401530處理后,進行比較,不等就注冊失敗,相等則注冊成功。 再看一下sub_401500和sub_401530。

第五季極客大挑戰writeup

第五季極客大挑戰writeup

偽代碼很簡單,用戶名的每一位是(a[i]^3)-20,密碼的每一位則是(a[i]+2)^0x10,據此可以寫出注冊機。

#!/usr/bin/env python

username = raw_input('Username:')
password = ''
for i in range(len(username)):
    password += chr((((ord(username[i]) ^ 3) - 20) ^ 0x10) - 2)
print "Password:" + password

syclover對應的密碼就是:[email protected]

BMW

反編譯bmw.apk后,有個TheFlagIsNotHere.java的文件中存在一個getKey()函數,直覺告訴我運行完該函數就能獲得Flag。

第五季極客大挑戰writeup

新建一個java class,將代碼copy過來,運行得到Flag。Java代碼如下:

public class bmw 
{
    public static final int LEN = "!0123456789abcdefghijklmnopqrstuvwxyz{}".length();
    public static final String SOURCE = "!0123456789abcdefghijklmnopqrstuvwxyz{}";
    public static String key = "v}f0frqjudwx4dwl3qv2}3xilqgp71";

    public static void main(String[] args) 
    {
        getKey();
    }

    public static void getKey()
    {
        StringBuilder stringbuilder = new StringBuilder();
        key.length();
        int i = 0;
        do
        {
            if(i &gt;= key.length())
                return;
            int j = "!0123456789abcdefghijklmnopqrstuvwxyz{}".indexOf(key.charAt(i));
            if(j == 2)
                j = 2 + LEN;
            if(j == 1)
                j = 1 + LEN;
            if(j == 0)
                j = LEN;
            stringbuilder.append("!0123456789abcdefghijklmnopqrstuvwxyz{}".charAt(j + -3));
            i++;
            System.out.println(stringbuilder);
        } while(true);
    }
}

運行結果如圖:

第五季極客大挑戰writeup

女神

第五季極客大挑戰writeup

題目給了一個PE程序,首先PEid查了下源程序,帶了UPX的殼,恰好PEid自帶的插件能脫。

第五季極客大挑戰writeup

脫完之后,OD加載程序,逐步分析,在GetDlgItemTextA處下斷點,從獲取到用戶輸入的Key后開始分析。

004011D4    8D7C24 10       lea     edi, dword ptr [esp+0x10]       ; esp+0x10=key的起始地址
004011D8    83C9 FF         or      ecx, 0xFFFFFFFF 
004011DB    33C0            xor     eax, eax    
004011DD    F2:AE           repne   scas byte ptr es:[edi]  
004011DF    F7D1            not     ecx 
004011E1    49              dec     ecx 
004011E2    83F9 0D         cmp     ecx, 0xD                        ; length(key)=13
004011E5    0F85 F0000000   jnz     004012DB    

004011ED    8A440C 10       mov     al, byte ptr [esp+ecx+0x10] 
004011F1    3C 30           cmp     al, 0x30                        ; key[i]&gt;=0x30
004011F3    0F8C E2000000   jl      004012DB    
004011F9    3C 39           cmp     al, 0x39                        ; key[i]&lt;=0x39
004011FB    0F8F DA000000   jg      004012DB    

00401207    0FBE7C24 16     movsx   edi, byte ptr [esp+0x16]        ; edi=key[6]
0040120C    0FBE4C24 10     movsx   ecx, byte ptr [esp+0x10]        ; ecx=key[0]
00401211    0FBE5424 19     movsx   edx, byte ptr [esp+0x19]        ; edx=key[9]
00401216    8D4439 A0       lea     eax, dword ptr [ecx+edi-0x60]   ; eax=key[6]+key[0]-0x60
0040121A    83EA 26         sub     edx, 0x26                       ; edx=key[9]-0x26
0040121D    3BC2            cmp     eax, edx                        ; key[6]+key[0]-0x60=key[9]-0x26
0040121F    0F85 B6000000   jnz     004012DB    

00401225    8A5C24 17       mov     bl, byte ptr [esp+0x17]         ; bl=key[7]
00401229    8D41 D0         lea     eax, dword ptr [ecx-0x30]   
0040122C    99              cdq     
0040122D    0FBEF3          movsx   esi, bl                         ; esi=key[7]
00401230    83E2 03         and     edx, 0x3    
00401233    03C2            add     eax, edx    
00401235    8D56 D0         lea     edx, dword ptr [esi-0x30]       ; edx=key[7]-0x30
00401238    C1F8 02         sar     eax, 0x2                        ; eax=(key[0]-0x30)&gt;&gt;2
0040123B    3BC2            cmp     eax, edx                        ; (key[0]-0x30)&gt;&gt;2=key[7]-0x30
0040123D    0F85 98000000   jnz     004012DB    

00401243    385C24 14       cmp     byte ptr [esp+0x14], bl         ; key[4]=key[7]
00401247    0F85 8E000000   jnz     004012DB    

0040124D    0FBE4424 11     movsx   eax, byte ptr [esp+0x11]    
00401252    8D1430          lea     edx, dword ptr [eax+esi]    
00401255    03D1            add     edx, ecx    
00401257    03D7            add     edx, edi                        ; edx=key[0]+key[1]+key[6]+key[7]
00401259    81FA D4000000   cmp     edx, 0xD4                       ; key[0]+key[1]+key[6]+key[7]=0xD4
0040125F    75 7A           jnz     short 004012DB  

00401261    0FBE5424 12     movsx   edx, byte ptr [esp+0x12]    
00401266    0FBE7424 15     movsx   esi, byte ptr [esp+0x15]    
0040126B    03F2            add     esi, edx                        ; esi=key[2]+key[5]
0040126D    03C1            add     eax, ecx                        ; eax=key[0]+key[1]
0040126F    3BC6            cmp     eax, esi                        ; key[2]+key[5]=key[0]+key[1]
00401271    75 68           jnz     short 004012DB  

00401273    0FBE4424 13     movsx   eax, byte ptr [esp+0x13]        ; eax=key[3]
00401278    42              inc     edx                             ; edx=key[2]+1
00401279    3BD0            cmp     edx, eax                        ; key[2]+1=key[3]
0040127B    75 5E           jnz     short 004012DB  

0040127D    807C24 16 38    cmp     byte ptr [esp+0x16], 0x38       ; key[6]=0x38
00401282    75 57           jnz     short 004012DB  
00401284    807C24 10 39    cmp     byte ptr [esp+0x10], 0x39       ; key[0]=0x39
00401289    75 50           jnz     short 004012DB  
0040128B    807C24 18 30    cmp     byte ptr [esp+0x18], 0x30       ; key[8]=0x30
00401290    75 49           jnz     short 004012DB  

00401294    B1 32           mov     cl, 0x32    
00401296    384C04 10       cmp     byte ptr [esp+eax+0x10], cl     ; key[i]=0x32?
0040129A    75 01           jnz     short 0040129D  
0040129C    45              inc     ebp                             ; ebp=count(key[i]==0x32)
0040129D    40              inc     eax 
0040129E    83F8 0D         cmp     eax, 0xD    
004012A1    7C F3           jl      short 00401296  
004012A3    83FD 03         cmp     ebp, 0x3                        ; count(key[i]==0x32)=3
004012A6    75 33           jnz     short 004012DB  

004012A8    0FBE4424 1B     movsx   eax, byte ptr [esp+0x1B]    
004012AD    0FBE4C24 1A     movsx   ecx, byte ptr [esp+0x1A]        ; ecx=key[10]
004012B2    8D50 FF         lea     edx, dword ptr [eax-0x1]        ; edx=key[11]-1
004012B5    3BCA            cmp     ecx, edx                        ; key[10]=key[11]-1
004012B7    75 22           jnz     short 004012DB  

004012B9    83C1 D0         add     ecx, -0x30  
004012BC    83C0 D0         add     eax, -0x30  
004012BF    0FAFC8          imul    ecx, eax                        ; ecx=key[10]*key[11]
004012C2    0FBE4424 1C     movsx   eax, byte ptr [esp+0x1C]    
004012C7    83E8 30         sub     eax, 0x30                       ; eax=key[12]
004012CA    33D2            xor     edx, edx    
004012CC    3BC8            cmp     ecx, eax                        ; key[10]*key[11]=key[12]

有了上述各個條件,加上key2=0x35的提示,容易分析出9156258207236就是Key。

第五季極客大挑戰writeup

toosimple?附件又是一個apk,反編譯后幾個java文件翻了翻,沒有結果,但是發現了一個libgetKey.so,是個ELF文件,果斷祭出IDA,果不其然發現了關鍵函數calculateKey()。

第五季極客大挑戰writeup

順著偽代碼寫了個腳本,運行下得到Flag。

#!/usr/bin/env python
str = '[email protected],!fWj&Bpa=zlemIu6}'
dest = list(str)
v0 = 11
v1 = 1 
v2 = 0
while v2 != 21:
    v3 = ord(dest[v2])
    if v2 &gt; 10:
        dest[v2] = chr(v3 - v0)
        v0 -= 1
    else:
        dest[v2] = chr(v3 + v1)
        v1 += 1
    v2 += 1
print "Flag:"+''.join(dest)

第五季極客大挑戰writeup

ATM

第五季極客大挑戰writeup

先本地運行程序,同時用IDA加載。

第五季極客大挑戰writeup

sub_804859E即輸出上面的部分。要求覆蓋到存放money的內存地址為0x63795324,即$Syc,下圖中對應的是a1的內存地址,同時a1也是sub_804859E函數的參數。

第五季極客大挑戰writeup

第五季極客大挑戰writeup

再看下接收輸入的函數sub_804872A。

第五季極客大挑戰writeup

v22是我們的輸入部分,v24作為存放money的參數帶入sub_804859E中運行。由于沒有對輸入v22的長度做校驗,我們就可以輸入較長字符串來覆蓋掉v24的內存地址,達到目的。下面看下v22和v24之間地址差,以便確定需要多長的shellcode。

第五季極客大挑戰writeup

因此只需要0x3C-0x1A=34個字符及就能覆蓋掉v22到v24之間的內存地址,再加上$Syc就能使money=0x63795324。因此shellcode可以取為a*34+$Syc。本地溢出的結果如圖。

第五季極客大挑戰writeup

EasyElf

出了一個VeryEasy_ELF,又來一個EasyELF,IDA加載下,下面的else分支,有疑似flag。輸入的password存在v14處,v14與疑似flag字樣進行比較,比對正確提交卻不正確。真正的True flag在上面的if分支中,與用戶輸入無關。

第五季極客大挑戰writeup

第五季極客大挑戰writeup

根據偽代碼的腳本如下,運行得到Flag。

#!/usr/bin/env python

v3 = '\x69\x75\x6f\x63\x67\x71\x70\x67'
v13 = [''] * 8
i = 7
while i >= 0:
    v13[i] = chr((ord(v3[7 - i])) - i)
    i -= 1
print 'Flag:SYC{'+''.join(v13)+'}'

第五季極客大挑戰writeup

00xx

第五季極客大挑戰writeup

開始不知道啥叫SEH,百度百科上是這么說的:SEH("Structured Exception Handling"),即結構化異常處理,是(windows)操作系統提供給程序設計者的強有力的處理程序錯誤或異常的武器。OD加載00xx時,在獲取到用戶輸入后,單步運行很容易產生異常,然后程序就結束了。但是可以通過一些內存地址來跳過這些異常。 首先在GetDlgItemTextW處下斷,輸入后,程序返回到0040111F,運行完0040111F后,應修改EIP(CPU區域右鍵有個New origin here選項就是EIP跳轉功能)直接跳轉到00401136。然后F7進入到目標函數00401190。

第五季極客大挑戰writeup

運行完00401193,應直接跳轉到004011A3處,從這里開始程序將00403018處的unicode字符串sYC.與00403378處輸入字符串的前4位分別作異或,結果存放在00403388處

第五季極客大挑戰writeup

第五季極客大挑戰writeup

第五季極客大挑戰writeup

運行完004011ED后,應直接跳轉到00401206處,從這里開始程序開始處理輸入字符串第4位之后的部分,0040123A處要求上面異或后的4位相加=wtoi(key[4:])+0x3E,滿足此條件后,再判斷異或后的前3位是不是”C6;”。因此可以退出key的前3位分別是0x43^0x73,0x36^0x59,0x3B^0x43,對應的是”0ox”。

第五季極客大挑戰writeup

但是這里沒有對key3做限制,事實上只要滿足key4^0x2E+0x76=wtoi(key[4:]),均能注冊成功。

第五季極客大挑戰writeup

唯一能解釋最終flag(0oxX236)的只有題目叫00xx了。 溢出和SEH這塊確實不怎么會,有不對的地方,請大牛們批評指正。

0x04 program


XOR

第五季極客大挑戰writeup

題目提示XOR以及與正常程序的比對,那就將out.exe前4字節7D 6B A0 31和正常程序00xx.exe前4字節4D 5A 90 00異或下得到30 31 30 31,猜測所謂的加密就是源程序每兩字節分別與30 31異或,下面是解密代碼。

#!/usr/bin/env python

f1 = open('out.exe', 'r')
out = list(f1.read())
xor = [0x30, 0x31]
for i in range(len(out)):
    out[i] = chr(ord(out[i]) ^ xor[i % 2])
f1.close()

f2 = open('xor.exe', 'w')
f2.write(''.join(out))
f2.close()

運行輸出的xor.exe拿到Flag。

第五季極客大挑戰writeup

LIGHT

第五季極客大挑戰writeup

開窗游戲的算法,我參考了一篇論文《華容道、開窗等經典智力問題的求解算法研究》。下面是原文中對算法的解釋。 經過分析得知,操作順序不影響操作結果,對一個窗戶操作偶數次等價于操作0次(即不操作);操作奇數次等價于操作1次,故最后的解答的形式可以表示為一個數組a(i, j)。窗子(i, j)不需要操作時,a(i, j)=0;窗子(i, j)需要操作一次時,a(i, j)=1。 因為每個窗戶(i, j)有兩種狀態,一共有mn個,所以一共有2nm 種可能,時間復雜度很大。進一步分析可知,窗子(i, j)的狀態只與以下因素有關:窗子(i, j)的初始狀態,以及a(i, j),a(i-1, j),a(i+1, j),a(i, j-1),a(i, j+1)。假設已經確定第一行的每個窗子是否操作,則對于窗子(1, j),由于窗子(1,j)的初始顏色以及a(1, j),a(i, j-1),a(i, j+1)都已確定,則該窗子的顏色只能由a(i+1, j)來調整。模擬第一行的操作過程后,若a(1, j)仍為開,則必須a(2, j)=1才能使窗子(1, j)滿足條件;同理當a(1, j)為關時,可知a(2, j)=0,這樣a(2, j)(1≤j≤n)也已經確定,依此類推可推出所有a(i, j)的值(1≤i≤m, 1≤j≤n ),最后驗證最后一行窗子是否都已關閉即可。 從而可以枚舉第一行每個窗子是否操作,共需枚舉2n種可能。對于每種可能按以上方法進行遞推,找出其中可使最后一行均為關閉的方案即可。具體算法如下(C#):

/************************************************************
請將1.txt置于Light.exe同路徑下程序自動讀取1.txt的狀態進行求解
************************************************************/
using System;
using System.Collections.Generic;
using System.IO;

namespace LIGHT
{
    class Program
    {
        private static int m = 0, n = 0;                            // 窗戶的行數m和列數n
        private static int[,] window;                               // 窗戶的狀態數組
        private static List<String> solution = new List<string>();  // 最終的解法
        static void Main(string[] args)
        {
            init();  //讀取1.txt并初始化window[m,n]

            if (solve())
            {
                Console.WriteLine("Solved!");
                foreach (string s in solution)
                {
                    Console.Write(s + " ");
                }
            }
            else
                Console.WriteLine("Can't solve!");
            Console.ReadKey();
        }

        public static void init()
        {
            List<String> state = new List<string>();  //以行為單位存放1.txt中的內容
            try
            {
                FileStream fs = new FileStream("./1.txt", FileMode.Open);
                StreamReader sr = new StreamReader(fs);
                string strLine = null;
                while ((strLine = sr.ReadLine()) != null)
                {
                    state.Add(strLine);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                Environment.Exit(0);
            }

            m = state.Count;
            n = state[0].Length;
            window = new int[m, n];
            for (int i = 0; i < m; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    window[i, j] = Int32.Parse(state[i][j].ToString());
                }
            }
        }

        public static bool solve()  // 全變成0,return true; 不能全變成0,return false
        {
            int max = (int)Math.Pow(2, n);
            for (int k = 0; k < max; k++)  // 對第一行的所有可能進行枚舉
            {
                int r = k;
                int[,] tmp = new int[m, n];

                for (int i = 0; i < m; i++)  // 將原始情況復制到臨時數組中操作
                {
                    for (int j = 0; j < n; j++)
                    {
                        tmp[i, j] = window[i, j];
                    }
                }

                for (int j = 0; j < n; j++)  // 第一行
                {
                    if (r % 2 == 1)
                    {
                        change(0, j, tmp);
                        solution.Add("(" + 1 + "," + (j + 1) + ")");
                    }
                    r = r / 2;
                }

                for (int i = 1; i < m; i++)  // 遞推后面的行
                {
                    for (int j = 0; j < n; j++)
                    {
                        if (tmp[i - 1, j] == 1)
                        {
                            change(i, j, tmp);
                            solution.Add("(" + (i + 1) + "," + (j + 1) + ")");
                        }
                    }
                }

                bool check = true;
                for (int j = 0; j < n; j++)  // 驗證最后一行是否全是0
                {
                    if (tmp[m - 1, j] == 1)
                    {
                        check = false;
                        solution.Clear();
                        break;
                    }
                }
                if (check)
                    return true; // 全0有解!
            }
            return false;  // 無解
        }

        private static void change(int i, int j, int[,] tmp)  // 開關窗操作,分9種情形
        {
            tmp[i, j] = swap(tmp[i, j]);
            if (0 < i && i < m - 1 && 0 < j && j < n - 1)
            {
                tmp[i, j - 1] = swap(tmp[i, j - 1]);
                tmp[i - 1, j] = swap(tmp[i - 1, j]);
                tmp[i, j + 1] = swap(tmp[i, j + 1]);
                tmp[i + 1, j] = swap(tmp[i + 1, j]);
                return;
            }
            if (0 < i && i < m - 1 && j == 0)
            {
                tmp[i - 1, 0] = swap(tmp[i - 1, 0]);
                tmp[i, 1] = swap(tmp[i, 1]);
                tmp[i + 1, 0] = swap(tmp[i + 1, 0]);
                return;
            }
            if (i == 0 && 0 < j && j < n - 1)
            {
                tmp[0, j - 1] = swap(tmp[0, j - 1]);
                tmp[0, j + 1] = swap(tmp[0, j + 1]);
                tmp[1, j] = swap(tmp[1, j]);
                return;
            }
            if (0 < i && i < m - 1 && j == n - 1)
            {
                tmp[i, n - 2] = swap(tmp[i, n - 2]);
                tmp[i - 1, n - 1] = swap(tmp[i - 1, n - 1]);
                tmp[i + 1, n - 1] = swap(tmp[i + 1, n - 1]);
                return;
            }
            if (i == m - 1 && 0 < j && j < n - 1)
            {
                tmp[m - 1, j - 1] = swap(tmp[m - 1, j - 1]);
                tmp[m - 2, j] = swap(tmp[m - 2, j]);
                tmp[m - 1, j + 1] = swap(tmp[m - 1, j + 1]);
                return;
            }
            if (i == 0 && j == 0)
            {
                tmp[0, 1] = swap(tmp[0, 1]);
                tmp[1, 0] = swap(tmp[1, 0]);
                return;
            }
            if (i == 0 && j == n - 1)
            {
                tmp[0, n - 2] = swap(tmp[0, n - 2]);
                tmp[1, n - 1] = swap(tmp[1, n - 1]);
                return;
            }
            if (i == m - 1 && j == n - 1)
            {
                tmp[m - 1, n - 2] = swap(tmp[m - 1, n - 2]);
                tmp[m - 2, n - 1] = swap(tmp[m - 2, n - 1]);
                return;
            }
            if (i == m - 1 && j == 0)
            {
                tmp[m - 2, 0] = swap(tmp[m - 2, 0]);
                tmp[m - 1, 1] = swap(tmp[m - 1, 1]);
                return;
            }
        }

        private static int swap(int i)
        {
            return (i == 1) ? 0 : 1;
        }
    }
}

題中提供初始情況的運行結果如下:

第五季極客大挑戰writeup

小菜一碟

第五季極客大挑戰writeup

e有多種取值,但是最終的明文能被識別的很少。鑒于e不大,可以枚舉出所有可能的e,看了下結果,發現有一種情形明文每個位置的值都在130以下,能按ascii解碼。

#!/usr/bin/env python

def foo(num1, num2, cmd):
    q = r = s = t = 0
    r1 = num1
    r2 = num2
    s1 = t2 = 1
    s2 = t1 = 0

    while r2 > 0:
        q = int(r1 / r2)
        r = r1 % r2
        s = s1 - q * s2
        t = t1 - q * t2

        r1 = r2
        r2 = r
        s1 = s2
        s2 = s
        t1 = t2
        t2 = t

    if cmd == 1:  # cmd = 1, return gcd(num1,num2)
        return r1
    if cmd == 2:  # cmd = 2, reyurn num^(-1)(mod num2) 
        if s1 < 0:
            return s1 + num2
        return s1

cipher = [1286,7792,11086,13837,4162,11482,3562,383,15995,21350,15374,3562,8713,15995,3267,16051,18518,16194,3562,15995,15374]
n = 23651
f = 23232

length = len(cipher)
e = []
for i in range(3, 10000, 2):
    if foo(i, f, 1) == 1:
        e.append(i)

for j in range(len(e)):
    d = foo(e[j], f, 2)
    plain = []
    for k in range(length):
        plain.append(pow(cipher[k], d, n))

    flag = True
    for l in range(length):
        if plain[l] > 128:
            flag = False
    if flag:
        for m in range(length):
            plain[m] = chr(plain[m])
        print 'e = %4d d = %5d plain = %s' % (e[j], d, "".join(plain))

運行結果:

第五季極客大挑戰writeup

0x05 #linux


奇怪的txt

解壓附件得到一個key.txt,中間部分是實際文件的二進制碼,能看出是一個BZ2文件,右側是對應的ASCII值。

第五季極客大挑戰writeup

寫一個腳本將中間部分復制出來到一個新文件中。

#!/usr/bin/env python

import binascii

f = open('key.txt','r')
content = ''
for line in f.readlines():
    content += line[9:49]
f.close()
content = content.replace(' ','')

he = binascii.a2b_hex(content)
f1 = open('newkey.bz2','w')
f1.write(he)
f1.close()

運行后得到newkey.bz2,解壓三次后得到一個key文件。base64decode一下得到FLAG:SYC{L1nux_taR_gZ1p_SYC}。

第五季極客大挑戰writeup

史上第二難的題目

第五季極客大挑戰writeup

運行下程序,結果是10000行9位數,多次運行發現每次的結果都一致。將運行結果復制到文件中,讀取文件進行排序。

#!/usr/bin/env python

f = open('lin2.txt','r')
num = list()
for line in f.readlines():
    num.append(line[0:9])
f.close()
num.sort()
print num[6249]

運行結果如圖。

第五季極客大挑戰writeup

lalala

第五季極客大挑戰writeup

源程序在我的kali上無法運行,一直沒找到libcrypto.so.1.0.0,求大神指教。

第五季極客大挑戰writeup

不能運行那就上IDA吧,據題意及f5得到的偽代碼來看,這里應該用的是RC4加密算法。輸入的4個ASCII碼數字做密鑰,下圖紅框中應該是密文,用密鑰解密密文,若解出來的明文前三字符以SYC(83 89 67)開頭,則明文就是Flag。

第五季極客大挑戰writeup

我們就可以針對密文進行爆破,下面是爆破腳本。

#!/usr/bin/env python

def rc4(data, key):
    #if the data is a string, convert to hex format.
    if(type(data) is type("string")):
        tmpData = data
        data = []
        for tmp in tmpData:
            data.append(ord(tmp))

    #if the key is a string, convert to hex format.
    if(type(key) is type("string")):
        tmpKey = key
        key = []
        for tmp in tmpKey:
            key.append(ord(tmp))

    #the Key-Scheduling Algorithm
    x = 0
    box = list(range(256))
    for i in range(256):
        x = (x + box[i] + key[i % len(key)]) % 256
        box[i], box[x] = box[x], box[i]

    #the Pseudo-Random Generation Algorithm
    x = 0
    y = 0
    out = []
    for c in data:
        x = (x + 1) % 256
        y = (y + box[x]) % 256
        box[x], box[y] = box[y], box[x]
        out.append(c ^ box[(box[x] + box[y]) % 256])

    result = ""
    printable = True
    for tmp in out:
        if(tmp < 0x21 or tmp > 0x7e):
            # there is non-printable character
            printable=False
            break
        result += chr(tmp)

    if(printable == False):
        result = ""
        #convert to hex string   
        for tmp in out:
            result += "{0:02X}".format(tmp)

    return result

if __name__ == '__main__':
    a = '!"#$%&\'()*+,-./0123456789:;<=>[email protected][\\]^_`abcdefghijklmnopqrstuvwxyz{|}~'
    b = ')}'
    length = len(a)
    ciphertext = '\x5F\x20\x6B\x24\x1C\x48\xCA\xFC\xF5\x41\x2D\xD4\xDA'

    for i in range(length):
        for j in range(length):
            for k in range(length):
                for l in range(len(b)):
                    key = a[i] + a[j] + a[k] + b[l]
                    plaintext = rc4(ciphertext, key)
                    if plaintext[0:3]=='SYC':
                        print '%s %s' % (key,plaintext)
                        exit(0)

其中RC4算法來自http://blog.csdn.net/white_eyes/article/details/6560355。運行得到

第五季極客大挑戰writeup

密鑰是@#()。我想了下主辦方干嘛要限制第4個字符呢,于是把第4個字符范圍擴大到所有可見字符,原來還有一解:'g=C,對應的十六進制明文是5359432B17FA53419C25E9979E,恰好也是SYC開頭。

第五季極客大挑戰writeup

最后附上題目附件及我用到的代碼和參考的論文。部分py如運行不順,請在linux中運行。

鏈接: http://pan.baidu.com/s/1eQs0u6A 密碼: hv8e


//下面這個css和插件后臺設置的主題有關系,如果需要換樣式,則需要修改以下CSS名稱

 

除特別注明外,本站所有文章均為鐵匠運維網原創,轉載請注明出處來自http://www.kzrhud.live/25258.html

中國互聯是江蘇邦寧科技有限公司旗下的著名IT服務供應商品牌之一,是國內IDC行業十大之一、企業互聯網服務首選品牌。江蘇邦寧科技成立于2003年,是國內互聯網名稱與數字地址服務、云數據中心機房服務的引領者,是行業云計算解決方案、網站智能建設、企業智能辦公軟件、移動互聯網開發的創新者。自成立以來,公司秉承“一切為了客戶滿意”的核心理念,堅持“國際化、專業化、高端化”的發展思路,堅持“以客戶需求為導向、以技術創新為基礎、以服務創新為支撐”,先后為國內各級政府、社會服務機構、國內外眾多500強企業及中小企業、個人客戶提供了專業、高質、優越的互聯網應用服務。

發表評論

暫無評論

切換注冊

登錄

忘記密碼 ?

您也可以使用第三方帳號快捷登錄

切換登錄

注冊

掃一掃二維碼分享
青海11选5开奖结果走势图