<span id="7ztzv"></span>
<sub id="7ztzv"></sub>

<span id="7ztzv"></span><form id="7ztzv"></form>

<span id="7ztzv"></span>

        <address id="7ztzv"></address>

            原文地址:http://drops.wooyun.org/tips/3434

            0x01 misc


            too young too simple

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

            enter image description here

            enter image description here

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

            enter image description here

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

            enter image description here

            你喜不喜歡萌萌噠的姐姐

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

            enter image description here

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

            enter image description here

            下面是解碼腳本。

            #!/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。

            enter image description here

            開胃小菜

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

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

            enter image description here

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

            enter image description here

            白神的假期

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

            enter image description here

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

            enter image description here

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

            reg

            enter image description here

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

            enter image description here

            bilibili

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

            0x02 pentest


            HTTP Base1

            Flag在HTTP response header中。

            enter image description here

            HTTP Base2

            enter image description here

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

            enter image description here

            HTTP Base3

            enter image description here

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

            enter image description here

            CrackPWD1

            enter image description here

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

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

            enter image description here

            CrackPWD2

            enter image description here

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

            enter image description here

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

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

            enter image description here

            美男子

            enter image description here

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

            enter image description here

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

            Login

            enter image description here

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

            admin\flag\key\KEY\user\login\submit
            

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

            enter image description here

            白神的shell

            enter image description here

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

            #!/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()
            

            enter image description here

            enter image description here

            德瑪西亞

            enter image description here

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

            enter image description here

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

            enter image description here

            Web Base1

            簡單的Get型注入。

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

            enter image description here

            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
            

            enter image description here

            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類型。

            enter image description here

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

            enter image description here

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

            enter image description here

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

            原來是吞掉了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。

            enter image description here

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

            enter image description here

            lfi

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

            enter image description here

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

            referer: http://syclover.sinaapp.com/
            

            enter image description here

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

            enter image description here

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

            enter image description here

            Wireless

            enter image description here

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

            enter image description here

            F4ck

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

            enter image description here

            CodeAudit1

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

            <?php
                $id = isset($_GET['syc&id']) ? $_GET['syc&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。

            enter image description here

            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。

            enter image description here

            來搞站了

            enter image description here

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

            enter image description here

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

            enter image description here

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

            enter image description here

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

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

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

            enter image description here

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

            enter image description here

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

            enter image description here

            enter image description here

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

            0x03 reverse


            VeryEasy_ELF

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

            enter image description here

            如花姐姐

            enter image description here

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

            enter image description here

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

            enter image description here

            enter image description here

            偽代碼很簡單,用戶名的每一位是(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對應的密碼就是:JtZIFo@K

            BMW

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

            enter image description here

            新建一個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 >= 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);
                }
            }
            

            運行結果如圖:

            enter image description here

            女神

            enter image description here

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

            enter image description here

            脫完之后,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]>=0x30
            004011F3    0F8C E2000000   jl      004012DB    
            004011F9    3C 39           cmp     al, 0x39                        ; key[i]<=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)>>2
            0040123B    3BC2            cmp     eax, edx                        ; (key[0]-0x30)>>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。

            enter image description here

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

            enter image description here

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

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

            enter image description here

            ATM

            enter image description here

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

            enter image description here

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

            enter image description here

            enter image description here

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

            enter image description here

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

            enter image description here

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

            enter image description here

            EasyElf

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

            enter image description here

            enter image description here

            根據偽代碼的腳本如下,運行得到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)+'}'
            

            enter image description here

            00xx

            enter image description here

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

            enter image description here

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

            enter image description here

            enter image description here

            enter image description here

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

            enter image description here

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

            enter image description here

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

            0x04 program


            XOR

            enter image description here

            題目提示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。

            enter image description here

            LIGHT

            enter image description here

            開窗游戲的算法,我參考了一篇論文《華容道、開窗等經典智力問題的求解算法研究》。下面是原文中對算法的解釋。 經過分析得知,操作順序不影響操作結果,對一個窗戶操作偶數次等價于操作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;
                    }
                }
            }
            

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

            enter image description here

            小菜一碟

            enter image description here

            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))
            

            運行結果:

            enter image description here?

            0x05 #linux


            奇怪的txt

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

            enter image description here

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

            #!/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}。

            enter image description here

            史上第二難的題目

            enter image description here

            運行下程序,結果是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]
            

            運行結果如圖。

            enter image description here

            lalala

            enter image description here

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

            enter image description here

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

            enter image description here

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

            #!/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:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`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。運行得到

            enter image description here

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

            enter image description here

            最后附上題目附件及我用到的代碼和參考的論文。部分py如運行不順,請在linux中運行。 鏈接: http://pan.baidu.com/s/1eQs0u6A 密碼: hv8e

            <span id="7ztzv"></span>
            <sub id="7ztzv"></sub>

            <span id="7ztzv"></span><form id="7ztzv"></form>

            <span id="7ztzv"></span>

                  <address id="7ztzv"></address>

                      亚洲欧美在线