ISG-2018 管理运维赛writeup

命令注入  
 

得到 flag: ISG{522b28987a79534f8a38b25ebcc474fb}

news

SQL 注入,关键字大小写绕过,空格用注释符绕过

http://202.120.7.206:60019/news-111111/**/union/**/sElect/**/1,flag/**/from/**/f

lag.html

表名:

得到 flag: ISG{7a78683a929dbc6bd8e5e96f0c185b16}

secret

在 chrome 浏览器中打开 view-source:http://202.120.7.207:60007/

ZmxhZzpJU0d7SDNJSU9fMXNHX2pzX1RyNHB9做 base64解码得到

flag:ISG{H3IIO_1sG_js_Tr4p}

junkcode

给了一个 32 位的 ELF,运行后需要提供输入 flag,并返回是否正确。在 IDA 中打开,

发现 main 函数的代码比较混乱,应该是运行时解密的。

所以用 gdb 调试,通过 disass main 查看运行时 main 函数的指令:从名称也可以猜

到,0x080485d4 处调用的 check 应该就是输入的检查函数。而静态看到的 check 函

数也是被加密过的。又从函数符号表中看到一个 xor,于是猜想是 xor 加密。

对比 IDA 中和调试器中 check 函数的指令,尝试发现确实是用 34 做 key 进行的 xor

加密。于是在 IDA 中把 check 函数的真实指令还原:

然后就可以 F5 看反编译代码了,逻辑也比较清晰,就是需要把两段 buf 做 xor:

要还原的话,直接把这两段内容做 xor 即可

stackoverflow

给了一个 64 位 ELF,从名称和 main 函数的内容可知,存在一个栈溢出,但是程序有

canary 保护。

然而,程序设置了 SIGABRT 的 handler,即检测到栈溢出后会调用这个 handler。而在

handler 中读取用户是否继续时,又存在一次溢出:

这处溢出,可以修改 v1 的内容。而 v1 最后可以作为 execve 要执行的命令路径。所

以只需要通过这个溢出,将 v1 的内容修改为/bin/sh,即可执行命令  

babyrsa

提供了一个.py 脚本。阅读代码,发现 flag 内容会生成随机的 padding,最后一个

bytes 由用户提供,返回 RSA 加密的密文。用户可以提供 3 次,但每次的 padding 都

是重新随机生成的。

反复阅读代码,发现最后有个坑:每轮清空尾部的 padding 重新生成时,那条语句单

独放在了最后,没有放到 try-catch 块中,他默认 try-catch 里不会发生异常。而 int()转

换用户输入时,是可以发生异常的

所以,一旦在读入用户输入时发生异常,那么在清空 flag 尾部的 padding 时,按照

bits/8 算就会少清空一个 byte。而这次异常的输入又不会记入 3 次之内。如此这般,

就可以将 flag 的内容逐渐加长,需要 padding 的逐渐减少。最终可以使得 flag 长度正

好不需要随机 padding。

又因为 n 的总长度是限制,flag 最大不超过 256 bytes,所以只需要连续输入 256 次字

母内容,这样就可以确保接下来不会有随机 padding 的影响了:

接下来,用户只需要提供 3 个不同的末尾 bytes 即可。根据 RSA 的计算方式,最后相

当于求解同余意义下的三元线性方程组。为了便于计算,3 个末尾 bytes 分别取 0, 1,  2:

对应的方程组是

x^3 = r1 mod n

(256x+1)^3 = r2 mod n

(256x+2)^3 = r3 mod n

x 是带有 padding 的 flag;r1, r2, r3 是末尾为 0, 1, 2 所得到的密文。直接求解方程

组,得到 x mod n。其后面是 padding,只需要保留前面的 bytes 即为 flag

babynote
 

分析程序发现:1、在deletenote时未将ptr中对应地址置NULL;2、editnote时,直接将新的内容保存到原来的内存中,且未check大小;

所以,应该存在double free、UAF、heap-overflow三类漏洞;

这里,我们利用heap-overflow来实现利用;

总体思路是:利用heap-overflow来达到任意地址写,然后将free_hook中写入system()的地址;那么deletenote时,note_content=’/bin/sh’即可拿到shell;free_hook和system的地址需要libc的基地址+偏移来算,基地址的泄漏见后文;

1、add两个noteA,noteB,内存分布上,noteB所在的chunkB在chunkA之后;

2、然后,编辑noteA,在noteA中伪造一个空闲块fakechunkA:

fakechunkA.size=chunkA.size-0x10;利用editnote的溢出,来修改chunkB的pre_size和pre_inuse;在delete noteB时会unlink fakechunkA;

如何绕过unlink中(p->fd->bk==p&&p->bk->fd==p)的检查?

由于(&ptr+index_A)中保存了noteA的地址,也就是fakechunkA的块首地址;让fakechunkA的fd=(&ptr+index_A)-0x18,bk=(&ptr+index_A)-0x10即可绕过;

之后,(&ptr+index_A)中保存的就是(&ptr+index_A)-0x18;

3、这时,编辑noteA,content=’a’*0x18+p64(address);这样(&ptr+index_A)中保存了address;edit noteA我们达到了任意地址写;当然,这里让address=free_hook;

4、再次编辑noteA,content=p64(system);free_hook里写入了system的地址;

5、最后deletenote时,note_content=’/bin/sh’;

6、为了泄漏libc的基地址:

先add noteX,noteY;delete noteX后,chunkX会链入unsorted bin;chunkX.fd中保存了unsortedbin的地址;main_arena地址=unsortedbin地址-0x58;

此外这道题中,main_arena在libc中的偏移是0x0x3c4b20;这样可算出libc的基地址;

7、我们注意到&ptr=0x6020c0;而在editnote时用scanf来读入数据,遇到空格0x20会截断,所以在noteA前面要多次addnote,让(&ptr+index_A)不包含0x20;

本文由 Galaxy Lab 作者:GalaxyLab 发表,其版权均为 Galaxy Lab 所有,文章内容系作者个人观点,不代表 Galaxy Lab 对观点赞同或支持。如需转载,请注明文章来源。
5

抱歉,评论已关闭!