2022DASCTF X SU 三月月赛 逆向部分
## Easyreasp壳
!(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)
为什么我吃了午饭,为什么.......整个人都不好了 easyre最后两位不对是因为你的key没有少了两位加上 0x10, 0xA1 就可以了 asp壳哦。。
感谢分享 向大佬学习,非常非常棒
页:
[1]