-
-
[原创]攻防世界PWN新手区:guess_num
-
发表于: 2022-4-4 14:14 11581
-
常规流程:file、checksec和运行程序
64位elf文件,开了金丝雀,NX,PIE保护
main函数:
分析主函数代码可以发现如果要返回success就需要输入正确的number(也就是v4变量),而v4变量有是rand函数生成的伪随机数,这是无法预测的除非能知道它的随机数种子,跟踪生成随机数的地方:
这个函数从头看到尾都没有看到哪里是可以注入的地方。这里其实是我的思路错了。因为回到主函数可以看到有一个危险函数gets,双击查看它的栈情况:
var_30处为v7的存放地址,seed就是随机数种子的存放地址。
注意到这里就好办了,v7和种子数在栈中是连在一起的,我们可以直接通过gets溢出,修改随机数种子的值,从而指定rand的生成值。
这里的种子数直接溢出为0,先写个c程序将随机数的种子为0时rand的生成情况:
__int64 __fastcall main(
int
a1, char
*
*
a2, char
*
*
a3)
{
int
v4;
/
/
[rsp
+
4h
] [rbp
-
3Ch
] BYREF
int
i;
/
/
[rsp
+
8h
] [rbp
-
38h
]
int
v6;
/
/
[rsp
+
Ch] [rbp
-
34h
]
char v7[
32
];
/
/
[rsp
+
10h
] [rbp
-
30h
] BYREF
unsigned
int
seed[
2
];
/
/
[rsp
+
30h
] [rbp
-
10h
]
unsigned __int64 v9;
/
/
[rsp
+
38h
] [rbp
-
8h
]
v9
=
__readfsqword(
0x28u
);
setbuf(stdin,
0LL
);
setbuf(stdout,
0LL
);
setbuf(stderr,
0LL
);
v4
=
0
;
v6
=
0
;
*
(_QWORD
*
)seed
=
sub_BB0();
puts(
"-------------------------------"
);
puts(
"Welcome to a guess number game!"
);
puts(
"-------------------------------"
);
puts(
"Please let me know your name!"
);
printf(
"Your name:"
);
gets(v7);
srand(seed[
0
]);
for
( i
=
0
; i <
=
9
;
+
+
i )
{
v6
=
rand()
%
6
+
1
;
printf(
"-------------Turn:%d-------------\n"
, (unsigned
int
)(i
+
1
));
printf(
"Please input your guess number:"
);
__isoc99_scanf(
"%d"
, &v4);
puts(
"---------------------------------"
);
if
( v4 !
=
v6 )
{
puts(
"GG!"
);
exit(
1
);
}
puts(
"Success!"
);
}
sub_C3E();
return
0LL
;
}
__int64 __fastcall main(
int
a1, char
*
*
a2, char
*
*
a3)
{
int
v4;
/
/
[rsp
+
4h
] [rbp
-
3Ch
] BYREF
int
i;
/
/
[rsp
+
8h
] [rbp
-
38h
]
int
v6;
/
/
[rsp
+
Ch] [rbp
-
34h
]
char v7[
32
];
/
/
[rsp
+
10h
] [rbp
-
30h
] BYREF
unsigned
int
seed[
2
];
/
/
[rsp
+
30h
] [rbp
-
10h
]
unsigned __int64 v9;
/
/
[rsp
+
38h
] [rbp
-
8h
]
v9
=
__readfsqword(
0x28u
);
setbuf(stdin,
0LL
);
setbuf(stdout,
0LL
);
setbuf(stderr,
0LL
);
v4
=
0
;
v6
=
0
;
*
(_QWORD
*
)seed
=
sub_BB0();
puts(
"-------------------------------"
);
puts(
"Welcome to a guess number game!"
);
puts(
"-------------------------------"
);
puts(
"Please let me know your name!"
);
printf(
"Your name:"
);
gets(v7);
srand(seed[
0
]);
for
( i
=
0
; i <
=
9
;
+
+
i )
{
v6
=
rand()
%
6
+
1
;
printf(
"-------------Turn:%d-------------\n"
, (unsigned
int
)(i
+
1
));
printf(
"Please input your guess number:"
);
__isoc99_scanf(
"%d"
, &v4);
puts(
"---------------------------------"
);
if
( v4 !
=
v6 )
{
puts(
"GG!"
);
exit(
1
);
}
puts(
"Success!"
);
}
sub_C3E();
return
0LL
;
}
__int64 sub_BB0()
{
int
fd;
/
/
[rsp
+
Ch] [rbp
-
14h
]
__int64 buf[
2
];
/
/
[rsp
+
10h
] [rbp
-
10h
] BYREF
buf[
1
]
=
__readfsqword(
0x28u
);
fd
=
open
(
"/dev/urandom"
,
0
);
if
( fd <
0
|| (
int
)read(fd, buf,
8uLL
) <
0
)
exit(
1
);
if
( fd >
0
)
close(fd);
return
buf[
0
];
}
__int64 sub_BB0()
{
int
fd;
/
/
[rsp
+
Ch] [rbp
-
14h
]
__int64 buf[
2
];
/
/
[rsp
+
10h
] [rbp
-
10h
] BYREF
赞赏
他的文章
- 关于迷宫题的一些求解思路 11248
- [原创]攻防世界PWN新手区:int_overflow 7870
- [原创]攻防世界PWN新手区:guess_num 11582
- [原创]攻防世界PWN新手区:level2 11858
- [原创]攻防世界PWN新手区:level0 6149
谁下载
看原图
赞赏
雪币:
留言: