- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
所以我有这个功能:
void print_usage(char* arg)
{
char buffer[640];
sprintf(buffer, "Usage: %s [options]\n"
"Randomly generates a password, optionally writes it to /etc/shadow\n"
"\n"
"Options:\n"
"-s, --salt <salt> Specify custom salt, default is random\n"
"-e, --seed [file] Specify custom seed from file, default is from stdin\n"
"-t, --type <type> Specify different encryption method\n"
"-v, --version Show version\n"
"-h, --help Show this usage message\n"
"\n"
"Encryption types:\n"
" 0 - DES (default)\n"
" 1 - MD5\n"
" 2 - Blowfish\n"
" 3 - SHA-256\n"
" 4 - SHA-512\n", arg);
printf(buffer);
}
我想利用格式化字符串漏洞攻击(我的任务)。这是我的尝试:
我有一个利用 noops 和 shell 代码填充缓冲区的漏洞利用程序(我用这个程序来缓冲区溢出相同的函数,所以我知道它的好处)。现在,我对文件进行了对象转储以找到 .dtors_list 地址,我得到了 0x0804a20c,添加 4 个字节以得到 0x804a210。
接下来,我使用 gdb 查找在运行我的程序时我的 noops 开始的地址。使用这个我得到了 0xffbfdbb8。
到目前为止,我觉得我是对的,现在我知道我想使用格式字符串将 noop 地址复制到我的 .dtors_end 地址中。这是我想出的字符串(这是我作为用户输入提供给函数的字符串):
"\x10\xa2\x04\x08\x11\xa2\x04\x08\x12\xa2\x04\x08\x13\xa2\x04\x08%%.168u%%1$n%%.51u% %2$n%%.228u%%3$n%%.64u%%4$n"
这对我不起作用。程序运行正常,%s被我输入的字符串替换(减去前面的小端内存地址,由于某些原因,两个百分号现在变成了一个百分号)。
无论如何,我在这里有点难过,任何帮助将不胜感激。
最佳答案
免责声明:我不是专家。
您正在传递 "\x10\xa2\x04\x08\x11\xa2\x04\x08\x12\xa2\x04\x08\x13\xa2\x04\x08%%.168u%%1 $n%%.51u%%2$n%%.228u%%3$n%%.64u%%4$n"
作为 arg
的值?这意味着 buffer
将包含
"用法:\x20\x10\xa2\x04\x08\x11\xa2\x04\x08\x12\xa2\x04\x08\x13\xa2\x04\x08%.168u%1$n %.51u%2$n%.228u%3$n%.64u%4$n [选项]\x0aRandomly..."
现在让我们进一步假设您在 x86-32 目标上(如果您在 x86-64 上,这将不起作用),并且您正在使用不放置任何内容的优化级别进行编译在 print_usage
的栈帧中,除了 640 字节的 buffer
数组。
然后 printf(buffer)
将按顺序执行以下操作:
&buffer
。printf
..."Usage:\x20\x10\xa2\x04\x08\x11\xa2\x04\x08\x12\xa2\x04\x08\x13\xa2\x04\x08"
(23 个字节的序列)。%.168u
:将 printf
的下一个参数解释为 unsigned int 并将其打印在宽度为 168 的字段中。由于 printf
没有下一个参数,这实际上是打印堆栈上的下一个东西;即buffer
的前四个字节;即 “Usag”
(0x67617355
)。%1$n
:将 printf
的第二个参数解释为指向 int 的指针,并将 23+168 存储在该位置。这会将 0x000000bf
存储在位置 0x67617355
中。所以这是您的主要问题:您应该使用 %2$n
而不是 %1$n
并在 arg< 的前面添加一个垃圾字节
。 (顺便说一句,请注意 GNU 说 "If any of the formats has a specification for the parameter position all of them in the format string shall have one. Otherwise the behavior is undefined." 所以为了安全起见,你应该仔细检查并将 1$
添加到你所有的 %u
中。)%.51u
:打印另外 51 个字节的垃圾。%2$n
:将 printf
的第三个参数解释为指向 int 的指针,并将 0x000000f2
存储在该垃圾位置。如上,这应该是 %3$n
。所以,这里的主要错误是您忘记考虑 "Usage: "
前缀。
我假设您正在尝试将四个字节 0xffbfdbb8
存储到地址 0x804a210
中。假设你已经让它工作了。但是你的下一步是什么?如何让程序将 0x804a210
处的四字节数字视为函数指针并跳过它?
利用此代码的传统方法是利用 sprintf
中的缓冲区溢出,而不是利用 printf< 中更复杂的
。您只需要使 "%n"
漏洞arg
的长度大约为 640 个字符,并确保它对应于 print_usage
的返回地址的 4 个字节包含您的 NOP sled 的地址。
不过,即使是那个部分也很棘手。您可能会遇到与 ASLR 相关的问题:仅仅因为您的 sled 在一次运行中存在于地址 0xffbfdbb8
并不意味着它会在下一次运行中存在于同一地址。
这有帮助吗?
关于c - Format String 漏洞困扰,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10740308/
很难理解 ownerdraw TreeView ,这里是完整的故事: 一个 VS2013 WinForms 应用程序(在 Windows 8.1 上运行,如果重要的话启用了 TrueType ....
我有以下 JSON 数据,其中包含一个 nations 数组。数据 JSON 文件中的 Neighbouring 指示哪些国家与其他国家有邻居。国家的id指的是邻国的id。 即。俄罗斯与乌克兰相邻,波
有两个表,一个 Contact 表和一个 RelationshipHistory 表。 联系人可以具有多种类型的关系(业务、个人、志愿者等),这意味着随着时间的推移,他们可以在Relationship
我是一名优秀的程序员,十分优秀!