Buuctf-reverse

新年快乐exeinfo pe的使用

image-20240717163433162

查壳发现有upx壳,那么脱壳是什么呢?

image-20240717164241987

用upx脱壳工具(https://github.com/upx/upx/releases)
进行脱壳,语句为upx -d +文件路径

image-20240717164447034

脱壳成功

image-20240717164604961

用ida打开

image-20240717164719026

分析代码可知,strcpy函数是将字符串复制给Str2。而if( !strncmp(Str1, Str2, strlen(Str2)) )语句是判断Str1和Str2这两个字符串的字符是否相等,长度为Str2字符串的长度。所以只要找到Str1和Str2中任意一个就可以知道flag了



xor

分析源代码

image-20240717190721532

这里最重要的是strncmp函数,strncmp(__b, global, 0x21uLL)比较了__b和global两个字符串的前0x21uLL(也就是33)个字符。如果这两个字符串的前33个字符相同,strncmp函数将返回0。也就是说,将global所对应的值逆向操作,就能得到flag了

image-20240717191549494

双击global,得到了字符串aFKWOXZUPFVMDGH,这个字符串对应的ascll码,进行逆向操作就是flag

image-20240717191716500

运行python脚本得到flag

a = [102,10,107,12,119,38,79,46,64,17,120,13,90,59,85,17,112,25,70,31,118,34,77,35,68,14,103,6,104,15,71,50,79,0]
b= [0]*33
b[0]=a[0]
for i in range(1,33 ):
   b[i]= a[i] ^ a[i - 1]

for i in range(33):
   print(chr(b[i]),end='')




reverse3

分析源码,找出Destination或者Str2的值,就能得出flag

image-20240717203547595

这里的for循环改了Destination的值,可以写脚本把str2逆向回去,得到e2lfbDB2ZV95b3V9

image-20240717203648729

a = [101,51,110,105,102,73,72,57,98,95,67,64,110,64,100,72,0]
b = [0]*len(a)
for i in range(0,16):
    b[i] = a[i] - i
    print(chr(b[i]),end='')
print(b)

提交发现并不是flag,继续往上看代码。strncpy函数的作用是从v4字符串复制最多40个字符到Destination中,也就是说v4也会改变Destination的值

image-20240717203811391

v4 =sub_4110BE(Str,v3,v14),v4的值又由sub_4110BE函数决定。根据sub_4110BE函数源代码,发现这个函数的作用是对输入的东西进行base+64编码

image-20240717204010271

所以把e2lfbDB2ZV95b3V9进行base64编码即可得到flag



SimpleRev

首先引入一个概念:大端字节序big endian 小端字节序little endian 中英字幕x精译搬运字节次序 - 位序和字节序 大端序 小端序

由die可知,本题文件字节序为LE,是小端序

image-20240718202812024

分析main函数,第二个if语句puts("Input fault format!"),看起来flag跟这里没什么关系。看另一个if语句,有一个没定义的Decry函数,双击查看源代码

image-20240718203148840

看到flag,这个函数就是解题关键了

image-20240718203623073

观察末尾if语句可知,本题要找到text或者是str2

image-20240718202655792

join函数功能是将多个字符串连接起来,这里的v9是经历了一个转为ascll码的过程,v9转化为ascll码是wodah。我们可能会误以为text = killswodah。当v9转化为ascll码并存储时,由于是小端序,高位字节会被存到高地址位中,v9存储到内存中是hadow。计算机对数据的读写是从低地址位向高地址位读取,执行了join函数后text = killshadow

image-20240718202619922

image-20240719093536335

ctrcat函数会把key和src连接。同理,key = ADSFKNDCLS

image-20240719095335759

image-20240719095526389

分析后面的源代码

v3=0  ADSFKNDCLS=key=src v9=hadow v5=10 v2=0 v1=0 text = killshadow
for(i = 0; i < 10; ++i){
    if( key[v3 % 10] > '@' && key[v3 % 10] <= 'Z')
        key[i] = key[v3 % 10] + 32;
    ++v3; #检测key[0-9]是否是大写,如果是大写就+32,也就是变成小写
} 
printf("Please input your flag:");
while ( 1 )
  {
    v1 = getchar();
    if ( v1 == '\n' )
      break;
    if ( v1 == ' ' ) #读取一个字符,如果是回车就跳出循环
    {
      ++v2; #如果是空格,v2+1
    }
    else
    {
      if ( v1 <= '`' || v1 > 'z' ) # 如果不是小写
      {
        if ( v1 > '@' && v1 <= 'Z' ) # 如果是大写就执行下面代码
        {
          str2[v2] = (v1 - 39 - key[v3 % v5] + 97) % 26 + 97; # 算是一个加密混淆过程
          ++v3;
        }
      }
      else # 如果是别的符号,执行下面代码
      {
        str2[v2] = (v1 - 39 - key[v3 % v5] + 97) % 26 + 97;
        ++v3;
      }
      if ( !(v3 % v5) ) # 如果v3能整除v5,打印一个空格
        putchar(32);
      ++v2;
    }
  }
if ( !strcmp(text, str2) ) # 如果text=str2,得到flag
    puts("Congratulation!\n");

接下来写脚本,把text逆向回去

text = 'killshadow'
key ='adsfkndcls'
flag = ""
for i in range(0,len(text)):
    for x in range(0,128):      # 用碰撞的思想
        if chr(x).isalpha():    # 判断x是否是字符串
            temp = (x - 39 - ord(key[i]) + 97) % 26 + 97
            # print(text[i]+"   "+chr(temp)+"   "+chr(x))
            if text[i] == chr(temp):
                flag = flag + chr(x)
                break

print(flag)


luck_guy

放入工具中查壳,无壳

image-20240719095909150

分析源代码。有两个未定义的函数,分别点进去看看

image-20240719100138133

在patch_me函数发现一个get_flag函数

image-20240719100313917

在case1中,f1 = GXY{do_not_ ,strcat函数把f1和s连接,又把f2和s连接,所以flag = f1+f2

image-20240719100522532

image-20240719111807561

case4中发现,s = \x7Ffo`guci(\x7在ascll中代表删除,对应ascll127)


由于小端序,s = icug`ofF\x7,strcat函数连接f2和s。


所以f2 = icug`ofF\x7,f2显然不符合flag的格式

*(&f2 + j)表示的是从f2中向后偏移j个位置的内存位置上的值

image-20240719111945765

case5中有一个处理f2的函数,写脚本逆向处理得到另一半flag

f = [105, 99, 117, 103, 96, 111, 102, 127]
a = [0]*8
for j in range(8):
    if j % 2 == 1:
        a[j] = f[j] - 2
    else:
        a[j] = f[j] - 1

for j in range(len(a)):
    print(chr(a[j]), end='')