• [GXYCTF2019]simple CPP


    [GXYCTF2019]simple CPP

    一.查壳

    无壳,64位程序

    二.IDA分析

    找到主函数后动态调试,看的更清楚

    经过调试后我们可以找到len就是储存字符串长度的变量,之后判断长度是不是大于30,不是的话继续,然后将输入的字符串分别与v7中的内容异或,而v7是经过动调发现是

    之后再进行一次长度判断,然后进入一个循环将加密后的字符串进行堆叠,例如字符串原本是A1B2,进行堆叠后储存到一个整型里就是

    0x41314232,然后满8位储存一次,最后一次不满8位的储存到v8,然后有一个判断是否动调的语句,修改RIP值进行绕过,后面的逻辑主要是对储存到v15这个数组中的数进行一些操作,也就是堆叠后的结果进行一些操作,我们可以直接使用z3解方程

    脚本来自大师傅(白嫖

    # -*- coding:utf-8 -*-
    
    from z3 import *
    
    x,y,z,w=BitVecs('x y z w',64)
    
    s=Solver()
    
    s.add((~x)&z==1176889593874)
    s.add(((z&~x)|(x&y)|(z&(~y))|(x&(~y)))^w==4483974543195470111)
    s.add(((z&~y)&x|z&((x&y)|y&~x|~(y|x)))==577031497978884115)
    s.add(((z&~x)|(x&y)|(z&~y)|(x&~y))==4483974544037412639)
    s.add(((z&(~x)) | (x&y) | y & z) == (((~x)& z)|864693332579200012))
    
    s.check()
    m = s.model()
    for i in m:
        print("%s = 0x%x"%(i,m[i].as_long()))
    

    然后可以得到

    Python>
    w = 0x32310600
    z = 0x8020717153e3013
    y = 0xc0002293008acac
    x = 0x3e3a460533286f0d
    

    而几个解就是储存到v15数组的值,我们反推,由于解是堆叠出来的 ,我们可以去掉堆叠,还原原本字符串

    # -*- coding:utf-8 -*-
    
    from z3 import *
    
    debug_str = "i_will_check_is_debug_or_not"
    x,y,z,w=BitVecs('x y z w',64)
    
    s=Solver()
    
    s.add((~x)&z==1176889593874)
    s.add(((z&~x)|(x&y)|(z&(~y))|(x&(~y)))^w==4483974543195470111)
    s.add(((z&~y)&x|z&((x&y)|y&~x|~(y|x)))==577031497978884115)
    s.add(((z&~x)|(x&y)|(z&~y)|(x&~y))==4483974544037412639)
    s.add(((z&(~x)) | (x&y) | y & z) == (((~x)& z)|864693332579200012))
    
    s.check()
    m = s.model()
    for i in m:
        print("%s = 0x%x"%(i,m[i].as_long()))
    flag=""
    li=[]
    # 拼接
    li.append(hex(m[x].as_long())[2:].rjust(16,"0"))
    li.append(hex(m[y].as_long())[2:].rjust(16,"0"))
    li.append(hex(m[z].as_long())[2:].rjust(16,"0"))
    li.append(hex(m[w].as_long())[2:-2])
    print(li)
    

    得到

    ['3e3a460533286f0dL', '8c008a0978492cacL', '8020717153e3013L', '323106']
    

    最后

    Dst = 'i_will_check_is_debug_or_noi_wil'
    flag=[0x3E,0x3A,0x46,0x05,0x33,0x28,0x6F,0x0D,0x8C,0x00,0x8A,0x09,0x78,0x49,0x2C,0xAC,0x08,0x02,0x07,0x17,0x15,0x3E,0x30,0x13,0x32,0x31,0x06]
    s=''
    for i in range(len(flag)):
        s+=chr(ord(Dst[i]) ^ flag[i])
    print(s)
    

    这个时候发现结果

    We1l_D0n�e�b' _�lgebra_am_i

    似乎不对,找到原因是方程不止一个解,而比赛的时候给出了第二部分的结果e!P0or_a

    最终得到

    We1l_D0ne!P0or_algebra_am_i

  • 相关阅读:
    小试牛刀,建立jsp网页与导出war包
    IDEA 官方背景与修改jsp模板以及字体大小
    类库日期和jsp导包
    eclipse配置
    mysql绿色版下载及应用
    创建一个学生信息表,与页面分离
    Tomcat配置
    c#简单加密和对称加密
    04面向对象基础
    ADO.NET复习——自己编写SqlHelper类
  • 原文地址:https://www.cnblogs.com/LLeaves/p/13522069.html
Copyright © 2020-2023  润新知