Easyre
asp壳
直接动调, 这里发现wrong,
长度0x2A, 前面要求DASCTF
关注到这里, eax[edx]是input[i], input[i] ^ 2940[i]后加0x47
最后跟这而比较
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在这儿
#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
为什么我吃了午饭,为什么.......整个人都不好了