XCTF pwn新手区解题记录

一、前言

    闲来无事,刷刷ctf题


二、题目: level0

    1、下载好题目后,拖入到kali中去,用filechecksec查看一下,可以发现该程序是64位,只开了NX保护,如下图所示:

    2、拖入到IDA中去,发现在main函数中打印出信息后就调用了vulnerable_function函数,跟进vulnerable_function函数,可以发现read函数处为栈溢出漏洞,并且可以得知该buf数组距离ebp0x80个字节,如下图所示:

    3、通过IDA,可以发现程序中存在一个名为callsystem的函数,可以直接getshell,有了这个加上上面的偏移量,就可以直接编写expexp执行结果如下图所示:


三、题目: level2

    1、下载好题目后,首先使用filechseksec,可以发现程序是32位并且开了NX的,如下图所示:

    2、拖入到IDA当中去,可以发现程序首先调用vulnerable_function函数后就打印一串字符串就结束了,跟进到vulnerable_function中去,可以发现read存在栈溢出,并且buf距离ebp0x88,如下图所示:

    3、上面我们找到了buf距离返回地址的偏移量(0x88+4),仔细观察,我们可以发现存在_system函数可以getshell,跟进去该函数后,可以发现,需要传入字符串/bin/sh作为参数才能getshell,使用快捷键shift+F12调出字符串界面,发现了该字符串,那么我们的payload应该为0x8C * b'A' + p32(_system函数地址) + p32(0) + p32(/bin/sh字符串地址)(PS:这里之所以有一个p32(0),是因为我们正常调用一个函数时,栈从高到底的结构为:参数 返回地址 ebp,所以这里我们需要提供一个虚假的返回地址以模拟正常的调用过程),最后exp执行结果如下图所示:


四、题目: string

    1、下载好题目后,拖入到kali中去,用filechecksec查看一下,可以发现该程序是64位,如下图所示:

    2、将程序拖入到IDA中去,在main函数中,首先调用alarm函数设置了0x3C秒后关闭程序,然后给变量v4申请了8个字节的空间,并且给v4[0]赋值为68v4[1]赋值为85,之后就是调用puts函数打印一些信息,然后就调用sub_400D72函数,并且将v4数组作为参数传入,之后main函数就结束退出了,如下图所示:

    3、跟进sub_400D72中去,该函数首先要求输入一个名字,如果长度小于等于0xC,则创建一个角色,然后依次调用sub_400A7Dsub_400BB9sub_400CA6函数,否则就退出,如下图所示:

    4、跟进到sub_400A7D中去,该函数只有输入east才能正常返回,如下图所示:

    5、接着跟进到sub_400BB9中去,该函数首先要求我们输入一个数字,如果输入的数字为1,则进入一个if里面去,在该if块里面,首先要求输入一个数字,然后要求输入一串字符串,紧接着该函数直接将该字符串作为参数传入到printf函数中去了,很明显的格式化字符串漏洞,如下图所示:

    6、接着分析一下sub_400CA6,该函数首先调用puts函数打印一些信息,然后判断参数数组a[0]是否等于a[1],如果相等,则申请一片空间,然后通过read函数获取用户输入写入到刚刚申请到的空间中,然后把该空间中的值作为一段代码执行,而这里的参数数组就是main函数的v4数组,如下图所示:

    7、有了上面的分析,可以很明显得出解题的方法,首先利用格式化字符串漏洞,将v4[0]=v4[1],然后写入shellcodegetshell,首先我们来寻找一下偏移量,执行程序,输入名字之后,输入east,然后输入1,之后输入payload测试偏移量,从下图可以看出,偏移量为8,如下图所示:

    8、有了偏移量,就可以写exp了,但这里有一个小坑,__isoc99_scanf函数这里前几个字节没办法直接作为地址写入(PS:事后对比了其他师傅的wp,发现IDA反编译出来的内容都有点不同,不知道是不是这个原因),这里使用代码中前面输入那个地址,偏移量为7,在上面的图片中已标注,执行exp,结果如下图所示:


五、题目: guess_num

    1、首先下载好题目,拖入kali中查看一下基础信息,可以发现为64位的程序,如下图所示:

    2、拖进IDA中,发现程序首先生成了一个随机种子,然后调用gets函数获取输入,典型的栈溢出漏洞,但前面保护全开,也没法直接覆盖返回地址来rce,往下接着看,要求用户练着猜10次并且全部正确就可以得到flag,前面存在一个栈溢出,虽然没办法来rce,但可以用来覆盖随机化种子,有了种子,我们就可以直接提前计算出来随机值,而gets输入距离种子偏移量为0x20,如下图所示:

    3、直接使用c算出随机值,然后nc连接上去即可得到flag(PS:不知道我的python脚本为啥一直得不到flag,这里就直接简单粗暴的nc连接了),如下图所示:


六、题目: get_shell

    nc连接即可,如下图所示:


七、题目: int_overflow

    1、还是首先拖入到kali中查看一下基础信息,可以发现是32位的程序,如下图所示:

    2、运行一下程序,没发现什么有意思的东西,拖入到IDA中去,根据运行时的字符串,定位到了main函数中去,分析一下main函数,就是一个登录流程,没什么可疑的地方,如下图所示:

    3、跟进到login函数中去,可以发现最多可以输入0x199大小的密码,其余地方也没什么可疑的,如下图所示:

    4、跟进到check_passwd函数中去,首先可以发现当中的v3变量大小是一字节,然后程序将密码字符串的大小赋值给了v3,之后判断v3是否小于3,大于8,如果是,就退出,否则就打印信息并将密码拷贝到dest数组中去,结合题目名的提醒,可以发现这里存在整数溢出漏洞,可以绕过其对v3的判断,然后栈溢出覆盖返回地址,如下图所示:

    5、那么v3等于多少时能绕过喃,这里v3只有一个字节大小,所以我们只需要使我们输入的密码长度的最后一个字节为4,5,6,7,8之中的一个即可,这里密码最多可输入0x199字节,写一个判断脚本跑一下所有可能,如下图所示:

    6、这里选择第一个260,接下来我们还需要偏移量,IDA已经给出了,为0x14ebp,那么我们覆盖0x18字节之后即可覆盖返回地址,在该程序中,还存在一个直接获取flag的函数what_is_this,我们直接将返回地址覆盖为这个函数地址即可拿到flagexp执行结果如下图所示:


八、题目: cgpwn2

    1、下载好题目之后,拖入kali中简单查看一下程序信息,可以发现该程序为32位,并且开了NX,如下图所示:

    2、将程序拖入到IDA中,首先查看main函数,该函数没什么可疑的,如下图所示:

    3、跟进到hello函数中去,可以发现在函数末尾调用了gets函数,很明显的栈溢出,并且从IDA反编译的结果我们可以知道数组s距离ebp0x26,也就是说0x26 + 4个字节的偏移量后即可覆盖到返回地址,如下图所示:

    4、因为题目开了NX,没办法在栈上直接部署shellcode来执行,仔细观察,我们发现提供了system函数,但是没有提供/bin/sh字符串,我们只要想办法制造一个/bin/sh字符串即可getshell,在hello函数中,程序还调用了fgets函数获取输入储存到name变量中,查看name位置可以发现name位于bss段中,那么exp的思路就是首先在程序调用fgets处输入/bin/sh;字符串,然后再调用gets函数处溢出覆盖返回地址为system函数地址,exp执行结果如下图所示:


九、题目: level3

    1、下载好题目,拖入到kali中去,查看一下程序的基本信息,可以发现程序为32位的,并且开了NX,如下图所示:

    2、将程序拖入到IDA中去,首先看一下main函数,main函数首先调用了一个vulnerable_function函数,然后就是调用了write输出信息到控制台中,没什么存在漏洞的地方,如下图所示:

    3、跟进到vulnerable_function函数中去,可以发现该函数调用的read函数存在栈溢出,并且IDA已经计算出来buf距离ebp0x88,那么覆盖0x88 + 4 = 0x8C个字节之后即可覆盖返回地址,如下图所示:

    4、仔细观察该程序,可以发现没有system等现成的函数可以让我们直接getshell,但是存在libc和已经调用过的write函数,并且题目还给了libc.so文件,那么思路就很明显了,首先栈溢出调用write函数输出write函数的地址,进而获取到libc的基地址,因为libc.so中存在system函数和/bin/sh字符串的偏移地址,加上基地址就可以得到对应的绝对地址,之后再栈溢出调用write时将返回地址设置为vulnerable_function函数的首地址,再次栈溢出覆盖返回地址为前面计算出的system的绝对地址即可getshellexp执行结果如下图所示:


十、题目: cgfsb

    1、下载好题目,拖入到kali中去,查看一下程序的基本信息,可以发现程序为32位的,并且开了NX,如下图所示:

    2、拖入到IDA中去,可以发现程序首先要求我们输入一个名字,然后输入一串信息,之后直接将信息作为传入到了printf函数里面去了,典型的格式化字符串漏洞,之后则判断pwnme变量是否等于8,如果等于8,则输出flag,如下图所示:

    3、经过上面的分析,那么解题的思路就很明显了,利用格式化字符串漏洞将pwnme变量修改为8即可。那么现在需要确定两个东西,一个是偏移量,另一个是pwnme变量的地址,仔细观察可发现,pwnme变量不是函数局部变量,而是bss段的一个变量,双击变量名即可获得地址,至于偏移量怎么确定,这么不过多叙述了,不明白的可以看我上一篇文章https://www.cnblogs.com/aWxvdmVseXc0/p/15734510.html,这里计算出来偏移量为10,如下图所示:

    4、最后exp执行结果如下所示:


十一、题目: hellopwn

    1、下载好题目,拖入到kali中去,查看一下程序的基本信息,可以发现程序为64位的,并且开了NX,如下图所示:

    2、拖入到IDA当中,进入到main函数,会发现程序首先输出一些信息,然后调用read函数获取输入,之后比较dword_60106C变量是否等于0x6E756161,如果相等,这调用sub_400686函数,跟进sub_400686函数,会发现该函数作用为输出flag,如下图所示:

    3、有了上面的分析,那么解题的思路就很明显了,利用read函数溢出覆盖dword_60106C变量为0x6E756161,仔细观察一下,会发现unk_601068变量增长4个字节到dword_60106C,既偏移量为4,最后exp执行结果如下图所示:


十二、相关链接

    题目和expgithub链接: https://github.com/windy-purple/XCTF_PWN

posted @ 2022-01-20 22:12  windy_ll  阅读(267)  评论(0编辑  收藏  举报