分析

原题在adworld上。

ida x64反汇编代码如下(部分函数被我改了名):

1645703690404.png

选择4进到的函数里发现了程序是把time和fmt的内容拼接到了命令里运行

命令如下:

1
/bin/date -d @%d +'%s'

1645703816510.png

不难发现,只需要在fmt这里动一动手脚,就能getshell

1
/bin/date -d @%d +'' ; sh''

1645705085571.png

1645705181650.png

但是经过一番分析,发现在设置fmt的时候,这里是有一个字符白名单的,而常用的&;|这些都不能用,也没办法闭合单引号。

(当时就在想,能不能利用stack来覆写白名单,但这里显然不行)

再检查一下在读fmt和读timezone的时候都出现了的一个函数

1645705416053.png

1645705445082.png

在sub_400C26里发现了一个strdup(),这个函数的原型如下:

1
2
3
4
5
6
7
8
char * __strdup(const char *s)
{
size_t len = strlen(s) +1;
void *new = malloc(len);
if (new == NULL)
return NULL;
return (char *)memecpy(new,s,len);
}

可以看到,它内部调用了malloc(),然后就可以联想到uaf来解了。

1645705562974.png

果然,在退出程序的函数中可以看到,这里是先free掉了fmt,再free掉了timezone。如果一开始随便申请一个fmt,然后去选择退出,但是不输入y,然后此时fmt就被free掉了。再去选择设置timezone,调用一手strdup(),之前那个fmt的chunk就会被分配到这里了,而timezone这里不存在白名单,便可以构造出getshell的指令了。