IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 【pwnable.kr】Toddler‘s Bottle-[random] -> 正文阅读

[C++知识库]【pwnable.kr】Toddler‘s Bottle-[random]


Target & Download


image-20211207123744058

Daddy, teach me how to use random value in programming!

ssh random@pwnable.kr -p2222 (pw:guest)

scp 下载文件

scp -P 2222 -p random@pwnable.kr:/home/random/* ./


Analysis & IDA


random.c

#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;
}

满足 (key ^ random) == 0xdeadbeef 即可

在 rand 被调用之前,srand 函数要先被调用,并且 srand 在整个程序中仅被调用一次。

这里并没有调用srand 这样其实每次运行rand 结果是不变的。

每次运行都会用同一个种子生成随机序列,那么每次程序运行得到的数就是一样的。tips

IDA pseudocode

.text:00000000004005F4 ; __unwind {
.text:00000000004005F4                 push    rbp
.text:00000000004005F5                 mov     rbp, rsp
.text:00000000004005F8                 sub     rsp, 10h
.text:00000000004005FC                 mov     eax, 0
.text:0000000000400601                 call    _rand
.text:0000000000400606                 mov     [rbp+var_4], eax
.text:0000000000400609                 mov     [rbp+var_8], 0
.text:0000000000400610                 mov     eax, offset unk_400760
.text:0000000000400615                 lea     rdx, [rbp+var_8]
.text:0000000000400619                 mov     rsi, rdx
.text:000000000040061C                 mov     rdi, rax
.text:000000000040061F                 mov     eax, 0
.text:0000000000400624                 call    ___isoc99_scanf
.text:0000000000400629                 mov     eax, [rbp+var_8]
.text:000000000040062C                 xor     eax, [rbp+var_4]
.text:000000000040062F                 cmp     eax, 0DEADBEEFh
.text:0000000000400634                 jnz     short loc_400656
.text:0000000000400636                 mov     edi, offset s   ; "Good!"
.text:000000000040063B                 call    _puts
.text:0000000000400640                 mov     edi, offset command ; "/bin/cat flag"
.text:0000000000400645                 mov     eax, 0
.text:000000000040064A                 call    _system
.text:000000000040064F                 mov     eax, 0
.text:0000000000400654                 jmp     short locret_400665
.text:0000000000400656 ; ---------------------------------------------------------------------------
.text:0000000000400656

Debug & writeup


ELF 文件,使用gdb debug

.text:0000000000400601                 call    _rand
.text:0000000000400606                 mov     [rbp+var_4], eax
.text:0000000000400609                 mov     [rbp+var_8], 0

执行到0x400609的时候已经获取到_rand 生成的伪随机数了。

在此处打断点,查看rbp+4h的数据,即可获得

使用pwndbg

hispark@ubuntu:~/code/pwndbg$ gdb gdb/random 
Reading symbols from gdb/random...(no debugging symbols found)...done.
pwndbg> b *0x400609
Breakpoint 1 at 0x400609
pwndbg> rub
Undefined command: "rub".  Try "help".
pwndbg> run
Starting program: /home/hispark/code/pwndbg/gdb/random 

Breakpoint 1, 0x0000000000400609 in main ()
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
─────────────────────────────────[ REGISTERS ]──────────────────────────────────
 RAX  0x6b8b4567
 RBX  0x0
 RCX  0x7ffff7dcd1c8 (randtbl+8) ?— 0x6774a4cd16a5bce3
 RDX  0x0
 RDI  0x7ffff7dcd740 (unsafe_state) —? 0x7ffff7dcd1d4 (randtbl+20) ?— 0x61048c054e508aaa
 RSI  0x7fffffffdd14 ?— 0x94e50d006b8b4567
 R8   0x7ffff7dcd1d4 (randtbl+20) ?— 0x61048c054e508aaa
 R9   0x7ffff7dcd240 (pa_next_type) ?— 0x8
 R10  0x3
 R11  0x7ffff7a264c0 (rand) ?— sub    rsp, 8
 R12  0x400510 (_start) ?— xor    ebp, ebp
 R13  0x7fffffffde30 ?— 0x1
 R14  0x0
 R15  0x0
 RBP  0x7fffffffdd50 —? 0x400670 (__libc_csu_init) ?— mov    qword ptr [rsp - 0x28], rbp
 RSP  0x7fffffffdd40 —? 0x7fffffffde30 ?— 0x1
 RIP  0x400609 (main+21) ?— mov    dword ptr [rbp - 8], 0
───────────────────────────────────[ DISASM ]───────────────────────────────────
 ? 0x400609 <main+21>    mov    dword ptr [rbp - 8], 0
   0x400610 <main+28>    mov    eax, 0x400760
   0x400615 <main+33>    lea    rdx, [rbp - 8]
   0x400619 <main+37>    mov    rsi, rdx
   0x40061c <main+40>    mov    rdi, rax
   0x40061f <main+43>    mov    eax, 0
   0x400624 <main+48>    call   __isoc99_scanf@plt                      <__isoc99_scanf@plt>
 
   0x400629 <main+53>    mov    eax, dword ptr [rbp - 8]
   0x40062c <main+56>    xor    eax, dword ptr [rbp - 4]
   0x40062f <main+59>    cmp    eax, 0xdeadbeef
   0x400634 <main+64>    jne    main+98                      <main+98>
───────────────────────────────────[ STACK ]────────────────────────────────────
00:0000│ rsp 0x7fffffffdd40 —? 0x7fffffffde30 ?— 0x1
01:0008│     0x7fffffffdd48 ?— 0x6b8b456700000000
02:0010│ rbp 0x7fffffffdd50 —? 0x400670 (__libc_csu_init) ?— mov    qword ptr [rsp - 0x28], rbp
03:0018│     0x7fffffffdd58 —? 0x7ffff7a03bf7 (__libc_start_main+231) ?— mov    edi, eax
04:0020│     0x7fffffffdd60 ?— 0x1
05:0028│     0x7fffffffdd68 —? 0x7fffffffde38 —? 0x7fffffffe1d7 ?— '/home/hispark/code/pwndbg/gdb/random'
06:0030│     0x7fffffffdd70 ?— 0x100008000
07:0038│     0x7fffffffdd78 —? 0x4005f4 (main) ?— push   rbp
─────────────────────────────────[ BACKTRACE ]──────────────────────────────────
 ? f 0         0x400609 main+21
   f 1   0x7ffff7a03bf7 __libc_start_main+231
   f 2         0x400539 _start+41
────────────────────────────────────────────────────────────────────────────────
pwndbg> 

image-20211207193540278

rbp+4h 即 01:0008 0x6b8b456700000000 则random为 0x6b8b4567

hispark@ubuntu:~/code/pwndbg$ python
Python 2.7.17 (default, Feb 27 2021, 15:10:58) 
[GCC 7.5.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> random = 0x6b8b4567
>>> res = 0xdeadbeef
>>> key = res ^ ramdom
>>> key = res ^ random
>>> print(key)
3039230856
>>> 

利用异或的运算即可获得最终值3039230856

random@pwnable:~$ ./random
3039230856
Good!
Mommy, I thought libc random is unpredictable...
random@pwnable:~$

TIPS


int rand(void);
int rand_r(unsigned int *seedp);
void srand(unsigned int seed);
  • 在rand函数的内部,是通过一个公式计算出一个值作为随机值,下次再调用rand的时候,再把这个随机值作为参数传给这个公式计算出一个新的随机值,周而复始。
  • 在C库中,是通过一个静态全局变量来作为“种子”,而这个“种子”的值是通过srand函数改变的,如果不写srand函数,这个“种子”值默认赋值为1。
  • 程序只要重新开始运行,“种子”值就会被默认赋值为1,那么通过公式算出来的序列肯定就一直相同了。
  • 目前流传较广的意见是rand_r函数是线程安全的。

参考:

https://blog.csdn.net/lvyibin890/article/details/80141412

https://blog.csdn.net/w_y_x_y/article/details/80199694

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-12-08 13:38:17  更:2021-12-08 13:40:26 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 12:03:53-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码