当前位置:   article > 正文

CTFshow-pwn入门-前置基础pwn13-pwn19

CTFshow-pwn入门-前置基础pwn13-pwn19

pwn13

在这里插入图片描述
题目说编译运行这个flag.c文件即可获得flag。那我们先把flag.c文件下载下来,然后托到虚拟机里使用gcc编译一下,运行看看是否能够拿到flag。

gcc -o flag -flag.c
./flag
  • 1
  • 2

在这里插入图片描述
ok,果然拿到了flag。flag为:ctfshow{hOw_t0_us3_GCC?}。

pwn14

在这里插入图片描述
本题是让我们阅读flag.c文件的源码,给定key为"CTFshow",编译运行之后即可获得flag。其中呢,给定key为CTFshow是个啥子意思我们现在不是很清楚。那我们就先下载flag.c文件查看一下源码吧!

flag.c文件源码:

// flag.c
#include <stdio.h>
#include <stdlib.h>

#define BUFFER_SIZE 1024

int main() {
    FILE *fp;
    unsigned char buffer[BUFFER_SIZE];
    size_t n;
    fp = fopen("key", "rb");
    if (fp == NULL) {
        perror("Nothing here!");
        return -1;
    }
    char output[BUFFER_SIZE * 9 + 12]; 
    int offset = 0;
    offset += sprintf(output + offset, "ctfshow{");
    while ((n = fread(buffer, sizeof(unsigned char), BUFFER_SIZE, fp)) > 0) {
        for (size_t i = 0; i < n; i++) {
            for (int j = 7; j >= 0; j--) {
                offset += sprintf(output + offset, "%d", (buffer[i] >> j) & 1);
            }
            if (i != n - 1) {
                offset += sprintf(output + offset, "_");
            }
        }
        if (!feof(fp)) {
            offset += sprintf(output + offset, " ");
        }
    }
    offset += sprintf(output + offset, "}");
    printf("%s\n", output);
    fclose(fp);
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

代码的大致逻辑就是读取一个名为"key"的文件,然后根据该文件的内容通过一个while循环再嵌套两个for循环,具体的代码就不分析了,之后就可以输出flag了。

大家注意这个key文件是从我们本地读取的,所以我们在运行之前需要先手动创建一个key文件,根据题目的提示,key文件的内容应该为CTFshow。这样我们再编译运行flag.c文件就可以获得flag了。

echo CTFshow > key # 创建内容为CTFshow的key文件
gcc -o flag ./flag.c # 编译flag.c
./flag #运行flag文件那flag
  • 1
  • 2
  • 3

在这里插入图片描述

pwn15

在这里插入图片描述
本题目是让我们将flag.asm汇编代码编译成可执行文件再运行即可拿到flag。那我们就下载flag.asm文件编译运行呗。

nasm -f elf64 flag.asm # 将flag.asm编译成64为.o文件
ld -s -o flag flag.o # 将flag.o链接成flag可执行文件
./flag # 运行flag可执行文件拿到flag
  • 1
  • 2
  • 3

在这里插入图片描述

pwn16

在这里插入图片描述
本题是让我们使用gcc将flag.s文件编译成可执行文件。那我们就下载flag.s文件将其编译成可执行文件。

gcc -o flag flag.s # 将flag.s编译成flag可执行文件
./flag # 运行flag可执行文件拿到flag
  • 1
  • 2

在这里插入图片描述

pwn17

在这里插入图片描述
我们先将这个pwn文件拖进虚拟机,给它加上个可执行的权限。然后再使用checksec命令查看该文件的信息。

chmod +x pwn
checksec ./pwn
  • 1
  • 2

在这里插入图片描述
可以看到,pwn文件是一个64为的可执行文件,那我们直接拖进ida64反编译下看一看里边有什么东西。
反编译出的代码:

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int v4; // [rsp+4h] [rbp-1Ch] BYREF
  char dest[4]; // [rsp+Ah] [rbp-16h] BYREF
  char buf[10]; // [rsp+Eh] [rbp-12h] BYREF
  unsigned __int64 v7; // [rsp+18h] [rbp-8h]

  v7 = __readfsqword(0x28u);
  setvbuf(_bss_start, 0LL, 2, 0LL);
  setvbuf(stdin, 0LL, 1, 0LL);
  puts(asc_D48);
  puts(asc_DC0);
  puts(asc_E40);
  puts(asc_ED0);
  puts(asc_F60);
  puts(asc_FE8);
  puts(asc_1080);
  puts("    * *************************************                           ");
  puts(aClassifyCtfsho);
  puts("    * Type  : Linux_Security_Mechanisms                               ");
  puts("    * Site  : https://ctf.show/                                       ");
  puts("    * Hint  : You should understand the basic command usage of Linux! ");
  puts("    * *************************************                           ");
  *(_DWORD *)dest = 790655852;
  v4 = 0;
  puts("\nHow much do you know about Linux commands? \n");
  while ( 1 )
  {
    menu();
    v4 = 0;
    puts("\nEnter the command you want choose:(1.2.3.4 or 5)\n");
    __isoc99_scanf("%d", &v4);
    switch ( v4 )
    {
      case 1:
        system("id");
        break;
      case 2:
        puts("Which directory?('/','./' or the directiry you want?)");
        read(0, buf, 0xAuLL);
        strcat(dest, buf);
        system(dest);
        puts("Execution succeeded!");
        break;
      case 3:
        sleep(1u);
        puts("$cat /ctfshow_flag");
        sleep(1u);
        puts("ctfshow{");
        sleep(2u);
        puts("... ...");
        sleep(3u);
        puts("Your flag is ...");
        sleep(5u);
        puts("ctfshow{flag is not here!}");
        sleep(0x14u);
        puts("wtf?You haven't left yet?\nOk~ give you flag:\nflag is loading......");
        sleep(0x1BF52u);
        system("cat /ctfshow_flag");
        break;
      case 4:
        sleep(2u);
        puts("su: Authentication failure");
        break;
      case 5:
        puts("See you!");
        exit(-1);
      default:
        puts("command not found!");
        break;
    }
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73

我们先来分析一下代码的逻辑,首先是进入一个while循环打印出menu也就是菜单。然后是一个switch-case语句,根据我们输入的选项来执行分支语句。
我们分析源码看到case 3中有一个system(“cat /ctfshow_flag”)的语句,也就是可以读取flag的语句。但是!!!
我们来看!!!
在这里插入图片描述
这条sleep(0x1BF52u)语句是我们读取flag的障碍!因为这条语句它要睡眠0x1BF52秒啊,换算成10进制就是114514秒,那就是31个小时啊!!!这怎么等的了!
所以另求他法。
我们再看case 2:

case 2:
        puts("Which directory?('/','./' or the directiry you want?)");
        read(0, buf, 0xAuLL);
        strcat(dest, buf);
        system(dest);
        puts("Execution succeeded!");
        break;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

如果我们选择的case2,首先它是输出一行字符串,然后让我们输入一行长度为0xA的字符串buf,也就是长度为9的字符串。接着把我们输入的字符串buf赋给dest,然后使用system函数将dest作为参数传入进行命令执行。

选项2的功能总的来说就是,将我们输入的字符串当作参数传入system()函数!那我们就可以直接传入cat /ctfshow_flag吗?

那当然不行的,因为代码已经限制了我们输入字符串的长度为9,所以我们得换个命令想办法读取flag。我们知道system(“/bin/sh”);是可以获得Linux的交互式shell的,正好/bin/sh的长度也没有超过9,所以我们就可以传入/bin/sh来获取交互式shell,进而手动执行cat /ctfshow_flag来get flag了!

nc 连接,开干!!!
在这里插入图片描述
输入2 ->输入/bin/sh->执行cat /ctfshow_flag
在这里插入图片描述
OK,成功拿到flag!

pwn18

在这里插入图片描述
首先我们还是下载pwn文件拖进虚拟机加上可执行权限再使用checksec命令查看文件信息。

chmod +x pwn
checksec pwn
  • 1
  • 2

在这里插入图片描述
64位的文件,并且题目也提示我们要看源码,那我们就将pwn这个文件拉到ida64反编译下看看源码是什么。

源码:

// main
int __cdecl main(int argc, const char **argv, const char **envp)
{
  int v4; // [rsp+4h] [rbp-Ch] BYREF
  unsigned __int64 v5; // [rsp+8h] [rbp-8h]

  v5 = __readfsqword(0x28u);
  setvbuf(_bss_start, 0LL, 2, 0LL);
  setvbuf(stdin, 0LL, 1, 0LL);
  puts(s);
  puts(asc_B10);
  puts(asc_B90);
  puts(asc_C20);
  puts(asc_CB0);
  puts(asc_D38);
  puts(asc_DD0);
  puts("    * *************************************                           ");
  puts(aClassifyCtfsho);
  puts("    * Type  : Linux_Security_Mechanisms                               ");
  puts("    * Site  : https://ctf.show/                                       ");
  puts("    * Hint  : Do you know redirect output ?                           ");
  puts("    * *************************************                           ");
  puts("Which is the real flag?");
  __isoc99_scanf("%d", &v4);
  if ( v4 == 9 )
    fake();
  else
    real();
  system("cat /ctfshow_flag");
  return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
// fake
int fake()
{
  return system("echo 'flag is here'>>/ctfshow_flag");
}
  • 1
  • 2
  • 3
  • 4
  • 5
// real
int real()
{
  return system("echo 'flag is here'>/ctfshow_flag");
}
  • 1
  • 2
  • 3
  • 4
  • 5

我们先来分析一下代码逻辑,大概流程就是需要我们输入一个值v4,看这个值v4是否等于9,如果等于9就执行fake()函数,然后再执行system函数打印出flag;如果不等于9就先执行real()函数,然后再执行system函数打印出flag。

查看源码我们可以发现啊,real()函数的内容是将"flag is here"这条字符串追加(echo >> 两个>表示追加)到ctfshow_flag文件里,而fake()函数是将"flag is here"这条字符串覆盖(echo > 一个>表示覆盖)ctfshow_flag的文件内容,这就代表如果我们输入的v4等于9的话,system函数最后输出flag的时候,屁股后面一定会有flag is here这条字符串,之后我们再把这条字符串从输出的flag删掉就是真正的flag了!而如果我们输入的不是9,system()函数就会将flag is here函数覆盖ctfshow_flag文件的内容,这样我们的flag就没了呀,所以我们nc连接之后输入9就行了!

nc连接,开干!!!
在这里插入图片描述
OK,成功拿到flag!

pwn19

在这里插入图片描述
OK,我们还是先下载pwn文件托到虚拟机里加上可执行权限再使用checksec命令查看文件信息。

chmod +x pwn
checksec pwn
  • 1
  • 2

在这里插入图片描述
pwn文件依旧是64位的,直接拖进ida64看一下源码。

// main
int __cdecl main(int argc, const char **argv, const char **envp)
{
  char buf[40]; // [rsp+10h] [rbp-30h] BYREF
  unsigned __int64 v5; // [rsp+38h] [rbp-8h]

  v5 = __readfsqword(0x28u);
  setvbuf(_bss_start, 0LL, 2, 0LL);
  setvbuf(stdin, 0LL, 1, 0LL);
  puts(s);
  puts(asc_BF0);
  puts(asc_C70);
  puts(asc_D00);
  puts(asc_D90);
  puts(asc_E18);
  puts(asc_EB0);
  puts("    * *************************************                           ");
  puts(aClassifyCtfsho);
  puts("    * Type  : Linux_Security_Mechanisms                               ");
  puts("    * Site  : https://ctf.show/                                       ");
  puts("    * Hint  : Turn off output, how to get flag? ");
  puts("    * *************************************                           ");
  if ( fork() )
  {
    wait(0LL);
    sleep(3u);
    printf("flag is not here!");
  }
  else
  {
    puts("give you a shell! now you need to get flag!");
    fclose(_bss_start);
    read(0, buf, 0x20uLL);
    system(buf);
  }
  return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
// fork
// attributes: thunk
__pid_t fork(void)
{
  return fork();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

这道题目前还没有想出来办法解决,因为它把输出流给关掉了,也就是我们执行命令得不到回显了,而且ping命令也没有也不能用dns带外,nc命令也没有,也不能反弹到外网服务器!哎,。。。。我再想想办法~ _ ~


// 2023/06/21 更新
根据评论区里师傅的意见,关闭了输出流,我们nc连接之后可以使用 >&0定向到输入流,我们就来尝试一下。

首先我们先来看一下所在路径:

pwd >&0
  • 1

在这里插入图片描述
可以看到我们输入命令之后,给我们返回了/,代表我们所处根路径。

我们再重新nc连接(因为这个程序给我们执行命令的环境不是交互式的,所以我们需要再次nc连接执行命令),使用ls >&0查看根目录。

ls >&0
  • 1

在这里插入图片描述
OK,我们发现了flag,再使用cat ctfshow_flag >&0进行读取即可。

cat ctfshow_flag >&0
  • 1

在这里插入图片描述
好的这样我们就拿到了本题的flag。

这里呢,希望大家,在学习的过程中啊,也可以多多尝试记录自己学习的过程,分享自己的理解,有不会的知识点也可以写在上面和志同道合的师傅们一起交流学习,就像这道题目pwn19,刚一开始不会解,然后就有一位热心的师傅在评论区回复帮助,真的很感谢师傅的帮助。所以大家还是跟其他人多多交流心得体会,这样我们的能力就会得到很大的提高。另外,感谢大家的支持与帮助,希望在pwn的学习之路,我们可以一起前行!!!^_^

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号