获取中...

-

Just a minute...

GXYCTF几道逆向wp

lucky_guy

main函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// local variable allocation has failed, the output may be wrong!
int __cdecl main(int argc, const char **argv, const char **envp)
{
unsigned int v4; // [rsp+14h] [rbp-Ch]
unsigned __int64 v5; // [rsp+18h] [rbp-8h]

v5 = __readfsqword(0x28u);
welcome(*(_QWORD *)&argc, argv, envp);
puts("_________________");
puts("try to patch me and find flag");
v4 = 0;
puts("please input a lucky number");
__isoc99_scanf("%d", &v4);
patch_me(v4);
puts("OK,see you again");
return 0;
}

需要输入一个数字然后进入patch_me中

patch_me

1
2
3
4
5
6
7
8
9
10
int __fastcall patch_me(int a1)
{
int result; // eax

if ( a1 % 2 == 1 )
result = puts("just finished");
else
result = get_flag();
return result;
}

当输入的值符合要求时进入get_flag

get_flag

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
for ( i = 0; i <= 4; ++i )
{
switch ( rand() % 200 ) // rand产生5个随机数
{
case 1:
puts("OK, it's flag:");
memset(&s, 0, 0x28uLL);
strcat((char *)&s, f1); // f1是GXY{do_not_
strcat((char *)&s, &f2);
printf("%s", &s);
break;
case 2:
printf("Solar not like you");
break;
case 3:
printf("Solar want a girlfriend");
break;
case 4:
v6 = 0;
s = 'fo`guci';
strcat(&f2, (const char *)&s); // f2是'icug`of '
break;
case 5:
for ( j = 0; j <= 7; ++j )
{
if ( j % 2 == 1 )
v1 = *(&f2 + j) - 2;
else
v1 = *(&f2 + j) - 1;
*(&f2 + j) = v1;
}
break;
default:
puts("emmm,you can't find flag 23333");
break;
}
}
1
2
3
4
5
6
7
8
9
a=[0x7F,0x66,0x6F,0x60,0x67,0x75,0x63,0x69]
a.reverse()
flag=''
for i in range(len(a)):
if i%2==1:
flag+=chr(a[i]-2)
else:
flag+=chr(a[i]-1)
print (flag)

GXY{do_not_hate_me}

simple CPP

0x01

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
if ( v37 > 0 )
{
v5 = 0i64;
do
{
v6 = &Memory; // v6是输入的字符串
if ( v38 >= 0x10 )
v6 = Memory;
v7 = &Dst; // Dst是i_will_check_is_debug_or_not
if ( (unsigned __int64)qword_140006060 >= 0x10 )
v7 = (void **)Dst;
v3[v5] = v6[v5] ^ *((_BYTE *)v7 + v4++ % 27);// 加密
++v5;
}
while ( v4 < v37 );
}

0x02

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
v35 = v15[2];                                
v16 = v15[1];
v17 = *v15;
v18 = sub_14000223C(0x20ui64);
if ( IsDebuggerPresent() )
{
sub_1400019C0(std::cout, "Hi , DO not debug me !");
Sleep(0x7D0u);
exit(0);
}
v19 = v16 & v17;
*v18 = v16 & v17;
v20 = v35 & ~v17;
v18[1] = v20;
v21 = ~v16;
v22 = v35 & v21;
v18[2] = v35 & v21;
v23 = v17 & v21;
v18[3] = v23;
if ( v20 != 1176889593874i64 )
{
v18[1] = 0i64;
v20 = 0i64;
}
v24 = v20 | v19 | v22 | v23;
v25 = v15[1];
v26 = v15[2];
v27 = v22 & *v15 | v26 & (v19 | v25 & ~*v15 | ~(v25 | *v15));
v28 = 0;
if ( v27 == 577031497978884115i64 )
v28 = v24 == 4483974544037412639i64;
if ( (v24 ^ v15[3]) == 4483974543195470111i64 )
v0 = v28;
if ( (v20 | v19 | v25 & v26) != (~*v15 & v26 | 864693332579200012i64) || v0 != 1 )
{
sub_1400019C0(std::cout, "Wrong answer!try again");
j_j_free(v3);
}
else
{
v29 = sub_1400019C0(std::cout, "Congratulations!flag is GXY{");
v30 = &Memory;
if ( v38 >= 0x10 )
v30 = Memory;
v31 = sub_140001FD0(v29, v30, v37);
sub_1400019C0(v31, "}");
j_j_free(v3);
}

v20 = v15[2] & v15[0]
v20 = 1176889593874
v24 = v15[2] & ~v15[0] | v15[1] & v15[0] | v15[2] & ~v15[1] | v15[0] & ~v15[1]
v24 = 4483974544037412639
v27 = v15[2] & ~v15[1] & v15[0] | v15[2] & (v15[1] & v15[0] | v15[1] & ~v15[0] | ~(v15[1] | v15[0]))
v27 = 577031497978884115
(v24 ^ v15[3]) = 4483974543195470111
(v15[2] & ~v15[0] | v15[1] & v15[0] | v15[1] & v15[2]) = (
v15[0] & v15[2] | 0xC00020130082C0C)
将输入的DXY{}中间的字符处理 :与0异或,第24位与0F异或每8位依次放入v15[0]-[3],求出v15[0]-[3]

1
2
3
4
5
6
7
8
9
from z3 import *
x,y,z,w=BitVecs('x y z w',64)
s=Solver()
s.add((~x)&z==1176889593874)
s.add(((z&~x)|(x&y)|(z&~y)|(x&~y))==4483974544037412639)
s.add(((z&~x)|(x&y)|(z&(~y))|(x&(~y)))^w==4483974543195470111)
s.add(((z&~y)&x|z&((x&y)|y&~x|~(y|x)))==577031497978884115)
print(s.check())
print(s.model())

w = 842073600
y = 3906943046058528520
x = 4483973367147818765
z = 577031497978884115

1
2
3
4
5
6
7
8
9
10
11
#include<stdio.h>
int main()
{
char a[29] = "i_will_check_is_debug_or_not";
int b[30] = { 0x3e,0x3a,0x46,0x05,0x33,0x28,0x6f,0x0d,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x08,0x2,0x07,0x17,0x15,0x3e,0x30,0x13,0x32,0x31,0x06,0x00,0x00 };
for (int i = 0;i < 27; i++)
{
printf("%c", a[i % 27] ^ b[i]);
}
return 0;
}

中间部分替换掉
GXY{We1l_D0ne!P0or_algebra_am_i}

相关文章
评论
分享
  • 网鼎杯部分wp

    pwnboom1分析远程已经打不通了,远程的偏移和本地的偏移不一样,只能复现一下本地的了。 首先看到流程图,代码量很大,有很大的switch语句和嵌套结构,可能是虚拟机或者是解析器。 从下图看出是一个C语言的解析器。 然后看了...

    网鼎杯部分wp
  • 数字中国创新大赛

    又是自闭的一天。。 game这一题是关于python字节码的题目,之前没有了解过,看了几篇关于python字节码的文章,死磕,手工还原。。 python字节码 12345678910111213141516171819202122...

    数字中国创新大赛
  • hitcontraining_uaf

    一道简单的uaf的题目 保护12345Arch: i386-32-little RELRO: Partial RELRO Stack: No canary found NX: NX...

    hitcontraining_uaf
Please check the parameter of comment in config.yml of hexo-theme-Annie!