Pwnable.tw Babystack-Deathnote-Alivenote



babystack

Brute force

首先,程序通过/dev/urandom生成一个16byte的真随机数,并储存在mmaped的内存中一份,在stack上也备份一份

虽然我们有3种选择,但是必须首先登录:

在登陆过程中,使用strlen判断输入长度,之后作为strncmp的参数进行判断,这里存在漏洞。
如果read_input中输入"\x00",即可控制strncmp的n,从而逐个字节爆破出password。
并且,该login是可以任意成功的,只要我们输入的第一个字节是"\x00",即可顺利Bypass check,成功登陆

所以,首先通过加入"\x00"控制strlen长度,爆破得到password。
只有看到copy函数:

read_input的栈中未初始化,导致strcpy时候越界,并且在copy函数中栈恰好与login输入的栈重叠,虽然我们可以控制strcpy覆盖到retaddress,但是程序保护全开,无法ROP,我们必须泄露出libc地址

纵观整个程序没有可以泄露的函数,puts,printf都没有合适的参数,猜测libc应该也是brute 出来
恰好,观察栈中有几个libc地址

可以通过copy将libc地址strcpy&password位置,同brute force password一样,爆破出libc地址,从而计算出one_gadgets
注意: strcpy会自动在move的string后加入"\x00",所以该libc地址不能再strcpy的最后
同时注意bypass login从而使得flag==1

最终,爆破出libc后,直接ret到one_gadgets即可Getshell,在最后还需要在将password中更改为我们泄露出的psd,因为在最后memcmp

如果相等,可以绕过canary,直接返回。

由于题目需要爆破,需要的时间比较长,程序中限制alarm(1200u)20分钟
一开始的几次泄露太慢,耽误了时间,远程失败,于是下面的Script做了一点小优化

下面的Deathnote与Alivenote是几乎相同的题目,只有shellcode的要求不同

Deathnote

题目分为add,delete,show三种基本操作,逆向比较容易漏洞位于每一种操作中对index的判断

v1是个int型,却只判断了v1>10,从而存在符号溢出,当v1为负值时,note数组可越界读写

由于程序未开启NX,从而造成其stack-heap段可写可执行

进而我们只需要通过add 将写入shellcode的note写入GOT表的一个函数地址中即可劫持住控制流
但难点在于题目中对shellcode的限制,其中不但限制了shllcode的长度最多0x80,而且必须是printable

需要我们写出一个80bytes之内的Printable shellcode,网上的起shell的类似的shellcode一般长度都比80byte长,例如:

如果用msf或者pwntools生成也一般会超越长度,所以我们只能根据题目的特点自己单独写shellcode。
32bit 下可用的pirntable 指令可见Shellcode/Appendix/Alphanumeric opcode

我们需要执行int 80h来执行execve("/bin/sh"),但是int 80h不是可见字符

所以我们需要在shellcode中对其编码,这里使用指令xor [ebx+立即数],eax
更改GOT[‘free’]为shellcode,控制第一个参数为"/bin/sh"
shellcode与"/bin/sh"在同在heap地址,所以可以计算出需要解码的偏移offset
我写的shellcode比较直接,就是直接控制ebx=&(“/bin/sh”),通过push 0x7e,pop eax,inc eax一系列执行控制eax=0x80,通过偏移xor得到"\xcdx80",组成int 80h
接下来再控制eax=0xb,执行int 80h 即可起Shell。

Alivenote

逻辑同death_note,漏洞也是符号溢出
思路也是修改GOT表执行shellcode,但是对shellcode的限制条件不同:

可输入的shellcode 为Alphanumic shellcode 加上一个空格,并且限制了shellcode的长度仅仅是8个字节

首先,/bin/sh中无法直接写入,所以需要考虑利用IO,将shellcode read进入到相应的空间
并且每次的shellcode仅仅能够写入8个字节,需要利用jmp指令,构造类似ROP链的note-chain,执行我们的shellcode

  1. 利用"/bin/sh"的地址确定heap地址的偏移,方便jmp
  2. 之后构造Chain,使得eax=3,ebx=0,ecx=address,edx=size执行read(0,address,size)读入shellcode到heap空间
  3. shellcode前构造node slide雪橇,从而能够顺利执行shellcode

发表评论