-
-
[原创]无路远征——GLIBC2.37后时代的IO攻击之道(三)house_of_借刀杀人
-
发表于: 2023-2-9 12:48 17737
-
为了说明下一个利用链,继续水一篇。
xctf 2021 final
同名题目提出了一种利用方式,是在calloc
的情况下,巧妙利用连续执行malloc、memcpy、free
,将提前布置在tcache
中的堆块申请出来,并赋值利用。关键代码如下。
可以看出,在memcpy (new_buf, old_buf, old_blen);
过程中,old_buf
和old_blen
都是可控的。那么理论上我们将tcache
指向任意地址就可以实现任意地址写,但同时面临3个问题。
在IO中,由于要处理宽字符的原因,有很多memcpy、memmove
等内存函数覆写函数,但想利用好它们却非常困难。以_IO_default_xsputn
为例,
从上面代码中可以看出此处调用的memcpy
与house_of_pig
中略有不同,在__mempcpy (f->_IO_write_ptr, s, count)
中,目标地址可控,源地址不可控,count
虽然是计算得来,但由于有需要判断,也是不可控。也就是说我能控制写入的地址,但无法控制写入什么。与house_of_pig
相比,此种手段的优势在于不需要调用malloc
,就可以指定要写入的地址。当然,要利用这个手段,我们还有2个问题需要解决。
下一篇文章将介绍如何绕过和利用。
......
char
*
old_buf
=
fp
-
>_IO_buf_base;
size_t old_blen
=
_IO_blen (fp);
......
new_buf
=
malloc (new_size);
if
(new_buf
=
=
NULL)
{
/
*
__ferror(fp)
=
1
;
*
/
return
EOF;
}
if
(old_buf)
{
memcpy (new_buf, old_buf, old_blen);
/
/
赋值函数
free (old_buf);
/
*
Make sure _IO_setb won't
try
to delete _IO_buf_base.
*
/
fp
-
>_IO_buf_base
=
NULL;
}
......
......
char
*
old_buf
=
fp
-
>_IO_buf_base;
size_t old_blen
=
_IO_blen (fp);
......
new_buf
=
malloc (new_size);
if
(new_buf
=
=
NULL)
{
/
*
__ferror(fp)
=
1
;
*
/
return
EOF;
}
if
(old_buf)
{
memcpy (new_buf, old_buf, old_blen);
/
/
赋值函数
free (old_buf);
/
*
Make sure _IO_setb won't
try
to delete _IO_buf_base.
*
/
fp
-
>_IO_buf_base
=
NULL;
}
......
size_t _IO_default_xsputn (
FILE
*
f, const void
*
data, size_t n)
{
const char
*
s
=
(char
*
) data;
size_t more
=
n;
if
(more <
=
0
)
return
0
;
for
(;;)
{
/
*
Space available.
*
/
if
(f
-
>_IO_write_ptr < f
-
>_IO_write_end)
{
size_t count
=
f
-
>_IO_write_end
-
f
-
>_IO_write_ptr;
/
/
count 在计算后还需要一个判断
if
(count > more)
count
=
more;
if
(count >
20
)
{
/
/
此处为可以覆写的位置。
/
/
困难
1
:执行后程序流无法控制。
/
/
困难
2
:s 和 n 均不可控
f
-
>_IO_write_ptr
=
__mempcpy (f
-
>_IO_write_ptr, s, count);
s
+
=
count;
}
else
if
(count)
{
char
*
p
=
f
-
>_IO_write_ptr;
ssize_t i;
for
(i
=
count;
-
-
i >
=
0
; )
*
p
+
+
=
*
s
+
+
;
f
-
>_IO_write_ptr
=
p;
}
more
-
=
count;
}
if
(more
=
=
0
|| _IO_OVERFLOW (f, (unsigned char)
*
s
+
+
)
=
=
EOF)
break
;
more
-
-
;
}
return
n
-
more;
}
size_t _IO_default_xsputn (
FILE
*
f, const void
*
data, size_t n)
{
const char
*
s
=
(char
*
) data;
size_t more
=
n;
if
(more <
=
0
)
return
0
;
for
(;;)
{
/
*
Space available.
*
/
if
(f
-
>_IO_write_ptr < f
-
>_IO_write_end)
{
赞赏记录
参与人
雪币
留言
时间
一笑人间万事
为你点赞~
2023-12-24 01:44
我超啊
为你点赞~
2023-8-2 10:18
gid
为你点赞~
2023-3-18 17:27
赞赏
他的文章
- [原创]反序列化的前生今世 9081
- [原创]gdb在逆向爆破中的应用 3037
- [原创]EOP编程 8860
- [原创]格式化字符串打出没有回头路(下)——回头望月 45079
- [原创]格式化字符串打出没有回头路(上) 16527
看原图
赞赏
雪币:
留言: