avatar

如果从Windows入门Pwn-1

强行进windows_pwn-1

前言

学校开了门<软件安全技术>,教材挺新的。但是学校没讲过汇编、堆栈就直接上,可以劝退大多数同学了。对我来说顺便入门Windows_Pwn,基本上有作业/调试任务都会写一篇,同时也会写的详细一些(尽管可能写的很弱智),方便周围不懂的同学看看

源代码与编译

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void attack()
{
printf("Hacked.\n");
}

void vuln()
{
char password[6] = "ABCDE";
char str[6];
FILE *fp;
if(!(fp=fopen("password.txt","r")))
exit(0);
fscanf(fp,"%s",str);

str[5]='\0';
if(strcmp(str,password)==0)
// fprintf(stderr,"OK.\n");
printf("OK.\n");
else
// fprintf(stderr,"NO.\n");
printf("NO.\n");
}

int main()
{
vuln();
return 0;
}

编译

gcc -fno-stack-protector -o passwd passwd.c

程序有两个函数,一个是后门函数 attack ,一个是检查密码的函数 vuln

如果文件里面的内容是"ABCDE"的话就成功。

但是,程序使用数组来存放文件里面读取的数据,如果我们构造 password.txt 里面的内容,就会导致栈溢出。

检查与崩溃

查壳

whkbSx.png

没有壳,而且看出是使用MinGw32编译的

运行

whkql6.png

功能被实现

crash(报错)

whkgS0.png

当我们改变文档的内容时,我这边先卡一下,然后程序异常退出

反汇编

IDA静态分析

whkWOU.png

找到了函数的地址,其中

函数名 地址
attack 0x04016B0
vuln 0x04016C4
main 0x0401750

各个寄存器功能能大致如下~~(更基础的可能会另外更一篇)

whkL6K.jpg

那么我们需要的就是控制 eip 寄存器(程序是32位的),也是汇编里面的ret,控制了他就可以劫持程序流了

x32dbg动态调试

u1s1,这个有经验的话只靠静态分析都可以出

我们的文件内容是

AAAAAAAAAAAAA

我们现在 main 函数(也就是 0x0401750 的地址)下个断点

但是x32dbg已经帮我们调好了几个断点

whk7f1.png

  • 等到运行 fscanf 到读取到文件后,等到返回的时候栈上的情况如下

whk5TJ.png

我们得到输入的栈地址 0x61FEB00x61FEB0的这个数个指针,指向我们的 0x61FEB0 ,因为它的值就是这么多。41是十六进制数,0x41在ASCII上就是’A’,所以 0x61FEB0 就是程序读取文件内容的位置

  • 继续单步,等到程序 ret

whkTYR.png

左边红框:程序运行时的汇编代码,显示已经到了ret,但是还没有执行操作

右上方的EIP寄存器:再单步进行发现 EIP 寄存器的值是 00401760,再从静态分析中可以看出这个位置是 printf("No.")的汇编代码,所以程序会跳转到这里

右下方红框:0x61FECC 地址的值就是 EIP 的值,也就是我们下一步要跳转的地方

  • 修改 0x61FECC 的值

我们把它的值改为 04016B0 ,也就是attack的地址,在重新运行一次

whkRyT.png

我们的程序运行到了一个根本没有运行过的函数

攻击思路A

输入的栈在 0x61FEB0 ,返回时的栈在 0x61FECC ,两者相差 0x1c 字节的空间,而且输入的栈 0x61FEB0 存在一个栈溢出,从而可以使我们可以覆盖掉 EIP ,从而实现任意地址跳转,这里就可以把他改到后门函数 0x04016B0

但是调试的时候会发现32位的程序为了每个栈的大小为4字节,那么就多分配了字节

攻击-生成payload

注意,程序是小端序,就是说地址要倒着写

是读取文件的栈溢出,那么要构造一个文件,根据上面的攻击思路得到payload,payload如下

whkok9.png

黑色框住的是填充的无意义字节,橙色框柱的是要覆盖的值,因为是小端序,所以要倒着写

运行

whk6Wq.png

程序运行完attack后会卡顿一下,因为该函数没有返回值,同时我们可以构造更复杂的payload来达到弹出shell或者其他程序的目的

补充

windows上的栈溢出很常见如

CVE-2019-9766

易语言5.11缓冲区溢出漏洞

上面说的不用动态调试也可以是怎么做的呢?

  • IDA f5 可以查看伪代码

    whkhmF.png

    这里就直接可以看出有个栈溢出漏洞

    v1 距离 ebp 0x18大小,在栈上

    whk4w4.png

同时为了覆盖 EBP 寄存器我们要多输入4字节字符(64位8字节 32位4字节)才能覆盖到 EIP 的地址,那么就需要填充 0x18+4=0x1c 个字符串来覆盖

这样的话不需要动态调试都可以直接得到payload

Author: Joe1sn
Link: http://blog.joe1sn.top/2020/Winpwn(%E7%AE%80%E5%8D%95)-1/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
Donate
  • 微信
    微信