首页
社区
课程
招聘
[分享]pwnable.kr random day5
2021-1-6 14:39 7781

[分享]pwnable.kr random day5

2021-1-6 14:39
7781

题目

解题过程

1. 查看文件列表


flag 只对创建者 random_pwn 和 root 可读,而我们登录的用户是 random,无读权限。random 对random_pwn 和 random 开放读和执行权限,而且权限里面有 s,因此 random 用户在执行这个文件时会被赋予 root 权限。

2. 查看 random.c 文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
 
int main(){
        unsigned int random;
        random = rand();        // random value!
 
        unsigned int key=0;
        scanf("%d", &key);
 
        if( (key ^ random) == 0xdeadbeef ){
                printf("Good!\n");
                system("/bin/cat flag");
                return 0;
        }
 
        printf("Wrong, maybe you should try 2^32 cases.\n");
        return 0;
}

我们的目标是执行 system("/bin/cat flag"),需满足 key ^ random == 0xdeadbeef
key 的值手动输入,我们可控
random 的值是由 rand() 产生,rand() 产生的随机数在每次运行的时候都是与上一次相同的。若要不同, 用函数 srand() 初始化它。此处没有使用 srand() 所以我们可以先执行一次程序查看 random 的值。

3. GDB 调试 random

  1. disassaemble main查看 main 函数的汇编代码

    与源码对照得知,random 的地址是 %rbp - 0x4,key 的地址是 %rbp - 0x8 我们这次只用到了 random 的地址
  2. 下断点,查看 random 值
    0x400606 处完成了对 random 的赋值,在其后面找一地址下断点,执行后查看 random 的值。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    b *0x0000000000400610
    x/10x $rbp-4       
    # 第一个 x 是 examine 的简写,用于查看内存地址的值。
    # 用法:x/<n/f/u> <addr> 
    # n,f,u 都是可选参数
    # n是一个正整数,表示需要显示的内存单元的个数,一个内存单元的大小由后面的u定义
    # f 表示显示的格式
    #        x 按十六进制格式显示变量。
    #        d 按十进制格式显示变量。
    #        u 按十六进制格式显示无符号整型。
    #        o 按八进制格式显示变量。
    #        t 按二进制格式显示变量。
    #        a 按十六进制格式显示变量。
    #        c 按字符格式显示变量。
    #        s 按字符串格式显示变量。
    #        f 按浮点数格式显示变量。
    # u 表示从当前地址往后请求的字节数,GDB 默认是 4 个 bytes。
    #         b 表示单字节。
    #         h 表示双字节。
    #         w 表示四字节。
    #         g 表示八字节。
    # 当我们指定了字节长度后,GDB会从指内存定的内存地址开始,读写指定字节,并把其当作一个值取出来。
    # <addr>表示一个内存地址,也可以用寄存器(偏移)表示地址,如此次用的是 $rbp-4

    读得 random 的值为 0x6b8b4567
  3. 计算 key 的值
    由 key ^ random == 0xdeadbeef 得 0xdeadbeef ^ random == key
    利用 python 求得 key 的值 print 0x6b8b4567^0xdeadbeef

    4. 输入 key 值,获得 flag

    因为 scanf() 要求格式为 %d,所以我们应输入十进制
    红框内为 flag

    参考链接

  • https://www.runoob.com/w3cnote/cpp-rand-srand.html
  • https://blog.csdn.net/allenlinrui/article/details/5964046

[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。

最后于 2021-1-6 14:44 被cease2e编辑 ,原因: 忘记加参考链接
收藏
点赞2
打赏
分享
最新回复 (1)
雪    币: 39
活跃值: (3593)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
cease2e 2021-1-6 14:42
2
0
参考链接
https://www.runoob.com/w3cnote/cpp-rand-srand.html
https://blog.csdn.net/allenlinrui/article/details/5964046
游客
登录 | 注册 方可回帖
返回