2021浙江省赛pwn2复盘
这题在比赛是没有做出来的,属于赛后复盘,但是感觉这题不该在比赛做不出来,因为赛后花了两小时就出了。
静态分析首先checksec发现保护全开了,ida打开,主函数是一个while 1 循环且没有return,如果要栈溢出得在其它函数。首先ida分析有部分不到位,有一个很明显的值赋值指针,然后后面还有对指针之后的元素读取一个int型变量,很明显栈布局是这样的。
1234char buf[]char *ptrint size
然后我们去混淆一下,去除那个指针刚好是31个int_64,把它改变一下就是char buf[248],如下更方便分析(isnan函数是因为去除了alarm方便调试)
可以很明显的看到中间有两层检测,但是一旦不满足最外层那个检测那么就会循环输出too easy,因此我们看看这个判断是什么,这个判断的意思就是我们的指针只有在>=缓冲区地址或者<=rbp-0x220才允许执行下面的流程。因为栈是向低地址增长,所以第一个判断就是ptr要落在buf或者buf下面(栈底方向)。如果我们有机会修改ptr,那确实可以通过ptr任意写,而我们之前 ...
wdb2018_guess writeup
buu刷题记录:wdb2018_guess
静态分析elf文件checksec一下发现开了NX和canary保护,64位程序,用ida分析看看
很明显的gets栈溢出,并且gets之后没有回显输入的内容,那这样的话意味着不能栈溢出劫持控制流了。那么看看前面,发现有一个把flag文件内容读到栈上面的动作。后面while循环调用了一个sub_400A11函数,v7=3,v6=0,,v7>=v6 break就意味着这个函数会被调用三次。而发现sub_400A11函数是调用fork函数,fork函数会创建和当前进程一模一样的进程,然后范围自身进程的ID,如果是被创建的进程,那么fork将会返回0。
简单点就是fork的子进程会返回0,如果返回0那么break执行下面的内容,父进程因为返回自己进程号不会break则继续循环,然后调用fork,也就是说这个进程一共会产生3个子进程执行while循环之后的内容。
这里有一个特性,那就是在发生栈溢出之后stack_chk_fail。在终止程序之前还会打印argv[0],这一点很合理。但是这里可以用于泄露栈上的fl ...
网鼎杯2020青龙组singal writeup
不知不觉做到了虚拟机逆向了,曾经我也只是听说,还未曾想也能自己做出。
静态分析文件exe文件,先查壳,没有壳直接ida打开。
main函数逻辑还是比较简单的,先拷贝一串内存给v4,v4再作为第一个参数给vm_operad函数,第二个参数是114。
那么我们先提取它拷贝的内存,至于这段内存如何使用那就进去分析vm_operad函数了。很明显,这个第一个参数是int*类型的,并且也没有对a1做强制转换之类的关系,那么很明显这个内存是一个int数组,那么用提取成char数组之后再用int *类型去输出它就能得到对应的int数组。
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667#include<stdio.h>#include<bits/stdc++.h>unsigned char s[] ={ 0x0A, 0x00, 0x00, 0x00, 0x04 ...
WUSTCTF2020 level4 writeup
好久没刷re了,来刷点re啊。
buuctf的[WUSTCTF2020]level4
静态分析文件下载发现是一个64位的elf文件,IDA打开分析。照例先看看明显的字符串明文,发现有left,right,然后还有三种打印(type1,type2,type3)。观察符号列表发现有type1和type2函数。跟进去发现跟我们二叉树的递归输出十分相似,并且type1 先递归了a1+1再递归a1+2,差不多他们就是左子树和右子树。那么type1就是一个后根遍历。然后type2是再中间输出的,是一个中根遍历,那么type3大概率就应该是先根遍历,这里他没有,那么先根遍历大概率就是flag。根据中序遍历和其它一个遍历可以求另外一个遍历,这个在数据结构课里有讲。
动态调试那么先运行一遍可以发现得到了两个结果
正解显然就是考一个数据结构嘛,但是一个题目总得有多种解法,这里我选择修改函数结构,让它从一个后序遍历变成先序遍历,这里需要patch elf我们先找到type2函数观察它的汇编代码
很明显
1jz short loc_4007FD
这一条指令对应了if (*a1)的跳转,那么 ...
ciscn2019_final_3 writeup
buu刷题记录:ciscn_final_3
写在前面今天解决了C++文件换版本的问题,也是一刻没耽误直接做了这道C++题目,不得不说太爽了啊,再也不用因为题目是C++写的就做不了了,话不多说来看文件。
静态分析elf文件题目告知是ubuntu18版本的,给了libc.so.6文件,但是盲猜跟它自己的一样,那就先换好elf文件的版本。checksec观察保护全开。然后IDA打开一看,发现是经典的堆菜单题,提供了两种操作,add和delete。delete很明显free之后指针没有清零,存在UAF漏洞,并且add只允许下标开到0x18,也就是0~24总共能add 25次。然后大小限制在了fastbin大小的范围内,但是很贴心地,每次add之后给了malloc之后的地址。那么大概率通过这里泄露(ps:一开始并没有想到,还想着用IO泄露来着的),思路大概是先通过一次double free修改一个chunk的size为其它大小,然后free一次,再修改成非fastbin范围的堆块,并且防止堆块放入unsortedbin被check fail,最好不要构造堆相互重叠(这句话的意思差不多就是尽量 ...
2021浙江省决赛
2021省赛决赛题解
总结本次比赛最终rank21,幸而拿到省赛一等奖最后一名。pwn题签到拿下二血,re签到拿下还是好的,但是pwn少拿了一道有点可惜。最终还是靠学长ak web才拿下的省一,希望学长明年还能带我。下面放出本次比赛提交的wp,misc和cry因为没有留下图片(就是wps复制过来的,导出pdf之后交了,后面word删了图片也就没了)。
Web远古特性换行绕过
1hint/hint.txt%0a../../../../../../flag
just login12345678910111213141516171819202122232425import requestsurl = "http://8fd95e2e-9d91-45b1-8ba9-d41be0125b3f.zj-ctf.dasctf.com:80/login"flag = ''data = {"username": "123' oorr 1=1 -- ", "password": &q ...
lctf2016_pwn200 writeup
buu刷题记录-lctf2016_pwn200
静态分析checksec 64位保护全关,并且栈可读可写可执行,那么主要思路应该是执行shellcode了。main函数一个IO初始化和一个函数,进去发现有一个name输入,是用for - read(1)实现的,但是观察缓冲区和循环大小,发现缓冲区大小与循环次数相同,意味着如果我输入填满缓冲区,一会输出名字的时候可以泄露栈地址。sub_4007DF这个函数就是输入一个3位数值返回int。继续往下看发现它又有一个与缓冲区大小相等的一次输入,并且可以覆盖到char *dest这个指针变量,一会会将整个缓冲区以字符串形式拷贝到那个指针内的地址中。那么如果我们将ptr修改那基本是任意地址写了,加上之前泄露的站地址便可以在上面执行shellcode,但是同时也有限制,那就是这是一个字符串拷贝,如果需要在返回的时候执行shellcode那么需要填上shellcode后先放上一个jmp rsp的地址。而64位程序地址虽占8个字节但是实际高两个字节一般都是空的,后面的shellcode很可能无法拷贝。我还尝试过栈迁移,但是栈迁移需要改连续的两个为地址 ...
2021江西省赛RSA题解
来源于一位师傅发的RSA的题目,这题正解是套公式,但是其实可以直接分解n。
题来康康别的师傅发给我的江西省赛的cry题,发现自己还是能很好的运用一些小技巧的,正解虽然不用分解n,但是咱还是可以分解n的hhh
题目分析1234n=275523046062290349033660588158499540302876486950633853629554321377908725714120358241289186747192477372955650015759915975192707897764082089703238080167339763384333713281008808989421065156276073882269128709811802158832738054912094616717303770991852787114539492656419665825639107085296191858859283101682888104887842423681607433596665834991179494079218123177002502400679295725587854310711 ...
2020浙江省赛 pwn2 writeup
国庆复的盘,今天补一下
静态分析checksec保护全开。
经典菜单题,没有去符号表,查看menu函数发现只有添加和删除操作,但是可以发现删除操作是通过函数指针实现的。并且分little 和 big的区别,free little就是一个free,free big 就是要把那个堆块里面的内容指向的堆块free了还要把本身给free,但是指针并没有清零。造成了UAF漏洞,并且在add的时候根据字符串长度来分配大小,并且会先读栈上,然后在strcpy拷贝,这就意味着输入不能存在\0。并且你输入的size只跟你输入大小有关,它拷贝分配的大小还是用strlen算出来长度再malloc然后strcpy,这一波操作下来就没办法溢出操作,并且由于\0截断也限制了很多。开了PIE无法unlink,和用got表泄露libc,而泄露程序基址也是比较难的(虽然正解是泄露程序基址的awa)。
泄露libc考虑劫持函数指针,直接覆盖部分来修改函数,发现freebig和freelittle函数指针都在堆上面,由于只有最后三位相同,而我们覆盖是以字节为单位的,在调试可以选择先关了ASLR,让它在确定位置上加载不妨 ...
gyctf_2020_document write up
今天来康康这道题gyctf_2020_document
静态分析确定漏洞类型经典的堆菜单题,保护全开,2.23的libc。保护全开意味着got表劫持不了。增删改查四样动作都有,并且没有那种虚晃一枪(例如show函数直接给你puts一个too young too simple之类的)的函数。
先看add函数,malloc了两个堆块,都是固定大小,一个堆块是0x20大小,另一个是0x90大小。然后第二个堆块的指针存在了第一个堆块上面。第一个堆块后八个字节用来存了性别,性别要么1要么16,是通过判断你输入的是否为W来决定的。之后就是那个0x90的大堆块上面存一个名字,中间间隔一个flag,然后堆块偏移0x10的位置上面放上你要输入的内容。
看看delete函数,存在明显 的UAF漏洞,可以操作free的堆块。并且只free 0x90的堆块而0x20的堆块不会free。那么通过这些分析我们就可以先add两个堆块,free掉第一个之后show第一个就能泄露出libc的地址。
其它的中规中矩,唯独edit函数正常情况下它每个堆块只允许edit一次,但也只是因为那个0x20堆块的后面的那个fla ...