[CTF/Reverse] 2022DASCTF X SU 三月 逆向部分
侧边栏壁纸
  • 累计撰写 65 篇文章
  • 累计收到 3 条评论

[CTF/Reverse] 2022DASCTF X SU 三月 逆向部分

x1n
x1n
2022-03-27 / 0 评论 / 135 阅读 / 正在检测是否收录...

Easyre

asp壳

image-20220326113620328.png

直接动调, 这里发现wrong,
image-20220326113653315.png

长度0x2A, 前面要求DASCTF

image-20220326114518105.png

关注到这里, eax[edx]是input[i], input[i] ^ 2940[i]后加0x47

image-20220326114712848.png

最后跟这而比较

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

2940在这儿

image-20220326115533991.png

#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[i]);
        tar[i] -= 0x47;
        tar[i] ^= key[i];
        putchar(tar[i]);
    }
}
// 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交互

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[i])
    r.sendline(ans[i])
    try :
        print(r.recvuntil(':'))
    except :
        break
r.interactive()

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

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[i] :
            break
        if 'lea     rdi, aThere' in tmp[i] :
            flag = True
        if 'call    _strcmp' in tmp[i] :
            s = tmp[i-1].find('"')
            p = tmp[i-1][s+1:-2]
            if p not in points :
                points.append(p)
            if now == -1 :
                continue
            print(points[now], p, i)
            edges.append([now, points.index(p)])
        elif 'lea     rdi, aNowYouIn' in tmp[i] :
            s = tmp[i].find('se ')
            t = tmp[i][s:].find(', ')
            p = tmp[i][s+3:s+t]
            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[0]) + " " + str(i[1]) + "\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[i] == s[i-1] :
            continue
        try :
            f.write(points[int(s[i])-1]+" ")
        except :
            print(i)
print(len(edges)//2, len(s))
#include <cstdio>
#include <iostream>
#include <vector>
using namespace std;
vector<int> v[1000];
int x,y,n,m,du[5020],sta=0x3f3f3f,mp[2520][2520],ans[5200],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[x][i])
        {
            mp[x][i]--;
            mp[i][x]--;
            cnt1 ++;
            dfs(i);
        }
    }
    ans[++top]=x;
}
void dfs1(int p, int t) {
    v[t].push_back(p);
    for(int i = 1; i <= n; i ++ ) {
        if(mp[p][i]) {
            mp[p][i]--;
            cnt1 ++;
            mp[i][p]--;
            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[x][y] = 1;
        mp[y][x] = 1;
        du[x]++;
        du[y]++;
    }
    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[i][j];
        if(!flag) break;
    }
    for(int i = 1; i <= top; i ++ ) 
        printf("%d ", ans[i]);
    printf("%d", rt);
    printf("\n%d\n", cnt1);
    return 0;
}

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

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

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

image-20220326183105465.png

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

2

评论 (0)

取消