Y1rannn 发表于 2022-3-27 14:26

2022DASCTF X SU 三月月赛 逆向部分

## Easyre

asp壳

!(https://tianyu.xin/usr/uploads/2022/03/4184165291.png)


直接动调, 这里发现wrong,
!(https://tianyu.xin/usr/uploads/2022/03/2040385935.png)


长度0x2A, 前面要求DASCTF

!(https://tianyu.xin/usr/uploads/2022/03/1698380717.png)


关注到这里, eax是input, input ^ 2940后加0x47

!(https://tianyu.xin/usr/uploads/2022/03/2268893170.png)


最后跟这而比较

```
004017FB|.C785 24FFFFFF>mov ,-0x3D
00401805|.C785 28FFFFFF>mov ,-0x80
0040180F|.C785 2CFFFFFF>mov ,-0x2B
00401819|.C785 30FFFFFF>mov ,-0xE
00401823|.C785 34FFFFFF>mov ,-0x65
0040182D|.C785 38FFFFFF>mov ,0x30
00401837|.C785 3CFFFFFF>mov ,0xB
00401841|.C785 40FFFFFF>mov ,-0x4C
0040184B|.C785 44FFFFFF>mov ,0x55
00401855|.C785 48FFFFFF>mov ,-0x22
0040185F|.C785 4CFFFFFF>mov ,0x22
00401869|.C785 50FFFFFF>mov ,-0x7D
00401873|.C785 54FFFFFF>mov ,0x2F
0040187D|.C785 58FFFFFF>mov ,-0x69
00401887|.C785 5CFFFFFF>mov ,-0x48
00401891|.C785 60FFFFFF>mov ,0x20
0040189B|.C785 64FFFFFF>mov ,0x1D
004018A5|.C785 68FFFFFF>mov ,0x74
004018AF|.C785 6CFFFFFF>mov ,-0x2F
004018B9|.C785 70FFFFFF>mov ,0x1
004018C3|.C785 74FFFFFF>mov ,0x73
004018CD|.C785 78FFFFFF>mov ,0x1A
004018D7|.C785 7CFFFFFF>mov ,-0x4E
004018E1|.C745 80 C8FFF>mov ,-0x38
004018E8|.C745 84 C5FFF>mov ,-0x3B
004018EF|.C745 88 74000>mov ,0x74
004018F6|.C745 8C C0FFF>mov ,-0x40
004018FD|.C745 90 5B000>mov ,0x5B
00401904|.C745 94 F7FFF>mov ,-0x9
0040190B|.C745 98 0F000>mov ,0xF
00401912|.C745 9C D3FFF>mov ,-0x2D
00401919|.C745 A0 01000>mov ,0x1
00401920|.C745 A4 55000>mov ,0x55
00401927|.C745 A8 B2FFF>mov ,-0x4E
0040192E|.C745 AC A4FFF>mov ,-0x5C
00401935|.C745 B0 AEFFF>mov ,-0x52
0040193C|.C745 B4 7B000>mov ,0x7B
00401943|.C745 B8 ACFFF>mov ,-0x54
0040194A|.C745 BC 5C000>mov ,0x5C
00401951|.C745 C0 56000>mov ,0x56
00401958|.C745 C4 BCFFF>mov ,-0x44
0040195F|.C745 C8 23000>mov ,0x23
00401966|.C745 F0 00000>mov ,0x0


```

2940在这儿

!(https://tianyu.xin/usr/uploads/2022/03/2655372908.png)


```cpp
#include <cstdio>
#include <cstdint>
uint8_t tar[] = {
    -0x3D,-0x80,-0x2B,-0xE,-0x65,0x30,
    0xB,-0x4C,0x55,-0x22,0x22,-0x7D,
    0x2F,-0x69,-0x48,0x20,0x1D,0x74,
    -0x2F,0x1,0x73,0x1A,-0x4E,-0x38,
    -0x3B,0x74,-0x40,0x5B,-0x9,0xF,
    -0x2D,0x1,0x55,-0x4E,-0x5C,-0x52,
    0x7B,-0x54,0x5C,0x56,-0x44,0x23
};
uint8_t key[] = {
    0x38, 0x78, 0xDD, 0xE8,
    0x00, 0xAF, 0xBF, 0x3A,
    0x6B, 0xFB, 0xB8, 0x0C,
    0x85, 0x35, 0x5C, 0xAD,
    0xE6, 0x00, 0xE0, 0x8A,
    0x1D, 0xBD, 0x46, 0xD2,
    0x2B, 0x00, 0x15, 0x24,
    0xC6, 0xAD, 0xA1, 0xC9,
    0x7B, 0x12, 0x28, 0x00,
    0x05, 0x00, 0x72, 0x3E
};
int main() {
    for(int i = 0; i < 42; i ++ ) {
      // printf("0x%02x, ", (int)tar);
      tar -= 0x47;
      tar ^= key;
      putchar(tar);
    }
}
// DASCTF{Welc0me-t0-j01n-SU-l0ve-suyug1eg1u
```

最后一位错了但是能猜出来是e...

## Stargate

倦了, 18:15出的, 比赛18:00 结束, 这本来是题二血, 1000分啊, 心疼死我了

做的时候没截图, 这里简单说一下题目, 有兴趣的可以去BUU环境还开着,太大了贴不上来, 懒得找oss了

题目要求是nc上去, 然后会给一个base64之后的elf, 是动态出题的, 超时120秒

然后让你输入密码

每输入一个密码就会到另一个星球, 并且把一个bss段的变量从1变成0

大概有n<1000个这样的变量, 初步分析的时候以为变量和星球关联, 每个bss段的bool对应一个星球, 最后到某个特定星球的时候会检查这些bss段的变量是否都是0了, 如果是0了cat flag, 否则继续问你password

需要注意的是如果这个变量已经是0的话, 你是不能走这条路的.

但是这问题是哈密顿路问题, NPC, 做不了

后来发现有一个变量对应两个点的情况, 而且一个点也不只对应一个变量, 分析发现变量对应的是边, 这样就变成了个欧拉通路问题, 从特定起点开始周游诸边即可

python写算法题不会写, 网上随便当了个cpp的, 来回互相调用.

python交互



```python
from pwn import *
import base64
import sys
import subprocess
r = remote('node4.buuoj.cn', 26087)
r.recvline()
ELF = r.recvline()[:-1]
ELF = base64.b64decode(ELF)
with open("1", "wb") as f :
    f.write(ELF)
ans = input().split(' ')[:-1]
print(ans)
r.recvuntil('Password : ')
for i in range(len(ans)) :
    print(i, ans)
    r.sendline(ans)
    try :
      print(r.recvuntil(':'))
    except :
      break
r.interactive()
```

这个ELF给IDA读一下生成一下ASM

```python
import os
points = []
now, rt = -1, 0
flag = False
edges = []
with open("1.asm") as f :
    tmp = f.readlines()
    for i in range(len(tmp)) :
      if 'lea   rdi, aLegendHasItTha' in tmp :
            break
      if 'lea   rdi, aThere' in tmp :
            flag = True
      if 'call    _strcmp' in tmp :
            s = tmp.find('"')
            p = tmp
            if p not in points :
                points.append(p)
            if now == -1 :
                continue
            print(points, p, i)
            edges.append()
      elif 'lea   rdi, aNowYouIn' in tmp :
            s = tmp.find('se ')
            t = tmp.find(', ')
            p = tmp
            if p not in points :
                points.append(p)
            now = points.index(p)
            if flag :
                rt = now
                flag = False
print(points)
ff = open("tt.in", "w")
ff.write(str(len(points)) + " " + str(len(edges)) + " " + str(rt) + '\n')
for i in edges :
    ff.write(str(i) + " " + str(i) + "\n")
ff.close()
os.system(".\dfs.exe")
s = input().split(' ')
with open('tt.ans', "w") as f :
    for i in range(len(s)) :
      if s == s :
            continue
      try :
            f.write(points)-1]+" ")
      except :
            print(i)
print(len(edges)//2, len(s))
```

```cpp
#include <cstdio>
#include <iostream>
#include <vector>
using namespace std;
vector<int> v;
int x,y,n,m,du,sta=0x3f3f3f,mp,ans,top;
inline int read()
{
    int x=0,f=1;char c=getchar();
    while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
    while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
    return x*f;
}
int cnt1 = 0;
void dfs(int x)
{
    for(int i=1;i<=n;i++)
    {
      if(mp)
      {
            mp--;
            mp--;
            cnt1 ++;
            dfs(i);
      }
    }
    ans[++top]=x;
}
void dfs1(int p, int t) {
    v.push_back(p);
    for(int i = 1; i <= n; i ++ ) {
      if(mp) {
            mp--;
            cnt1 ++;
            mp--;
            dfs1(i, t);
      }
    }
}
int main()
{
    freopen("tt.in", "r", stdin);
    freopen("tt.out", "w", stdout);
    int rt;
    scanf("%d%d%d", &n, &m, &rt);
    rt ++;
    for(int i=1;i<=m;i++)
    {
      scanf("%d%d", &x, &y);
      x ++, y ++;
      mp = 1;
      mp = 1;
      du++;
      du++;
    }
    dfs(rt);
    while(true) {
      for(int i = 1; i <= n; i ++ ) {
            dfs1(i, i);
      }
      bool flag = 0;
      for(int i = 1; i <= n; i ++ ) for(int j = 1; j <= n; j ++ ) flag |= mp;
      if(!flag) break;
    }
    for(int i = 1; i <= top; i ++ )
      printf("%d ", ans);
    printf("%d", rt);
    printf("\n%d\n", cnt1);
    return 0;
}
```

这两个脚本一个是跑欧拉图一个是生成边, cpp脚本网上当的, 没想到这个破玩意成了最后的瓶颈, 我还不如自己写呢.

cpp写的复杂度应该不对, 但是本身数量级少, 还是硬缝补的, 就无所谓了

第一个py生成ELF->IDA生成ASM->第二个py生成边调用dfs, dfs结果输入回第二个py拿到点对应的名字, 名字给第一个py和服务器交互, 最后拿到flag

!(https://tianyu.xin/usr/uploads/2022/03/3340768425.png)


为什么我吃了午饭,为什么.......整个人都不好了

xiadongming 发表于 2022-3-27 16:26

Anneliese 发表于 2022-3-27 17:07

easyre最后两位不对是因为你的key没有少了两位加上 0x10, 0xA1 就可以了

0xchuxiuyun 发表于 2022-3-27 17:25

asp壳哦。。

iloveasdl 发表于 2022-3-28 08:51


感谢分享

gly198752 发表于 2022-3-28 11:15

向大佬学习,非常非常棒
页: [1]
查看完整版本: 2022DASCTF X SU 三月月赛 逆向部分