首页
社区
课程
招聘
[原创]长城杯初赛wp xiran_encrypto
发表于: 2024-10-7 14:35 6389

[原创]长城杯初赛wp xiran_encrypto

2024-10-7 14:35
6389

该题为正常ctf题与恶意脚本相结合的题目,cha为常规的re题目,clickme为恶意样本,在cha中拿到信息,然后根据clickme的逻辑解密

cha的核心为比较经过换表base64然后与自己xor之后与内存中的32字节相比较

求解思路:


爆破脚本:

clickme为babyuk家族,主要加密逻辑也类似

核心加密逻辑在main_encrypt_file中

解密脚本:

cha中的私钥如果纯静态的分析 只有爆破才行 能不能在cha运行时把 私钥dump出来?

在尝试的过程中发现cha中,在.init_array中存在一个特殊的初始化函数,在这个函数中做了两个(或者一个)反调试:

在bypass这两个点之后,进入main之后 发现私钥对应的内存实际为0,这也和在ida中找不到它的xref呼应,我觉得这里作者的意思就是故意让程序运行不到main,所以正确做法只能爆破,不然直接进内存dump太简单了。

convert_table = b'APet8BQfu9CRgv+DShw/ETixFUjyGVkzHWl0IXm1JYn2KZo3Lap4Mbq5Ncr6Ods7'
encrypted_flag = [0xD9, 0x40, 0x6F, 0xCA, 0x3D, 0x8F, 0x53, 0xB1, 0x8B, 0x34,
  0x92, 0x8E, 0xF7, 0x19, 0x94, 0x61, 0x68, 0x71, 0x55, 0xB6,
  0xCE, 0x5B, 0x71, 0x1A, 0x79, 0x42, 0x9D, 0x02, 0x93, 0x38,
  0xAD, 0x1F, 0xD3, 0x24, 0x48, 0xFF, 0x21, 0xA2, 0x24, 0xBE,
  0x95, 0x3A, 0xC1, 0xD2]
 
def convert(flag,index):
    group = (index // 4) * 3
    if index % 4 == 0:
        return convert_table[flag[group] >> 2]
    if index % 4 == 1:
        return convert_table[(flag[group] << 4 & 0x30) + (flag[group + 1] >> 4)]
    if index % 4 == 2:
        return convert_table[(flag[group + 1] << 2 & 0x3c) + (flag[group + 2] >> 6)]
    if index % 4 == 3:
        return convert_table[flag[group + 2] & 0x3f]
 
def brup(flag):
    cur_len = len(flag)
    if cur_len != 0:
        res = flag[cur_len-1] ^ convert(flag,cur_len-1)
        if res != encrypted_flag[cur_len-1]:
            return
    if cur_len == 32:
        sum = 0
        for i in range(len(flag)):
            sum = 19*sum + flag[i]
        sum = sum & 0xffffffff
        if sum == 0xD033A96A:
            for i in flag:
                print(i,end=',')
        return
    for i in range(256):
        flag.append(i)
        brup(flag)
        flag.pop()
 
flag = bytearray()
brup(flag)
convert_table = b'APet8BQfu9CRgv+DShw/ETixFUjyGVkzHWl0IXm1JYn2KZo3Lap4Mbq5Ncr6Ods7'
encrypted_flag = [0xD9, 0x40, 0x6F, 0xCA, 0x3D, 0x8F, 0x53, 0xB1, 0x8B, 0x34,
  0x92, 0x8E, 0xF7, 0x19, 0x94, 0x61, 0x68, 0x71, 0x55, 0xB6,
  0xCE, 0x5B, 0x71, 0x1A, 0x79, 0x42, 0x9D, 0x02, 0x93, 0x38,
  0xAD, 0x1F, 0xD3, 0x24, 0x48, 0xFF, 0x21, 0xA2, 0x24, 0xBE,
  0x95, 0x3A, 0xC1, 0xD2]
 
def convert(flag,index):
    group = (index // 4) * 3
    if index % 4 == 0:
        return convert_table[flag[group] >> 2]
    if index % 4 == 1:
        return convert_table[(flag[group] << 4 & 0x30) + (flag[group + 1] >> 4)]
    if index % 4 == 2:
        return convert_table[(flag[group + 1] << 2 & 0x3c) + (flag[group + 2] >> 6)]
    if index % 4 == 3:
        return convert_table[flag[group + 2] & 0x3f]
 
def brup(flag):
    cur_len = len(flag)
    if cur_len != 0:
        res = flag[cur_len-1] ^ convert(flag,cur_len-1)
        if res != encrypted_flag[cur_len-1]:
            return
    if cur_len == 32:
        sum = 0
        for i in range(len(flag)):
            sum = 19*sum + flag[i]
        sum = sum & 0xffffffff
        if sum == 0xD033A96A:
            for i in flag:
                print(i,end=',')
        return
    for i in range(256):
        flag.append(i)
        brup(flag)
        flag.pop()
 
flag = bytearray()
brup(flag)
package main
 
import (
    "crypto/sha256"
    "os"
 
    "golang.org/x/crypto/chacha20"
    "golang.org/x/crypto/curve25519"
)
 
func main() {
 
    file, err := os.OpenFile("flag.png.xiran",os.O_RDWR,0)
    if err != nil {
        panic(err)
    }
 
    fileinfo,err :=  file.Stat()
    if err != nil {
        panic(err)
    }
 
    filesize := fileinfo.Size()
    var start  int64  =  0
    end := filesize
     
    privateKeyBob := [32]byte{144,16,46,165,100,230,124,220,241,66,166,239,164,119,237,82,49,23,47,236,139,107,73,98,43,49,237,80,249,117,245,115}
     
    publicKeyAlice := make([]byte,32,32)
 
    offset,err := file.Seek(filesize-32-6,0)
    if err != nil {
        panic(err)
    }
 
    file.ReadAt(publicKeyAlice,offset)
 
    var sharedKeyAlice [32]byte
    curve25519.ScalarMult(&sharedKeyAlice, &privateKeyBob, (*[32]byte)(publicKeyAlice))
     
    var key [32]byte= sha256.Sum256(sharedKeyAlice[:])
    var res [32]byte = sha256.Sum256(key[:])
    nonce := res[10:22]
 
     
    cipher, err :=  chacha20.NewUnauthenticatedCipher(key[:],nonce)
    if err != nil {
        panic(err)
    }
     
     
 
    buffer := make([]byte, 0x100000,0x100000)
 
    for start < end {
        file.ReadAt(buffer,start)
        cipher.XORKeyStream(buffer,buffer)
        file.WriteAt(buffer,start)
        start += 0xA00000
    }
 
    if err := file.Close(); err != nil {
        panic(err)
    }
 
}
package main
 
import (
    "crypto/sha256"
    "os"
 
    "golang.org/x/crypto/chacha20"
    "golang.org/x/crypto/curve25519"
)
 
func main() {
 
    file, err := os.OpenFile("flag.png.xiran",os.O_RDWR,0)
    if err != nil {
        panic(err)
    }

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2024-10-7 14:38 被SleepAlone编辑 ,原因:
收藏
免费 3
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//