当前位置: 首页 > article >正文

NewStar CTF 2024 re方向 week2 wp

文章目录

  • 前言
  • upx
  • drink_TEA
  • ptrace
  • ezencrypt
  • Dirty_flowers

前言

在这里插入图片描述
PangBai泰拉记(1)没做出来,其他题目都有wp

upx

根据题目提示,附件有upx壳,直接upx -d 碰运气
脱壳成功,证明没有其他混淆

ida打开看main函数,逻辑很清晰。使用rc4加密,接着是对比验证
在这里插入图片描述
直接点击data,发现是空的,可能在main函数前还执行了其他函数为其赋值
在这里插入图片描述
观察右侧函数列表,发现before main函数
在这里插入图片描述

直接赛博厨子一把梭哈
在这里插入图片描述
flag{Do_you_know_UPX?}

drink_TEA

根据题意猜测是tea算法
查看main函数,很明显的tea算法标志
在这里插入图片描述
分析tea算法,发现没有魔改
在这里插入图片描述
由于tea算法密文长度为64位(相当于16个十六进制数),所以知道进行了四次tea加密

# 收集密文
address = 0x140004080
print('')
for i in range(0, 32, 4):
    num = ida_bytes.get_byte(address + i) | \
           (ida_bytes.get_byte(address + i + 1) << 8) | \
           (ida_bytes.get_byte(address + i + 2) << 16) | \
           (ida_bytes.get_byte(address + i + 3) << 24)
    print(hex(num), end=', ')

直接上解密脚本

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#define DELTA 0x9e3779b9

void DTea(uint32_t *flag, const uint32_t *Key)
{
    uint32_t sum = DELTA * 32;
    int i;
    uint32_t v1 = flag[0];
    uint32_t v2 = flag[1];
    for (i = 0; i < 32; i++)
    {

        v2 -= ((v1 << 4) + Key[2]) ^ (v1 + sum) ^ ((v1 >> 5) + Key[3]);
        v1 -= ((v2 << 4) + Key[0]) ^ (v2 + sum) ^ ((v2 >> 5) + Key[1]);
        sum -= DELTA;
    }
    flag[0] = v1;
    flag[1] = v2;
}
int Check(uint32_t *enc, uint32_t *Input)
{
    int i = 0;
    for (i; i < 10; i++)
    {
        if (enc[i] != Input[i])
        {
            return 0;
        }
    }
    return 1;
}

int main()
{
    char *Key = "WelcomeToNewStar";
    // uint32_t Key[4] = {0x65736162, 0x6F783436, 0x61657472, 0x61657478};
    uint32_t enc[11] = {0xb3f72078, 0xdace42c5, 0x1a215985, 0x595a5626, 0xed0d0229, 0xeeb9a807, 0x87115936, 0x24235cfd};
    for (int i = 0; i < 4; i++)
    {
        DTea(&enc[i * 2], (uint32_t *)Key);
    }
    puts((char *)enc);

    return 0;
}

flag{There_R_TEA_XTEA_and_XXTEA}

ptrace

有两个文件,用ida看了看,应该是父进程和子进程的意思
这是father文件的内容

  v11 = fork();
  if ( v11 )
  {
    if ( v11 <= 0 )
    {
      perror("fork");
      return -1;
    }
    wait(stat_loc);
    ptrace(PTRACE_POKEDATA, addr, addr, 3);
    ptrace(PTRACE_CONT, 0, 0, 0);
    wait(0);
  }
  else
  {
    ptrace(PTRACE_TRACEME, 0, 0, 0);
    execl("./son", "son", &s, 0);
  }
  return 0;

值得注意的是,ptrace(PTRACE_POKEDATA, addr, addr, 3);将addr0x60004040地址中存放的值改为3。
用ida打开sum文件,找到60004040,对应值如下

data:60004040 num             dd 4       

这是本题坑人的地方,实际应该是3而不是4,绕过之后按照son中的加密逻辑,很容易写出解密脚本

int __cdecl sub_600011AD(int a1, int a2)
{
signed int i; // [esp+2h] [ebp-28h]
signed int j; // [esp+6h] [ebp-24h]
char *s; // [esp+Ah] [ebp-20h]
signed int v6; // [esp+Eh] [ebp-1Ch]

s = *(char **)(a2 + 4);
v6 = strlen(s);
for ( i = 0; i < v6; ++i )
  result[i] = ((int)(unsigned __int8)s[i] >> num) | (s[i] << (8 - num));
for ( j = 0; j < v6; ++j )
{
  if ( result[j] != byte_60004020[j] )
  {
    puts("this is Wrong~");
    return 0;
  }
}
puts("this is right~");
return 0;
}
list = [204 ,141 ,44 ,236 ,111 ,136 ,237 ,235 ,47 ,237 ,174 ,235 ,78 ,172 ,44 ,141 ,141 ,47 ,235 ,109 ,205 ,237 ,238 ,235 ,14 ,142 ,78 ,44 ,108 ,172 ,231 ,175]
result = []

for i in range(32):
   for num in range(0,255):
       tmp =((num >> 3) |(num << (8-3))) % 256 # 这里要注意取模运算
       if tmp == list[i]:
           result.append(chr(num))
           break
print(''.join(result))

flag{Do_you_really_know_ptrace?}

ezencrypt

在MainActivity中找到加密函数
在这里插入图片描述
双击,发现完整的加密函数
在这里插入图片描述
其中doEncCheck函数没有给出定义,由于题目提示,去so文件里找
在这里插入图片描述
找到了验证函数,点进去enc函数看看,发现使用了异或和rc4(这是通过分析算法特征发现的:有s盒,循环256次,%256,swap(s[i],s[j])等等,刷多题目就知道了)

总结整个加密流程如下
在这里插入图片描述

接下来按照这个顺序解密。 先rc4,后异或

key = 'meow'
def init_Sbox(seed):
    k_b = [ord(seed[i % len(seed)]) for i in range(256)]
    s = list(range(256))
    j = 0
    for i in range(256):
        j = (j + s[i] + k_b[i]) % 256
        s[i], s[j] = s[j], s[i]
    return s

def KeyStream(text, Sbox):
    s = Sbox.copy()
    i, j = 0, 0
    k = [0] * len(text)
    for r in range(len(text)):
        i = (i + 1) % 256
        j = (j + s[i]) % 256
        s[i], s[j] = s[j], s[i]
        t = (s[i] + s[j]) % 256
        k[r] = s[t]
    return k

def Encrypt(text, seed):
    Sbox = init_Sbox(seed)
    key = KeyStream(text, Sbox)
    enc = [text[i] ^ key[i] for i in range(len(text))]
    return bytes(enc)

# Encrypted flag (this should be provided or replaced with actual data)
enc = [0xc2,0x6c,0x73,0xf4,0x3a,0x45,0xe,0xba,0x47,0x81,0x2a,0x26,0xf6,0x79,0x60,0x78,0xb3,0x64,0x6d,0xdc,0xc9,0x4,0x32,0x3b,0x9f,0x32,0x95,0x60,0xee,0x82,0x97,0xe7,0xca,0x3d,0xaa,0x95,0x76,0xc5,0x9b,0x1d,0x89,0xdb,0x98,0x5d]

# Input handling
tmp1 = enc
#flag = [ord(i) for i in flag]
tmp1 = Encrypt(tmp1, key)
print(tmp1)
tmp2 = []
for i in range(44):
    tmp2.append(tmp1[i]^ord(key[i%4]))

print(tmp2)
tmp3 = ''.join(chr(i) for i in tmp2)
print(tmp3)
# 2BB+GQampKmsrfDG85+0A7n18M+kT2zBDiZSO28Ich4=

接下来用赛博厨子一把梭哈
在这里插入图片描述
flag{0hh_U_kn0w_7h15_5ki11}

Dirty_flowers

根据题目字符串的提示,将调用$5函数和ret之间的汇编代码nop掉

for i in range(0x4012f1 , 0x401302):
    patch_byte(i,0x90)
for i in range(0x401166, 0x401176):
    patch_byte(i,0x90)

接下来编辑函数的起始和终止地址
在这里插入图片描述
另外一个函数同理

反编译后的代码是简单的异或逻辑代码

tmp = "dirty_flower"
v3 = [ 0 for _ in range(36)]

v3[0] = 2
v3[1] = 5
v3[2] = 19
v3[3] = 19
v3[4] = 2
v3[5] = 30
v3[6] = 83
v3[7] = 31
v3[8] = 92
v3[9] = 26
v3[10] = 39
v3[11] = 67
v3[12] = 29
v3[13] = 54
v3[14] = 67
v3[15] = 7
v3[16] = 38
v3[17] = 45
v3[18] = 85
v3[19] = 13
v3[20] = 3
v3[21] = 27
v3[22] = 28
v3[23] = 45
v3[24] = 2
v3[25] = 28
v3[26] = 28
v3[27] = 48
v3[28] = 56
v3[29] = 50
v3[30] = 85
v3[31] = 2
v3[32] = 27
v3[33] = 22
v3[34] = 84
v3[35] = 15
result = []
for i in range(36):
    result.append(v3[i]^ord(tmp[i%len(tmp)]))

print(''.join(chr(i)for i in result))

flag{A5s3mB1y_1s_r3ally_funDAm3nta1}


http://www.kler.cn/a/348857.html

相关文章:

  • Geist「Polter」测试网现已上线——不可错过的关键信息
  • 电脑插上U盘不显示怎么回事?怎么解决?
  • IT基础监控运维:监控易的深度解析与应用
  • Python网络爬虫
  • 大模型烧钱战,百度云亟需突围之路
  • AD9680(adc直采芯片)使用说明
  • Java:数据结构-队列(Queue)
  • SpringBoot教程(三十二) | SpringBoot集成Skywalking链路跟踪
  • 施耐德EcoStruxure Machine SCADA Expert(EMSE)文件管理功能-上(二十)
  • 76.【C语言】perror函数介绍
  • ssh连接慢的问题或zookeeper远程连接服务超时
  • uniapp学习(005-1 详解Part.1)
  • 百度地图怎么上传店铺定位?
  • 前端继承:原理、实现方式与应用场景
  • 中国海油携手科大讯飞共建“海能”人工智能模型,助力能源行业焕新
  • 近邻算法:深入理解与广泛应用
  • protobuf的简介、安装与使用
  • 文献阅读(222) VVQ协议死锁
  • Redis学习笔记:简单动态字符串
  • Kafka原理剖析之「Purgatory(炼狱 | 时间轮)」