-
-
[原创]攻防世界PWN新手区:int_overflow
-
发表于: 2022-4-6 11:17 7860
-
常规流程:file、checksec和运行程序
开了NX保护
根据题目的提示,这里的知识点是整数溢出,那么What is the int_flow?
由于整数在内存里面保存在一个固定长度的空间内,它能存储的最大值和最小值是固定的,如果我们尝试去存储一个数,而这个数又大于这个固定的最大值时,就会导致整数溢出。
具体的证书溢出看之前的笔记分析:
https://magnificent-syrup-61f.notion.site/f3e9be83616e45a8a4865709f737413c
丢进ida32分析:
结合运行的结果可以知道主函数会接收一个值,然后做分支语句选择调用login()函数还是输出“Bye~”
这个函数主要负责的就是接收用户名和密码,先判断这里是否有溢出点:buf变量负责接收密码,它定义的空间大小为512字节,而read函数只读取了409字节,它读取的空间小于自己本身所占的空间所以不满足溢出条件。再看s变量,它负责接收用户名,定义的空间大小为40字节,而接收的最大空间大小只有25字节,同样也不满足溢出条件,这里接收的两个值在这个函数的栈空间都不满足溢出条件,只能另找出路。可以看到返回时还调用了check_passwd函数,接着分析该函数:
这个函数是对接收的密码进行判断,首先密码的长度要在4到8之间。这里注意一个地方就是存放strlen的len变量空间大小只有一字节,根据题目名称的提示我们可以联想到的一个点就是只要我们输入的长度值大于一个字节能存储的空间,就可以导致一个问题就是整数溢出,这里举个例子:
通过分析login函数我们知道了接收密码的buf变量可以接收的最大地址空间为409字节,这个空间完全够我们构造栈溢出了,因为要想通过if判断len的值必须要在4~8之间,所以要构造的payload的总长度在260(1 0000 0100)字节~264(1 0000 1000)字节之间。
确定了栈溢出的方式,接下来看payload如何构造:
首先观察其栈空间:
程序从dest开始总共分配了0x14个字节的地址空间,之后是4个字节的esp值,最后就是四个字节我们要修改的返回地址。
分析到这就万事俱备只欠后门函数了,这里我吸取了上次的教训先观察一下函数的窗口:
这个函数已看就不正常,进去看一下里面的代码:
好了,后门函数也找到了,下面写shellcode。
这里补充一个python的知识点:ljust()方法
用于返回一个原字符串左对齐,并使用空格填充至指定长度的新字符串。如果指定的长度小于原字符串的长度则返回原字符串。
这里的payload还可以这么写:
cyberpeace{2045fa7e3286f5b911ed7f0515ede0ad}
int
__cdecl main(
int
argc, const char
*
*
argv, const char
*
*
envp)
{
int
v4;
/
/
[esp
+
Ch] [ebp
-
Ch] BYREF
setbuf(stdin,
0
);
setbuf(stdout,
0
);
setbuf(stderr,
0
);
puts(
"---------------------"
);
puts(
"~~ Welcome to CTF! ~~"
);
puts(
" 1.Login "
);
puts(
" 2.Exit "
);
puts(
"---------------------"
);
printf(
"Your choice:"
);
__isoc99_scanf(
"%d"
, &v4);
if
( v4
=
=
1
)
{
login();
}
else
{
if
( v4
=
=
2
)
{
puts(
"Bye~"
);
exit(
0
);
}
puts(
"Invalid Choice!"
);
}
return
0
;
}
int
__cdecl main(
int
argc, const char
*
*
argv, const char
*
*
envp)
{
int
v4;
/
/
[esp
+
Ch] [ebp
-
Ch] BYREF
setbuf(stdin,
0
);
setbuf(stdout,
0
);
setbuf(stderr,
0
);
puts(
"---------------------"
);
puts(
"~~ Welcome to CTF! ~~"
);
puts(
" 1.Login "
);
puts(
" 2.Exit "
);
puts(
"---------------------"
);
printf(
"Your choice:"
);
__isoc99_scanf(
"%d"
, &v4);
if
( v4
=
=
1
)
{
login();
}
else
{
if
( v4
=
=
2
)
{
puts(
"Bye~"
);
exit(
0
);
}
puts(
"Invalid Choice!"
);
}
return
0
;
}
char
*
login()
{
char buf[
512
];
/
/
[esp
+
0h
] [ebp
-
228h
] BYREF
char s[
40
];
/
/
[esp
+
200h
] [ebp
-
28h
] BYREF
memset(s,
0
,
0x20u
);
memset(buf,
0
, sizeof(buf));
puts(
"Please input your username:"
);
read(
0
, s,
0x19u
);
printf(
"Hello %s\n"
, s);
puts(
"Please input your passwd:"
);
read(
0
, buf,
0x199u
);
return
check_passwd(buf);
}
char
*
login()
{
char buf[
512
];
/
/
[esp
+
0h
] [ebp
-
228h
] BYREF
char s[
40
];
/
/
[esp
+
200h
] [ebp
-
28h
] BYREF
memset(s,
0
,
0x20u
);
memset(buf,
0
, sizeof(buf));
puts(
"Please input your username:"
);
read(
0
, s,
0x19u
);
printf(
"Hello %s\n"
, s);
puts(
"Please input your passwd:"
);
read(
0
, buf,
0x199u
);
return
check_passwd(buf);
}
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
赞赏
- 关于迷宫题的一些求解思路 11226
- [原创]攻防世界PWN新手区:int_overflow 7861
- [原创]攻防世界PWN新手区:guess_num 11574
- [原创]攻防世界PWN新手区:level2 11850
- [原创]攻防世界PWN新手区:level0 6145