Lufer

  • 首页
  • 编程
  • 学习笔记
  • 日常折腾
Lufer
Code the World
  1. 首页
  2. 学习笔记
  3. WriteUP
  4. 正文

攻防世界逆向练习题 难度1 WP

2025年7月3日 31点热度 0人点赞 0条评论

easyre-xctf

题目

龟缩起来,保护自己

题解

扔进die里面看一下,UPX加壳程序,脱壳之后拉进IDA,可以找到后半截flag。

在字符串里面找不到前半截,看一眼是不是有其他函数在负责处理,可以找到part1函数。

这里用伪代码只能得到一部分flag,在汇编里面才能看见后面还拼接了_4n。

666

题解

先IDA发现是把输入串通过encode函数加密后与enflag的值对比。

encode函数每三个字符做一轮操作,直接反向即可解出flag,这里注意异或运算符优先级低于加减,要带括号。

enflag="izwhroz\"\"w\"v.K\".Ni"

realflag=""

for i in range (0,18,3):
    realflag+=chr((18^ord(enflag[i]))-6)
    realflag+=chr((18^ord(enflag[i+1]))+6)
    realflag+=chr(18^ord(enflag[i+2])^6)
print(realflag)

easyRE1

题解

IDA一把唆,用flag{}包裹。

Reversing-x64Elf-100

题解

IDA发现关键函数是sub_4006FD。

__int64 __fastcall sub_4006FD(__int64 a1)
{
  int i; // [rsp+14h] [rbp-24h]
  __int64 v3[4]; // [rsp+18h] [rbp-20h]

  v3[0] = (__int64)"Dufhbmf";
  v3[1] = (__int64)"pG`imos";
  v3[2] = (__int64)"ewUglpt";
  for ( i = 0; i <= 11; ++i )
  {
    if ( *(char *)(v3[i % 3] + 2 * (i / 3)) - *(char *)(i + a1) != 1 )
      return 1LL;
  }
  return 0LL;
}

可以看出函数逻辑是有一个3个元素的字符串数组,然后每个数组进行加减操作,然后与输入的字符作比较,反向编写代码得到flag。

str=["Dufhbmf","pG`imos","ewUglpt"]
flag=""
i=0
print(flag)
for i in range(0,12) :
    print(i)
    flag+=chr(ord(str[i%3][2*(int(i/3))])-1)
print(flag)

lucknum

题解

IDA直接可以看见flag。

1000Click

题解

打开程序,提示点击1000次或者逆向获得flag。

逆向试了一下,没找到线索,直接上CE。

找到内存,修改为999,然后再点击一次,获得flag。

xxxorrr

题解

IDA逆向,只能看见一个main函数,找不到逻辑,这里学到了一个知识点。

在 ELF (Executable and Linkable Format) 文件中,Initialization Function Table 是一种特殊的数据结构,用于存储在程序启动时(在 main 函数执行之前)需要调用的一系列初始化函数的地址。这个机制允许程序或库执行必要的初始化任务,例如设置全局变量的初始状态、注册回调函数、初始化硬件设备或执行其他任何启动前准备工作。
如果 sub_840 的地址被包含在 ELF 的 Initialization Function Table 中,那么它会在程序的主逻辑开始执行之前被自动调用。这种自动调用是由程序的启动代码(通常是由编译器和链接器自动生成的一部分)负责的,该代码会遍历 Initialization Function Table 中的所有条目,并按照它们出现的顺序调用每个函数。

可以看出会按顺序调用sub_840、sub_84A、sub_8C3、sub_800。

跟一下这几个函数,发现只有84A有一些操作,对s1进行了一轮异或运算,同时可以直接定位到s1的值。

unsigned __int64 sub_84A()
{
  int i; // [rsp+Ch] [rbp-14h]
  unsigned __int64 v2; // [rsp+18h] [rbp-8h]

  v2 = __readfsqword(0x28u);
  for ( i = 0; i <= 33; ++i )
    s1[i] ^= 2 * i + 65;
  return __readfsqword(0x28u) ^ v2;
}

回到main函数,发现注册了sub_916,跟进一下,发现这里是最终判断的函数

unsigned __int64 sub_916()
{
  unsigned __int64 v1; // [rsp+8h] [rbp-8h]

  v1 = __readfsqword(0x28u);
  if ( !strcmp(s1, byte_201060) )
    puts("Congratulations!");
  else
    puts("Wrong!");
  return __readfsqword(0x28u) ^ v1;
}

在此之前,main函数里面又进行了一轮异或,是用s1和我们的输入值进行异或,然后进入sub_916,与byte_201060进行比较,可以读到这个串的值。

因此,我们的合理输入,就应该是s1先本身进行一轮异或,再与byte_201060进行一轮异或。

s1="qasxcytgsasxcvrefghnrfghnjedfgbhn"
s2=[ 0x56, 0x4E, 0x57, 0x58, 0x51, 0x51, 0x09, 0x46, 0x17, 0x46,
  0x54, 0x5A, 0x59, 0x59, 0x1F, 0x48, 0x32, 0x5B, 0x6B, 0x7C,
  0x75, 0x6E, 0x7E, 0x6E, 0x2F, 0x77, 0x4F, 0x7A, 0x71, 0x43,
  0x2B, 0x26, 0x89, 0xFE, 0x00]
flag=""
for i in range (0,33):
    flag+=chr(ord(s1[i])^(2*i)+65)
flag2=""
for i in range(0,33):
    flag2+=chr(ord(flag[i])^s2[i])
print(flag2)

reverse_re3

题目

我从不走回头路,但你能找到我选择的路吗

题解

main函数很简单,直接调用了sub_940()

940点进去,有一些逻辑,并且最后提示flag是输入的md5值。

100、115、119、97对应的字符分别是d s w a,考虑是走迷宫的题。

每一个选项进去都是一个子函数,都使用了dword_202020这个变量,并且步进为15,那么迷宫应该是15个字符为一行,并且可以看出,字符为1的地方是路,那么字符为0就是墙,3是当前位置,4是迷宫出口。

进入dword_202020变量,是一个数组,通过shift+E对变量进行提取。

对提取的数据进行处理,15个字符一行,从3开始走到4

111110000000000
111110311000000
111110001000000
111110001000000
111110001111100
111110000000100
111110000000100
111110000000110
111110000000010
111110000000040
111111111111111
111111111111111
111111111111111
111111111111111
111111111111111

走法:ddsssddddsssdss

110000000000000
110311111000000
110110001000000
110000001000000
110110001111100
110110000000100
110110000000100
110110000011110
110110000010010
110110000010000
110111111010110
110111111111110
110000000000040
111111111111111
111111111111111

走法:dddddsssddddsssaassssddds

000000000000000
031100000000000
000101110000000
000111010000000
000010010000000
011010010000000
001110010000000
000000010000000
000000011110000
000000000010000
000000000010000
000000000010000
000000000011110
000000000000010
000000000000040

走法:ddssddwddssssssdddssssdddss

合理输入:ddsssddddsssdssdddddsssddddsssaassssdddsddssddwddssssssdddssssdddss

计算MD5:aeea66fcac7fa80ed8f79f38ad5bb953

happyctf

题解

这题给了pdb文件,用IDA分析的时候,如果加载了pdb文件,代码会变得非常乱,看不出来什么东西,不加载pdb反而会好一点。

输入一个flag,经过一些函数的处理,然后与目标串“rxusoCqxw{yqK{KZqag{ri”进行比较。

看一下前面的几个函数,发现while内部的sub_403B70进行了一些操作。

int __thiscall sub_403B70(void *this, char a2)
{
  char v3[65]; // [esp+Fh] [ebp-45h] BYREF
  void *v4; // [esp+50h] [ebp-4h]

  v4 = this;
  v3[0] = a2 ^ 0x14;
  sub_406170(v3);
  return ++dword_4DD8F8;
}

看起来是把字符进行了一轮和0x14的异或,直接梭,得到flag。

s1="rxusoCqxw{yqK`{KZqag{r`i"
flag=""
for i in range(0,len(s1)):
    flag+=chr(ord(s1[i])^0x14)
print(flag)

//flag{Welcome_to_Neusoft}

标签: CTF Reverse 攻防世界
最后更新:2025年7月3日

Lufer

新的一天开始啦

点赞
< 上一篇

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复

文章目录
  • easyre-xctf
    • 题目
    • 题解
  • 666
    • 题解
  • easyRE1
    • 题解
  • Reversing-x64Elf-100
    • 题解
  • lucknum
    • 题解
  • 1000Click
    • 题解
  • xxxorrr
    • 题解
  • reverse_re3
    • 题目
    • 题解
  • happyctf
    • 题解

COPYRIGHT © 2025 lufer.cc.

Theme Kratos Made By Seaton Jiang

鲁ICP备2021045819号