总的来说有两个层面的攻击,exit.c下基本上是结构体指针的挟持,_dl_fini层面上基本上是linkmap的字段修改或整个挟持
在exit函数调用的时候会进行tls的解构
void
attribute_hidden
__run_exit_handlers (int status, struct exit_function_list **listp,
bool run_list_atexit, bool run_dtors)
{
/* First, call the TLS destructors. */
#ifndef SHARED
if (&__call_tls_dtors != NULL)
#endif
if (run_dtors)
__call_tls_dtors (); // dstruct tls
...
这里传入参数的时候run_dtors是0x0
__call_tls_dtors的代码如下:
void
__call_tls_dtors (void)
{
while (tls_dtor_list)
{
struct dtor_list *cur = tls_dtor_list;
dtor_func func = cur->func;
#ifdef PTR_DEMANGLE
PTR_DEMANGLE (func);
#endif
tls_dtor_list = tls_dtor_list->next;
func (cur->obj);
atomic_fetch_add_release (&cur->map->l_tls_dtor_count, -1);
free (cur);
}
}
struct dtor_list:
type = struct dtor_list {
dtor_func func; // dtor_func是函数指针
void *obj;
struct link_map *map;
struct dtor_list *next;
}
可以看到这里会依次调用它的func
可以利用这一点构造ROP链条
但是tls_dtor_list在mmap出来的一段中(ld的前一段 相当于打ld需要爆破offset
这种打法的利用条件仅为能够修改tls_dtor_list的值为一个地址,然后能够往这个地址填东西就行
概念验证:
发现地址还发生了变化 查看宏定义 前面有个PTR_DEMANGLE