[WUSTCTF2020]Cr0ssfun-学习笔记

📅 2026/7/28 18:58:18 👁️ 阅读次数 📝 编程学习
[WUSTCTF2020]Cr0ssfun-学习笔记
    • 前置知识
    • 正文
      • 一、UPX脱壳
      • 二、IDA静态分析
        • 1、main函数反编译,代码审计
        • 2、追踪 check() 函数链
      • 三、根据 check() 函数链调用链,编写有效 Flag

前置知识

BUUCTF 新年快乐-学习笔记

正文

一、UPX脱壳

查过了,无壳。

二、IDA静态分析

1、main函数反编译,代码审计

IDA 进入后,左侧Functions Window(函数窗口)可以看到所有函数。找到main函数并双击,然后按F5键反编译。

代码如下:

int__fastcallmain(intargc,constchar**argv,constchar**envp){_BYTE v4[48];// 存储用户输入的 flag// 打印 ASCII 艺术字(忽略)puts(" _ _ _ _ _____ _____ _____ ");// ...(省略 banner)while(1){puts("Input the flag");__isoc99_scanf("%s",v4);// 读取用户输入if((unsignedint)check(v4)==1)// 调用 check() 验证break;puts("0ops, your flag seems fake.");rewind(__bss_start);}puts("Your flag is correct, go and submit it!");return0;}

逻辑很简单:用户输入一个字符串 → 调用check()验证 → 正确则输出成功信息,错误则继续循环。
关键问题check()函数到底检查了什么条件?

2、追踪 check() 函数链

check()只有一行代码:

__int64 __fastcallcheck(__int64 a1){returniven_is_handsome(a1);// 调用 iven_is_handsome}


iven_is_handsome里面又调用了iven_is_c0oliven_is_c0ol调用了iven_1s_educated…… 实际上,这些函数形成了一条调用链:

check() → iven_is_handsome() → iven_is_c0ol() → iven_1s_educated() → iven_1s_brave() → iven_1s_great() → iven_and_grace() → finally_fun()

从后往前,逐一反编译每个函数,esc键往前退回,可以得到如下的位置→字符映射表:

finally_fun(最后一环):

returna1[1]==99&&a1[25]==64&&a1[27]==101;// 索引1 = 'c' 索引25 = '@' 索引27 = 'e'

可以用随波逐流工具验证一下a1的值:

也可以用 Python 的chr()函数转换。

iven_and_grace:

returna1[4]==50&&a1[17]==114&&a1[29]==102&&a1[24]==95&&finally_fun(a1);// 索引4 = '2' 索引17 = 'r' 索引29 = 'f' 索引24 = '_'

iven_1s_great:

returna1[2]==116&&a1[9]==99&&a1[32]==125&&a1[19]==118&&a1[5]==48&&a1[14]==110&&iven_and_grace(a1);// 索引2 = 't' 索引9 = 'c' 索引32 = '}' 索引19 = 'v' 索引5 = '0' 索引14 = 'n'

iven_1s_brave:

returna1[15]==100&&a1[8]==123&&a1[18]==51&&a1[28]==95&&a1[21]==114&&iven_1s_great(a1);// 索引15 = 'd' 索引8 = '{' 索引18 = '3' 索引28 = '_' 索引21 = 'r'

iven_1s_educated:

returna1[0]==119&&a1[6]==50&&a1[22]==115&&a1[31]==110&&a1[12]==95&&iven_1s_brave(a1);// 索引0 = 'w' 索引6 = '2' 索引22 = 's' 索引31 = 'n' 索引12 = '_'

iven_is_c0ol:

returna1[7]==48&&a1[16]==95&&a1[11]==112&&a1[23]==101&&a1[30]==117&&iven_1s_educated(a1);// 索引7 = '0' 索引16 = '_' 索引11 = 'p' 索引23 = 'e' 索引30 = 'u'

iven_is_handsome:

returna1[10]==112&&a1[13]==64&&a1[3]==102&&a1[26]==114&&a1[20]==101&&iven_is_c0ol(a1);// 索引10 = 'p' 索引13 = '@' 索引3 = 'f' 索引26 = 'r' 索引20 = 'e'

每个函数都做同一件事:检查输入字符串的某些位置是否等于特定字符。

三、根据 check() 函数链调用链,编写有效 Flag

用AI 编写脚本:

flag=['']*33# finally_funflag[1]=chr(99)# 'c'flag[25]=chr(64)# '@'flag[27]=chr(101)# 'e'# iven_and_graceflag[4]=chr(50)# '2'flag[17]=chr(114)# 'r'flag[29]=chr(102)# 'f'flag[24]=chr(95)# '_'# iven_1s_greatflag[2]=chr(116)# 't'flag[9]=chr(99)# 'c'flag[32]=chr(125)# '}'flag[19]=chr(118)# 'v'flag[5]=chr(48)# '0'flag[14]=chr(110)# 'n'# iven_1s_braveflag[15]=chr(100)# 'd'flag[8]=chr(123)# '{'flag[18]=chr(51)# '3'flag[28]=chr(95)# '_'flag[21]=chr(114)# 'r'# iven_1s_educatedflag[0]=chr(119)# 'w'flag[6]=chr(50)# '2'flag[22]=chr(115)# 's'flag[31]=chr(110)# 'n'flag[12]=chr(95)# '_'# iven_is_c0olflag[7]=chr(48)# '0'flag[16]=chr(95)# '_'flag[11]=chr(112)# 'p'flag[23]=chr(101)# 'e'flag[30]=chr(117)# 'u'# iven_is_handsomeflag[10]=chr(112)# 'p'flag[13]=chr(64)# '@'flag[3]=chr(102)# 'f'flag[26]=chr(114)# 'r'flag[20]=chr(101)# 'e'print(''.join(flag))