我正在研究The Shellcoder手册的格式字符串部分。 正如书中建议我使用这样的代码来做我的测试:
[formatstring.c]
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
if(argc>1) {
if(argc>2) {
printf("Push a key to continue...\n");
getc(stdin);
}
printf("Sortie format string => ");
printf( argv[1] );
printf("\n");
}
printf("\n");
}
所以,我理解的诀窍是在堆栈上找到你的参数(你传递给formatstring的链,以及后面的printf使用的链)和偏移量。
./formatstring "aaaa%$offset\$x"
(将kernel.randomize_va_space设置为0,使偏移量保持不变)。为了找到这个偏移,他们使用一个小的批处理脚本
for((i=0; i<1000; i++)); do echo -n "$i " && ./formatstring "AAAAAAAA%$i\$x"; done | grep 4141
我把它弄出来了(这里偏移= 137)
137 Sortie format string => AAAAAAAA41414141
138 Sortie format string => AAAAAAAA25414141
Firstable我的“AAAAAAAA”在堆栈上没有“对齐”(我这里只计算7个41,但是我发送了8个'A'到格式字符串),它们放在堆栈上的方式似乎在时间内改变了=&GT;如果我在2小时后启动我的bash脚本(for)可能是'A'的“对齐”会发生变化。
更令人不安的是,当我向发送到./formatstring的参数添加字节时,偏移似乎会改变。如果我跑
for((i=0; i<1000; i++)); do echo -n "$i " && ./formatstring "AAAAAAAA%32x%$i\$x"; done | grep 4141
我得到了
136 Sortie format string => AAAAAAAA b7ff103041414141
137 Sortie format string => AAAAAAAA b7ff103025414141
或运行
for((i=0; i<1000; i++)); do echo -n "$i " && ./formatstring "AAAAAAAA%320x%$i\$x"; done | grep 4141
我得到了
139 Sortie format string => AAAAAAAA b7ff103041410067
140 Sortie format string => AAAAAAAA b7ff103041414141
141 Sortie format string => AAAAAAAA b7ff103033254141
正如你所看到的,偏移量变化并遵循逻辑我无法理解。根据这本书,这一切都不会发生。你知道它来自哪里吗?它是一种堆栈保护机制吗?我可以在gcc formatstring.c中删除它吗?
答案 0 :(得分:0)
好吧,我明白了。书中没有解释的东西(或者我误解为你可以看到英语不是我的本地语言)是你只能在你的论证中添加16个字符(字节)的集合,如果你想让它保持相同的偏移量堆。
因此,如果您在参数中添加“%320x”,则还必须使用(16-5 = 11)'A'(或任何其他字符)来完成,因为strlen(“%320x”)= 5。