根据上面的描述,我们应该在参数和保存的EIP中间放置一个执行完的返回地址。鉴于我们调用scanf读取字符串后还要调用system函数,我们让__isoc99_scanf执行完后再次返回到main函数开头,以便于再执行一次栈溢出。改良后的ROP链如下: 我们再次进行调试,发现这回成功调用__isoc99_scanf把”/bin/sh”字符串读取到地址0x0804a03...
v5 = 0LL; while ( (_DWORD)kl ) { puts("i am bad boy "); __isoc99_scanf("%ld", &v4); write(1, (char *)buf + v4, (unsigned int)kl); LODWORD(kl) = kl - 3; } 首先这一段设计的非常巧妙,kl的值是6,说明while循环可以执行两次,第一次只能泄露出6字节的值,第二次可以泄露3字节...
puts("Give me your choice: "); __isoc99_scanf("%d", &v3); if ( v3 != 4 ) break; Bye(); } if ( v3 <= 4 ) { switch ( v3 ) { case 3: Choice((__int64)s); break; case 1: sandbox(); break; case 2: Read((__int64)s); break; } } } } Read函数看一看,是向栈上...
根据上面的描述,我们应该在参数和保存的EIP中间放置一个执行完的返回地址。鉴于我们调用scanf读取字符串后还要调用system函数,我们让__isoc99_scanf执行完后再次返回到main函数开头,以便于再执行一次栈溢出。改良后的ROP链如下: from pwn import * context.update(arch = 'i386', os = 'linux', timeout = 1) i...
(void*)0x20240000,0x1000uLL,7,33,-1,0LL);if(v5==(void(*)(void))-1LL){perror("mmap");exit(1);}printf("input the length of your shellcode:");__isoc99_scanf("%2d",&v4);if((int)v4<=10){printf("input your shellcode:");myread(v5,v4);}else{puts("too long");}v5();...
接着我们使用pwntools的功能获取到__isoc99_scanf在PLT表中的地址,PLT表中有一段stub代码,将EIP劫持到某个函数的PLT表项中我们可以直接调用该函数。我们知道,对于x86的应用程序来说,其参数从右往左入栈。因此,现在我们就可以构建出一个ROP链。 `from pwn import * context.update(arch = 'i386', os = 'linu...
Arch: amd64-64-little RELRO: No RELRO Stack: Canary found NX: NX enabled PIE: No PIE (0x400000) 这里其实已经给出提示了,没有Relocation Read-Only,没有PIE,说明可以去修改got表项,当时咋就没想到呢hhhh 程序运行信息: *** Select an option *** List appointments...
8048520: e8 bb fe ff ff call 80483e0 <__isoc99_scanf@plt> 8048525: 83 c4 10 add $0x10,%esp 1. 2. 3. 4. 5. 6. 7. 8. 9. 我们可以看到p在flag下面四个偏移,a又在p下面四个偏移,用缓冲区溢出是不可能了。下面有个printf,也许可以利用字符串格式化漏洞。
漏洞在change_numbers中,未对index做边界检查,可实现任意地址写: if(option!=3)break;puts("which number to change:");uVar1=(ulonglong)dVar2&0xffffffff00000000;__isoc99_scanf(&DAT_08048a97,&num_num,(int)((ulonglong)dVar2>>0x20));puts("new number:");dVar2=(double)(uVar1&0xffffffff0000...
_isoc99_scanf("%u", &v1); printf("%#x\n", *v1); return *MK_FP(__GS__, 20) ^ v2; } 这个函数可以打印任意地址的内存数据。 void __noreturn leave() { signed int i; // [sp+8h] [bp-B0h]@1 char s[160]; // [sp+Ch] [bp-ACh]@1 ...