Lufer

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

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

2026年3月9日 715点热度 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,经过一些函数的处理,然后与目标串进行比较。

看一下前面的几个函数,发现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}

crypt

题解

输入字符串给Str,然后经过函数sub_140001240处理,在通过异或0x22与byte_14013B000对比。

sub_140001240传入了v9和v4作为参数,v9来自于sub_140001120。

看sub_140001120,像是初始化S盒

看sub_140001240,RC4加密

from Crypto.Cipher import ARC4

Key = "12345678abcdefghijklmnopqrspxyz"
Str = [0x9E, 0xE7, 0x30, 0x5F, 0xA7, 0x01, 0xA6, 0x53, 0x59, 0x1B, 0x0A, 0x20, 0xF1, 0x73, 0xD1, 0x0E, 0xAB, 0x09, 0x84,
       0x0E, 0x8D, 0x2B]
a = []
flag = []
for i in range(0, 22):
    a.append(Str[i] ^ 34)
flag = ARC4.new(bytes(Key, encoding="utf-8")).decrypt(bytes(a))

for i in range(0, len(Str)):
    print(chr(flag[i]), end='')

flag{nice_to_meet_you}

bad_python

题解

给了一个破损的pyc,根据文件名提示应该是python36,补全文件头得到

# Source Generated with Decompyle++
# File: pyre.cpython-36.pyc (Python 3.6)

from ctypes import *
from Crypto.Util.number import bytes_to_long
from Crypto.Util.number import long_to_bytes

def encrypt(v, k):
    v0 = c_uint32(v[0])
    v1 = c_uint32(v[1])
    sum1 = c_uint32(0)
    delta = 195935983
    for i in range(32):
        v0.value += (v1.value << 4 ^ v1.value >> 7) + v1.value ^ sum1.value + k[sum1.value & 3]
        sum1.value += delta
        v1.value += (v0.value << 4 ^ v0.value >> 7) + v0.value ^ sum1.value + k[sum1.value >> 9 & 3]

    return (v0.value, v1.value)

if __name__ == '__main__':
    flag = input('please input your flag:')
    k = [
        255,
        187,
        51,
        68]
    if len(flag) != 32:
        print('wrong!')
        exit(-1)
    a = []
    for i in range(0, 32, 8):
        v1 = bytes_to_long(bytes(flag[i:i + 4], 'ascii'))
        v2 = bytes_to_long(bytes(flag[i + 4:i + 8], 'ascii'))
        a += encrypt([
            v1,
            v2], k)

    enc = [
        0xEEC7D402,
        0x99E9363F,
        0x853BDE61,
        558171287,
        0x908F94B0,
        1715140098,
        986348143,
        1948615354]
    for i in range(8):
        if enc[i] != a[i]:
            print('wrong!')
            exit(-1)
    print('flag is flag{%s}' % flag)

TEA加密,解密代码如下

from ctypes import *
# 关键:补全 long_to_bytes/bytes_to_long 的导入
from Crypto.Util.number import bytes_to_long, long_to_bytes

def decrypt(v, k):
    """TEA解密函数(加密的逆过程)"""
    v0 = c_uint32(v[0])
    v1 = c_uint32(v[1])
    delta = 195935983
    sum1 = c_uint32(delta * 32)  # 32轮后的sum值 = delta*32
    for i in range(32):
        # 逆序更新v1(加密的反向操作)
        v1.value -= (v0.value << 4 ^ v0.value >> 7) + v0.value ^ sum1.value + k[sum1.value >> 9 & 3]
        sum1.value -= delta
        # 逆序更新v0
        v0.value -= (v1.value << 4 ^ v1.value >> 7) + v1.value ^ sum1.value + k[sum1.value & 3]
    return (v0.value, v1.value)

def long_to_str(n):
    """32位整数转回4个ASCII字符(bytes_to_long的逆操作)"""
    # 转4字节大端字节串(因为bytes_to_long是按大端处理ASCII)
    # length=4 保证输出固定4字节,不足补前导0
    return long_to_bytes(n, 4).decode('ascii')

# 预设的加密结果
enc = [
    0xEEC7D402, 0x99E9363F, 0x853BDE61, 558171287,
    0x908F94B0, 1715140098, 986348143, 1948615354]
# 加密密钥
k = [255, 187, 51, 68]

# 分4组解密(每组2个元素)
flag = ""
for i in range(0, 8, 2):
    # 取当前组的加密值
    v0_enc = enc[i]
    v1_enc = enc[i+1]
    # 解密
    v0_dec, v1_dec = decrypt([v0_enc, v1_enc], k)
    # 转回字符串并拼接
    flag += long_to_str(v0_dec) + long_to_str(v1_dec)

# 输出结果
print("正确flag:flag{%s}" % flag)


#flag{Th1s_1s_A_Easy_Pyth0n__R3veRse_0}
标签: CTF Reverse 攻防世界
最后更新:2026年3月9日

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
    • 题解
  • crypt
    • 题解
  • bad_python
    • 题解

COPYRIGHT © 2025 lufer.cc. 网站访问统计

Theme Kratos Made By Seaton Jiang

鲁ICP备2021045819号