NKCTF的login_system题解复现

1、脱壳

1、好像需要upx脱壳,直接工具脱了 upx -d

2、查看用户名的答案

2d51d1b25cf8403d93faed04cbebd0a6.png

使用z3进行求解

from z3 import *
s=Solver()#创建约束器
a1=[Int('a1%d'%i)for i in range(0,16)]#创建整数约束变量,一次创建多个
#下面添加约束条件
s.add(a1[2] + a1[1] + a1[0] + a1[3] == 447)
s.add(101 * a1[2] + a1[0] + 9 * a1[1] + 8 * a1[3] == 12265)
s.add(5 * a1[2] + 3 * a1[0] + 4 * a1[1] + 6 * a1[3] == 2000)
s.add(88 * a1[2] + 12 * a1[0] + 11 * a1[1] + 87 * a1[3] == 21475)
s.add(a1[6] + 59 * a1[5] + 100 * a1[4] + a1[7] == 7896)
s.add(443 * a1[4] + 200 * a1[5] + 10 * a1[6] + 16 * a1[7] == 33774)
s.add(556 * a1[5] + 333 * a1[4] + 8 * a1[6] + 7 * a1[7] == 44758)
s.add(a1[6] + a1[5] + 202 * a1[4] + a1[7] == 9950)
s.add(78 * a1[10] + 35 * a1[9] + 23 * a1[8] + 89 * a1[11] == 24052)
s.add(78 * a1[8] + 59 * a1[9] + 15 * a1[10] + 91 * a1[11] == 25209)
s.add(111 * a1[10] + 654 * a1[9] + 123 * a1[8] + 222 * a1[11] == 113427)
s.add(6 * a1[9] + 72 * a1[8] + 5 * a1[10] + 444 * a1[11] == 54166)
s.add(56 * a1[14] + 35 * a1[12] + 6 * a1[13] + 121 * a1[15] == 11130)
s.add(169 * a1[14] + 158 * a1[13] + 98 * a1[12] + 124 * a1[15] == 27382)
s.add(147 * a1[13] + 65 * a1[12] + 131 * a1[14] + 129 * a1[15] == 23564)
s.add(137 * a1[14] + 132 * a1[13] + 620 * a1[12] + 135 * a1[15] == 51206)
​
s.check()#检查是否可以有解
result=s.model()#将结果赋值给result
print(result)
flag=''
​
for i in range(16):
    flag+=chr(result[a1[i]].as_long().real)
    #得到的结果有复数形式,所以需要得到他的实数(我也不清楚,直接输出显示类型错误,不都是整数类型)上面的as_long().real的意思是将上面的实部数据转换进行提取,此处有点不理解
print(flag)
​

3、查看密码的答案

43d2edfef3fa49fba9c42288de273496.png

 

可以发现应该是AES加密,而且是换了盒的AES加密,所以进行换盒操作

此处贴上AES解密代码

from z3 import *
import binascii
import re
import hashlib
x = Solver()
ans=[]
a1 = [Int('%d'%i) for i in range(16)]
x.add(a1[2] + a1[1] + a1[0] + a1[3] == 447
      , 101 * a1[2] + a1[0] + 9 * a1[1] + 8 * a1[3] == 12265
      , 5 * a1[2] + 3 * a1[0] + 4 * a1[1] + 6 * a1[3] == 2000
      , 88 * a1[2] + 12 * a1[0] + 11 * a1[1] + 87 * a1[3] == 21475
      , a1[6] + 59 * a1[5] + 100 * a1[4] + a1[7] == 7896
      , 443 * a1[4] + 200 * a1[5] + 10 * a1[6] + 16 * a1[7] == 33774
      , 556 * a1[5] + 333 * a1[4] + 8 * a1[6] + 7 * a1[7] == 44758
      , a1[6] + a1[5] + 202 * a1[4] + a1[7] == 9950
      , 78 * a1[10] + 35 * a1[9] + 23 * a1[8] + 89 * a1[11] == 24052
      , 78 * a1[8] + 59 * a1[9] + 15 * a1[10] + 91 * a1[11] == 25209
      , 111 * a1[10] + 654 * a1[9] + 123 * a1[8] + 222 * a1[11] == 113427
      , 6 * a1[9] + 72 * a1[8] + 5 * a1[10] + 444 * a1[11] == 54166
      , 56 * a1[14] + 35 * a1[12] + 6 * a1[13] + 121 * a1[15] == 11130
      , 169 * a1[14] + 158 * a1[13] + 98 * a1[12] + 124 * a1[15] == 27382
      , 147 * a1[13] + 65 * a1[12] + 131 * a1[14] + 129 * a1[15] == 23564
      , 137 * a1[14] + 132 * a1[13] + 620 * a1[12] + 135 * a1[15] == 51206)
if x.check() == sat:
    model = x.model()
    for i in range(16):
        ans.append(model[a1[i]].as_long().real)
username="".join(map(chr,ans))
print(username)
​
enc1=[0x7E, 0x5A, 0x6E, 0x77, 0x3A, 0x79, 0x35, 0x76, 0x7C]
pre_pass=""
for i in range(len(enc1)):
    pre_pass+=chr((enc1[i]-9+i)^i)
print(pre_pass)
​
​
class AES:#128-ECB
    sbox = [0x31, 0x52, 0x5A, 0xC8, 0x0B, 0xAC, 0xF3, 0x3A, 0x8B, 0x54,
  0x27, 0x9B, 0xAB, 0x95, 0xDE, 0x83, 0x60, 0xCB, 0x53, 0x7F,
  0xC4, 0xE3, 0x0A, 0x97, 0xE0, 0x29, 0xD5, 0x68, 0xC5, 0xDF,
  0xF4, 0x7B, 0xAA, 0xD6, 0x42, 0x78, 0x6C, 0xE9, 0x70, 0x17,
  0xD7, 0x37, 0x24, 0x49, 0x75, 0xA9, 0x89, 0x67, 0x03, 0xFA,
  0xD9, 0x91, 0xB4, 0x5B, 0xC2, 0x4E, 0x92, 0xFC, 0x46, 0xB1,
  0x73, 0x08, 0xC7, 0x74, 0x09, 0xAF, 0xEC, 0xF5, 0x4D, 0x2D,
  0xEA, 0xA5, 0xDA, 0xEF, 0xA6, 0x2B, 0x7E, 0x0C, 0x8F, 0xB0,
  0x04, 0x06, 0x62, 0x84, 0x15, 0x8E, 0x12, 0x1D, 0x44, 0xC0,
  0xE2, 0x38, 0xD4, 0x47, 0x28, 0x45, 0x6E, 0x9D, 0x63, 0xCF,
  0xE6, 0x8C, 0x18, 0x82, 0x1B, 0x2C, 0xEE, 0x87, 0x94, 0x10,
  0xC1, 0x20, 0x07, 0x4A, 0xA4, 0xEB, 0x77, 0xBC, 0xD3, 0xE1,
  0x66, 0x2A, 0x6B, 0xE7, 0x79, 0xCC, 0x86, 0x16, 0xD0, 0xD1,
  0x19, 0x55, 0x3C, 0x9F, 0xFB, 0x30, 0x98, 0xBD, 0xB8, 0xF1,
  0x9E, 0x61, 0xCD, 0x90, 0xCE, 0x7C, 0x8D, 0x57, 0xAE, 0x6A,
  0xB3, 0x3D, 0x76, 0xA7, 0x71, 0x88, 0xA2, 0xBA, 0x4F, 0x3E,
  0x40, 0x64, 0x0F, 0x48, 0x21, 0x35, 0x36, 0x2F, 0xE8, 0x14,
  0x5D, 0x51, 0xD8, 0xB5, 0xFE, 0xD2, 0x96, 0x93, 0xA1, 0xB6,
  0x43, 0x0D, 0x4C, 0x80, 0xC9, 0xFF, 0xA3, 0xDD, 0x72, 0x05,
  0x59, 0xBF, 0x0E, 0x26, 0x34, 0x1F, 0x13, 0xE5, 0xDC, 0xF2,
  0xC6, 0x50, 0x1E, 0xE4, 0x85, 0xB7, 0x39, 0x8A, 0xCA, 0xED,
  0x9C, 0xBB, 0x56, 0x23, 0x1A, 0xF0, 0x32, 0x58, 0xB2, 0x65,
  0x33, 0x6F, 0x41, 0xBE, 0x3F, 0x6D, 0x11, 0x00, 0xAD, 0x5F,
  0xC3, 0x81, 0x25, 0xA8, 0xA0, 0x9A, 0xF6, 0xF7, 0x5E, 0x99,
  0x22, 0x2E, 0x4B, 0xF9, 0x3B, 0x02, 0x7A, 0xB9, 0x5C, 0x69,
  0xF8, 0x1C, 0xDB, 0x01, 0x7D, 0xFD]
    s_box = {}
    ns_box = {   }
​
    Rcon = {
        1: ['0x01', '0x00', '0x00', '0x00'],
        2: ['0x02', '0x00', '0x00', '0x00'],
        3: ['0x04', '0x00', '0x00', '0x00'],
        4: ['0x08', '0x00', '0x00', '0x00'],
        5: ['0x10', '0x00', '0x00', '0x00'],
        6: ['0x20', '0x00', '0x00', '0x00'],
        7: ['0x40', '0x00', '0x00', '0x00'],
        8: ['0x80', '0x00', '0x00', '0x00'],
        9: ['0x1B', '0x00', '0x00', '0x00'],
        10: ['0x36', '0x00', '0x00', '0x00']
    }
    Matrix = [
        ['0x02', '0x03', '0x01', '0x01'],
        ['0x01', '0x02', '0x03', '0x01'],
        ['0x01', '0x01', '0x02', '0x03'],
        ['0x03', '0x01', '0x01', '0x02']
    ]
    ReMatrix = [
        ['0x0e', '0x0b', '0x0d', '0x09'],
        ['0x09', '0x0e', '0x0b', '0x0d'],
        ['0x0d', '0x09', '0x0e', '0x0b'],
        ['0x0b', '0x0d', '0x09', '0x0e']
    ]
    plaintext = [[], [], [], []]
    plaintext1 = [[], [], [], []]
    subkey = [[], [], [], []]
​
    def __init__(self, key):#密钥扩展
        self.s_box = dict(zip(["0x%02x"%i for i in range(256)], ["0x%02x"%i for i in self.sbox]))
        self.ns_box = dict(zip(self.s_box.values(), self.s_box.keys()))
        for i in range(4):
            for j in range(0, 8, 2):
                self.subkey[i].append("0x" + key[i * 8 + j:i * 8 + j + 2])
        # print(self.subkey)
        for i in range(4, 44):
            if i % 4 != 0:
                tmp = xor_32(self.subkey[i - 1], self.subkey[i - 4],0)
                self.subkey.append(tmp)
            else:  # 4的倍数的时候执行
                tmp1 = self.subkey[i - 1][1:]
                tmp1.append(self.subkey[i - 1][0])
                # print(tmp1)
                for m in range(4):
                    tmp1[m] = self.s_box[tmp1[m]]
                # tmp1 = self.s_box['cf']
                tmp1 = xor_32(tmp1, self.Rcon[i / 4], 0)
                self.subkey.append(xor_32(tmp1, self.subkey[i - 4],0))
​
    def AddRoundKey(self, round):#轮密钥加
        for i in range(4):
            self.plaintext[i] = xor_32(self.plaintext[i], self.subkey[round * 4 + i],0)
        # print('AddRoundKey',self.plaintext)
​
    def PlainSubBytes(self):
        for i in range(4):
            for j in range(4):
                self.plaintext[i][j] = self.s_box[self.plaintext[i][j]]
        # print('PlainSubBytes',self.plaintext)
​
    def RePlainSubBytes(self):
        for i in range(4):
            for j in range(4):
                self.plaintext[i][j] = self.ns_box[self.plaintext[i][j]]
​
    def ShiftRows(self):#行移位
        p1, p2, p3, p4 = self.plaintext[0][1], self.plaintext[1][1], self.plaintext[2][1], self.plaintext[3][1]
        self.plaintext[0][1] = p2
        self.plaintext[1][1] = p3
        self.plaintext[2][1] = p4
        self.plaintext[3][1] = p1
        p1, p2, p3, p4 = self.plaintext[0][2], self.plaintext[1][2], self.plaintext[2][2], self.plaintext[3][2]
        self.plaintext[0][2] = p3
        self.plaintext[1][2] = p4
        self.plaintext[2][2] = p1
        self.plaintext[3][2] = p2
        p1, p2, p3, p4 = self.plaintext[0][3], self.plaintext[1][3], self.plaintext[2][3], self.plaintext[3][3]
        self.plaintext[0][3] = p4
        self.plaintext[1][3] = p1
        self.plaintext[2][3] = p2
        self.plaintext[3][3] = p3
        # print('ShiftRows',self.plaintext)
​
    def ReShiftRows(self):
        p1, p2, p3, p4 = self.plaintext[0][1], self.plaintext[1][1], self.plaintext[2][1], self.plaintext[3][1]
        self.plaintext[3][1] = p3
        self.plaintext[2][1] = p2
        self.plaintext[0][1] = p4
        self.plaintext[1][1] = p1
        p1, p2, p3, p4 = self.plaintext[0][2], self.plaintext[1][2], self.plaintext[2][2], self.plaintext[3][2]
        self.plaintext[0][2] = p3
        self.plaintext[1][2] = p4
        self.plaintext[2][2] = p1
        self.plaintext[3][2] = p2
        p1, p2, p3, p4 = self.plaintext[0][3], self.plaintext[1][3], self.plaintext[2][3], self.plaintext[3][3]
        self.plaintext[0][3] = p2
        self.plaintext[1][3] = p3
        self.plaintext[2][3] = p4
        self.plaintext[3][3] = p1
​
    def MixColumns(self):#列混淆
        for i in range(4):
            for j in range(4):
                self.plaintext1[i].append(MatrixMulti(self.Matrix[j], self.plaintext[i]))
        # print('MixColumns',self.plaintext1)
​
    def ReMixColumns(self):
        for i in range(4):
            for j in range(4):
                self.plaintext1[i].append(MatrixMulti(self.ReMatrix[j], self.plaintext[i]))
​
    def AESEncryption(self, plaintext):
        self.plaintext = [[], [], [], []]
        for i in range(4):
            for j in range(0, 8, 2):
                self.plaintext[i].append("0x" + plaintext[i * 8 + j:i * 8 + j + 2])
        self.AddRoundKey(0)
        for i in range(9):
            self.PlainSubBytes()
            self.ShiftRows()
            self.MixColumns()
            self.plaintext = self.plaintext1
            self.plaintext1 = [[], [], [], []]
            self.AddRoundKey(i + 1)
​
        self.PlainSubBytes()
        self.ShiftRows()
        self.AddRoundKey(10)
        return Matrixtostr(self.plaintext)
​
    def AESDecryption(self, cipher):
        self.plaintext = [[], [], [], []]
        for i in range(4):
            for j in range(0, 8, 2):
                self.plaintext[i].append('0x' + cipher[i * 8 + j:i * 8 + j + 2])
​
        # print(self.ns_box)
        self.AddRoundKey(10)
        for i in range(9):
            self.ReShiftRows()
            self.RePlainSubBytes()
            self.AddRoundKey(9-i)
            self.ReMixColumns()
            self.plaintext = self.plaintext1
            self.plaintext1 = [[], [], [], []]
        self.ReShiftRows()
        self.RePlainSubBytes()
        self.AddRoundKey(0)
        return Matrixtostr(self.plaintext)
​
    def Encryption(self, text):
        group = PlaintextGroup(TextToByte(text), 32, 1)
        # print(group)
        cipher = ""
        for i in range(len(group)):
            cipher = cipher + self.AESEncryption(group[i])
        return cipher
​
    def Decryption(self, cipher):
        group = PlaintextGroup(cipher, 32, 0)
        # print(group)
        text = ''
        for i in range(len(group)):
            text = text + self.AESDecryption(group[i])
        text = ByteToText(text)
        return text
​
​
def xor_32(start, end, key):
    a = []
    for i in range(0, 4):
        xor_tmp = ""
        b = hextobin(start[i])
        c = hextobin(end[i])
        d = bin(key)[2:].rjust(8,'0')
        for j in range(8):
            tmp = int(b[j], 10) ^ int(c[j], 10) ^ int(d[j],10)
            xor_tmp += str(tmp )
        a.append(bintohex(xor_tmp))
    return a
​
​
def xor_8(begin, end):
    xor_8_tmp = ""
    for i in range(8):
        xor_8_tmp += str(int(begin[i]) ^ int(end[i]))
    return xor_8_tmp
​
​
def hextobin(word):
    word = bin(int(word, 16))[2:]
    for i in range(0, 8-len(word)):
        word = '0'+word
    return word
​
def bintohex(word):
    word = hex(int(word, 2))
    if len(word) == 4:
        return word
    elif len(word) < 4:
        return word.replace('x', 'x0')
​
​
def MatrixMulti(s1, s2):
    result = []
    s3 = []
    for i in range(4):
        s3.append(hextobin(s2[i]))
    for i in range(4):
        result.append(MultiProcess(int(s1[i], 16), s3[i]))
    for i in range(3):
        result[0] = xor_8(result[0], result[i+1])
    return bintohex(result[0])
​
​
def MultiProcess(a, b):
    if a == 1:
        return b
    elif a == 2:
        if b[0] == '0':
            b = b[1:] + '0'
        else:
            b = b[1:] + '0'
            b = xor_8(b, '00011011')
        return b
    elif a == 3:
        tmp_b = b
        if b[0] == '0':
            b = b[1:] + '0'
        else:
            b = b[1:] + '0'
            b = xor_8(b, '00011011')
        return xor_8(b, tmp_b)
​
    elif a == 9:
        tmp_b = b
        return xor_8(tmp_b, MultiProcess(2, MultiProcess(2, MultiProcess(2, b))))
    elif a == 11:
        tmp_b = b
        return xor_8(tmp_b, xor_8(MultiProcess(2, MultiProcess(2, MultiProcess(2, b))), MultiProcess(2, b)))
    elif a == 13:
        tmp_b = b
        return xor_8(tmp_b, xor_8(MultiProcess(2, MultiProcess(2, MultiProcess(2, b))), MultiProcess(2, MultiProcess(2, b))))
    elif a == 14:
        return xor_8(MultiProcess(2, b), xor_8(MultiProcess(2, MultiProcess(2, MultiProcess(2, b))), MultiProcess(2, MultiProcess(2, b))))
​
​
def Matrixtostr(matrix):
    result = ""
    for i in range(4):
        for j in range(4):
            result += matrix[i][j][2:]
    return result
​
​
def PlaintextGroup(plaintext, length, flag):
    group = re.findall('.{'+str(length)+'}', plaintext)
    group.append(plaintext[len(group)*length:])
    if group[-1] == '' and flag:
        group[-1] = '16161616161616161616161616161616'
    elif len(group[-1]) < length and flag:
        tmp = int((length-len(group[-1])) / 2)
        if tmp < 10:
            for i in range(tmp):
                group[-1] = group[-1] + '0'+str(tmp)
        else:
            for i in range(tmp):
                group[-1] = group[-1] + str(tmp)
    elif not flag:
        del group[-1]
    return group
​
#字符串转16进制
def TextToByte(words):
    text = words.encode('utf-8').hex()
    return text
​
​
def ByteToText(encode):
    tmp = int(encode[-2:])
    word = ''
    for i in range(len(encode)-tmp*2):
        word = word + encode[i]
    # print(word)
    word = bytes.decode(binascii.a2b_hex(word))
    return word
#字节非轮异或
def xorbytes(bytes1,bytes2):
    length=min(len(bytes1),len(bytes2))
    output=bytearray()
    for i in range(length):
        output.append(bytes1[i]^bytes2[i])
    return bytes(output)
​
res='B0CC93EAE92FEF5699396E023B4F9E42'.lower()
key = ''
​
for i in username:
    key+=hex(ord(i))[2:].rjust(2,"0")
​
A1 = AES(key)
tail_pass=""
for i in range(0,len(res),32):
    tail_pass+=bytes.fromhex(A1.AESDecryption(res[i:i+32])).decode()
print(tail_pass)
print(hashlib.md5(str(username+pre_pass+"_"+tail_pass).encode("utf-8")).hexdigest())
​
​

 

至此,解密完成

 

收获:学到了AES分辨及解密方式(但是代码是借鉴别人的的,太菜了,写不出来)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 15
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值