XYCTF re部分wp

一.目录

1.喵喵喵的flag碎了一地

2.聪明的信使

3.你是真的大学生吗

4.DebugMe

5.砸核桃

6.ez_cube

7.baby unity

二.题解

1.喵喵喵的flag碎了一地

例行查壳,没有壳,64bit的,直接丢到ida-64里分析,分析结束,直接在函数窗口找到main函数,

三个提示,第一部分flag在字符串界面里,shift+F12就可以看到,第二部分在函数窗口里找,在最上面,

第三部分就是在函数里找,这里提到了Xref,就是交叉引用,CTRL+x,

就可以找到剩下这部分flag,拼接在一起就是完整的flag,签到题

2.聪明的信使

例行查壳,没有壳,32bit的,直接丢到ida-32里分析

分析结束,找到main函数,

很清晰,就是加密,然后比对,直接拿着密文解密就好了

enc = "oujp{H0d_TwXf_Lahyc0_14_e3ah_Rvy0ac@wc!}"
flag = ''
for i in range(len(enc)):
    if 96 < ord(enc[i]) <= 122:
        for j in range(97, 123):
            if (j + 9 - 97) % 26 + 97 == ord(enc[i]):
                flag += chr(j)
                break
    elif 64 < ord(enc[i]) <= 90:
        for k in range(65, 91):
            if (k + 9 - 65) % 26 + 65 == ord(enc[i]):
                flag += chr(k)
                break
    else:
        flag += enc[i]
print(flag)

3.你是真的大学生吗

这个题一查壳,没有壳,但是显示8bit,就猜这应该是直接分析汇编的题了,那么就随便那ida-32或者ida-64分析了。丢入ida-32,然后按空格,这样好看点,

dseg:0000 ; Segment type: Pure data
dseg:0000 dseg            segment para stack 'DATA' use16
dseg:0000                 assume cs:dseg
dseg:0000 unk_10000       db  0Dh                 ; DATA XREF: start+5↓o
dseg:0001                 db  0Ah
dseg:0002                 db  69h ; i
dseg:0003                 db  6Eh ; n
dseg:0004                 db  70h ; p
dseg:0005                 db  75h ; u
dseg:0006                 db  74h ; t
dseg:0007                 db  20h
dseg:0008                 db  73h ; s
dseg:0009                 db  74h ; t
dseg:000A                 db  72h ; r
dseg:000B                 db  69h ; i
dseg:000C                 db  6Eh ; n
dseg:000D                 db  67h ; g
dseg:000E                 db  3Ah ; :
dseg:000F                 db  24h ; $
dseg:0010 unk_10010       db  0Dh                 ; DATA XREF: start+15↓o
dseg:0011                 db  0Ah
dseg:0012                 db  24h ; $
dseg:0013 unk_10013       db  0Dh                 ; DATA XREF: start+52↓o
dseg:0014                 db  0Ah
dseg:0015                 db  59h ; Y
dseg:0016                 db  65h ; e
dseg:0017                 db  73h ; s
dseg:0018                 db  24h ; $
dseg:0019 unk_10019       db  76h ; v             ; DATA XREF: start+3D↓o
dseg:001A                 db  0Eh
dseg:001B                 db  77h ; w
dseg:001C                 db  14h
dseg:001D                 db  60h ; `
dseg:001E                 db    6
dseg:001F                 db  7Dh ; }
dseg:0020                 db    4
dseg:0021                 db  6Bh ; k
dseg:0022                 db  1Eh
dseg:0023                 db  41h ; A
dseg:0024                 db  2Ah ; *
dseg:0025                 db  44h ; D
dseg:0026                 db  2Bh ; +
dseg:0027                 db  5Ch ; \
dseg:0028                 db    3
dseg:0029                 db  3Bh ; ;
dseg:002A                 db  0Bh
dseg:002B                 db  33h ; 3
dseg:002C                 db    5
dseg:002D unk_1002D       db  15h                 ; DATA XREF: start+D↓o
dseg:002E byte_1002E      db 0                    ; DATA XREF: start+21↓r
dseg:002F unk_1002F       db    0                 ; DATA XREF: start+39↓o
dseg:0030                 db    0
dseg:0031                 db    0
dseg:0032                 db    0
dseg:0033                 db    0
dseg:0034                 db    0
dseg:0035                 db    0
dseg:0036                 db    0
dseg:0037                 db    0
dseg:0038                 db    0
dseg:0039                 db    0
dseg:003A                 db    0
dseg:003B                 db    0
dseg:003C                 db    0
dseg:003D                 db    0
dseg:003E                 db    0
dseg:003F                 db    0
dseg:0040                 db    0
dseg:0041                 db    0
dseg:0042                 db    0
dseg:0043                 db    0
dseg:0044                 db    0
dseg:0045                 db    0
dseg:0046                 db    0
dseg:0047                 db    0
dseg:0048                 db    0
dseg:0049                 db    0
dseg:004A                 db    0
dseg:004B                 db    0
dseg:004C                 db    0
dseg:004D                 db    0
dseg:004E                 db    0
dseg:004F                 db    0
dseg:004F dseg            ends
dseg:004F
seg001:0000 ; ===========================================================================
seg001:0000
seg001:0000 ; Segment type: Pure code
seg001:0000 seg001          segment byte public 'CODE' use16
seg001:0000                 assume cs:seg001
seg001:0000                 assume es:nothing, ss:dseg, ds:nothing, fs:nothing, gs:nothing
seg001:0000
seg001:0000 ; =============== S U B R O U T I N E =======================================
seg001:0000
seg001:0000 ; Attributes: noreturn
seg001:0000
seg001:0000                 public start
seg001:0000 start           proc near
seg001:0000                 mov     ax, seg dseg
seg001:0003                 mov     ds, ax
seg001:0005                 assume ds:dseg
seg001:0005                 lea     dx, unk_10000
seg001:0009                 mov     ah, 9
seg001:000B                 int     21h             ; DOS - PRINT STRING
seg001:000B                                         ; DS:DX -> string terminated by "$"
seg001:000D                 lea     dx, unk_1002D
seg001:0011                 mov     ah, 0Ah
seg001:0013                 int     21h             ; DOS - BUFFERED KEYBOARD INPUT
seg001:0013                                         ; DS:DX -> buffer
seg001:0015                 lea     dx, unk_10010
seg001:0019                 mov     ah, 9
seg001:001B                 int     21h             ; DOS - PRINT STRING
seg001:001B                                         ; DS:DX -> string terminated by "$"
seg001:001D                 xor     cx, cx
seg001:001F                 xor     ax, ax
seg001:0021                 mov     cl, byte_1002E
seg001:0025                 mov     si, 2Fh ; '/'
seg001:0028                 mov     al, [si]
seg001:002A                 add     si, cx
seg001:002C
seg001:002C loc_1007C:                              ; CODE XREF: start+37↓j
seg001:002C                 sub     si, 1
seg001:002F                 xor     [si], al
seg001:0031                 mov     al, [si]
seg001:0033                 dec     cx
seg001:0034                 cmp     cx, 0
seg001:0037                 jnz     short loc_1007C
seg001:0039                 lea     si, unk_1002F
seg001:003D                 lea     di, unk_10019
seg001:0041
seg001:0041 loc_10091:                              ; CODE XREF: start+50↓j
seg001:0041                 mov     al, [si]
seg001:0043                 mov     bl, [di]
seg001:0045                 add     si, 1
seg001:0048                 inc     di
seg001:0049                 cmp     al, bl
seg001:004B                 jnz     short loc_100AA
seg001:004D                 cmp     cx, 0
seg001:0050                 jnz     short loc_10091
seg001:0052                 lea     dx, unk_10013
seg001:0056                 mov     ah, 9
seg001:0058                 int     21h             ; DOS - PRINT STRING
seg001:0058                                         ; DS:DX -> string terminated by "$"
seg001:005A
seg001:005A loc_100AA:                              ; CODE XREF: start+4B↑j
seg001:005A                 mov     ah, 4Ch
seg001:005C                 int     21h             ; DOS - 2+ - QUIT WITH EXIT CODE (EXIT)
seg001:005C start           endp                    ; AL = exit code
seg001:005C
seg001:005C seg001          ends
seg001:005C
seg001:005C
seg001:005C                 end start

这个还是很好看的,就是一个异或,不过是级联异或,那么我们就可以直接用厨子梭一下就好了

xyctf{you_know_8086}

4.DebugMe

这道题在题目提示就已经给了,就是去动态调试这个.apk文件。那么动态调试,就需要用到虚拟器,我这里是用到雷电模拟器,然后调试的工具是jadx,但是这里要记住,可能需要把雷电模拟器自带的adb.exe给换掉,当时弄了好久,发现是这玩意出了问题,以及模拟器要调成手机模式

那么就开始吧

1.先用MT管理器查看其是否具备可调式的属性,如果没有得加上去,在application那一个<>里加入,android:debuggable="true",因为这个.apk文件本身没有这个属性,所以得加,如果有,但现实的是false,就改成true,然后得记得,加完之后,点击保存,然后记得加上签名,点击自动签名,

2.打开模拟器,安装这个修改了的.apk文件,然后打开设置,进入开发者模式,如果没有进,就多点几次版本号,就好了,

打开USB调试,然后再选择调试应用,现在我们要调试的应用,如果在之前,没有把它的可调式属性改成true,这里就无法选择。

3.打开cmd,然后运行adb.exe,这里要记得去用户的环境变量里添加,但是文件地址只到bin,

如果这里记得要检查端口是否连接上,以及设备连的是否是要使用的设备或者模拟器,可以用

adb devices -l查看连接的设备

adb shell ps查看线程状态

连接上以后,就可以进行动调了

4.用jadx打开

点击这个和甲虫一样的图标,

如果前面的步骤正确,就可以到这里,可能第一个选项没有,但不影响,

然后在模拟器里点击应用,就会显示这个,此时,jadx那边也会显示线程

点击线程

就到了这里,然后点击运行,直到模拟器那边显示

再点击那个按钮,就出flag了

5.砸核桃

下载好附件,是.exe文件,先查壳吧,

32bit的,同时我们可以看到是UPX壳,换了名的,那么我就用010editor修改一下,

这样,我们修改完成之后,保存一下,再用工具脱壳,

很遗憾,没有脱壳成功,那么我们就只能手动脱壳了,刚哈这又是32bit的可执行文件,那么就用吾爱破解打开,

恰好我们在这里看到了pushad,我们先按两次F8,

看到旁边寄存器,除了EIP,只有ESP变红了,那么我们就可以利用ESP定律进行脱壳,然后我们光标来到ESP寄存器上,右键,选择HD break [ESP],下个断点,然后F9运行,

此时我们可以看到程序跑到了popfd这一行,我们继续F8单步,通过第一个jmp跳转,可以看到,

如果没有看到汇编代码,只看到了十六进制数,可以右键,然后在分析选项中,找到,从模块中删除分析,就好了,这里我们仔细阅读代码,就可以看到这里有一个函数的开头,push ebp,mov ebp,esp,然后光标来到这里,右键,用吾爱破解的插件进行脱壳,点击用OllyDump脱壳调试进程,

点击获取EIP作为OEP,然后点击脱壳,再将文件取名保存即可,

此时我们再去查壳,显示壳还在,因为我们只是更改了程序的入口点,壳的特征还在。接下来我们就可以进行正常分析了,

直接用ida-32打开分析,找到main函数,就可以得到伪代码了,就是一个简单的异或,脚本如下,

不过得动调一下才能得正确的数据,

key = "this_is_not_flag"
enc = [0x12, 0x04, 0x08, 0x14, 0x24, 0x5C, 0x4A, 0x3D, 0x56, 0x0A, 0x10,
       0x67, 0x00, 0x41, 0x00, 0x01, 0x46, 0x5A, 0x44, 0x42, 0x6E,
       0x0C, 0x44, 0x72, 0x0C, 0x0D, 0x40, 0x3E, 0x4B, 0x5F, 0x02,
       0x01, 0x4C, 0x5E, 0x5B, 0x17, 0x6E, 0x0C, 0x16, 0x68, 0x5B,
       0x12, 0x48]
flag = ''
for i in range(42):
    flag += chr(ord(key[i % 16]) ^ enc[i])
print(flag)

得到flag:flag{59b8ed8f-af22-11e7-bb4a-3cf862d1ee75}

6.ez_cube

下载好附件,是一个.exe文件,依旧现查壳,

没有壳,64bit,直接丢到ida64里分析,分析结束,在函数窗口找到main函数,然后就得到伪代码了,

int __fastcall main_0(int argc, const char **argv, const char **envp)
{
  int i; // [rsp+44h] [rbp+24h]
  char v5; // [rsp+64h] [rbp+44h]
  int v6; // [rsp+84h] [rbp+64h]

  j___CheckForDebuggerJustMyCode(&unk_1400240A2, argv, envp);
  for ( i = 0; i < 9; ++i )
  {
    qword_14001FB60[i] = &unk_14001CC24;
    qword_14001FB00[i] = "Blue";
    qword_14001FAA0[i] = "Green";
    qword_14001FA40[i] = "Orange";
    qword_14001F9E0[i] = "Yellow";
    qword_14001F980[i] = "White";
  }
  qword_14001FB00[1] = &unk_14001CC24;
  qword_14001FB60[1] = "Green";
  qword_14001FAA0[1] = "Blue";
  while ( 1 )
  {
    do
      v5 = getchar();
    while ( v5 == 10 );
    switch ( v5 )
    {
      case 'R':
        sub_140011375();
        break;
      case 'U':
        sub_1400113BB();
        break;
      case 'r':
        sub_140011366();
        break;
      case 'u':
        sub_14001115E();
        break;
    }
    ++dword_14001F1C0;
    v6 = sub_140011389();
    if ( v6 == 1 )
      break;
    if ( v6 == 2 )
      goto LABEL_19;
  }
  sub_14001119F(&unk_14001CCA0);
LABEL_19:
  system("pause");
  return 0;
}

第一个for循环就是将魔方进行初始化,后面的三行代码就是将某三个面的最上面那一行的中间的那个换成了其他颜色。然后就是读入我们的输入,怎么操作,把魔方进行还原,具体R U r u的所带来的影响进入每个函数查看即可。

R:右侧面进行顺时针转一圈;r相反

U:上面这层进行顺时针转一圈;u相反

来玩魔方肯定是不可能的啦,去网上一搜三阶魔方三面凹字还原,教程一堆,不过只有一种才是正确答案,控制步数在12步以内,那么flag就是 flag{RuRURURuruRR}

7.baby unity

这道题是根据题目的hint所提供的工具完成的

GitHub - Perfare/Il2CppDumper: Unity il2cpp reverse engineer

用这个工具对文件的符号进行修复。

先查壳,.exe文件和.dll文件(GameAssembly.dll)都有壳,都脱下吧。

我们通过链接所下载的是Il2CppDumper-win-v6.7.40.zip。

然后我点击运行Il2CppDumper.exe,再依次选择GameAssembly.dll,global-metadata.dat(在文件夹里,找找),然后就可以看到

我们先用ILSpy打开Assembly-CSharp看看有没有什么有用的信息,

果不其然,这里有加密函数,可是我们却看不到完整的,这也就是我们为什么要使用这个工具的原因,记下这个函数名,待会有用

然后将GameAssembly.dll用ida-64分析,这是一个漫长的过程,分析结束,我们就可以利用Il2CppDumper自带的恢复符号的idapython脚本进行复原,在File选项中找到Script flie,然后依次选中这三个文件,ida_with_struct_py3.py-->script.json-->il2cpp.h,然后静等ida自己跑,结束后,我们在函数窗口搜索Check....,

就可以找到加密函数了,分析代码下来,就是先进行base64加密,然后再进行一个简单的异或,但是加密结果在ida里是找不到的,要在stringliteral.json里找,我当时在做的时候,是通过flag的格式的开头XYCTF反推找到的加密结果,然后进行完整的逆向,得到flag,

8.今夕是何年

这道题,就真的是跑一下就出了,但是我们需要支持龙芯架构的系统来跑,然后我用的是qemu,在Ubuntu上下载了这玩意,然后跑一下,

  • 13
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值