XCTF pwn新手区解题记录
source link: https://bbs.pediy.com/thread-271236.htm
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
闲来无事,刷刷ctf题
二、题目: level0
1、下载好题目后,拖入到kali中去,用file
和checksec
查看一下,可以发现该程序是64位
,只开了NX
保护,如下图所示:
2、拖入到IDA
中去,发现在main
函数中打印出信息后就调用了vulnerable_function
函数,跟进vulnerable_function
函数,可以发现read
函数处为栈溢出漏洞,并且可以得知该buf
数组距离ebp
为0x80
个字节,如下图所示:
3、通过IDA
,可以发现程序中存在一个名为callsystem
的函数,可以直接getshell
,有了这个加上上面的偏移量,就可以直接编写exp
,exp
执行结果如下图所示:
三、题目: level2
1、下载好题目后,首先使用file
和chseksec
,可以发现程序是32
位并且开了NX
的,如下图所示:
2、拖入到IDA
当中去,可以发现程序首先调用vulnerable_function
函数后就打印一串字符串就结束了,跟进到vulnerable_function
中去,可以发现read
存在栈溢出,并且buf
距离ebp
为0x88
,如下图所示:
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中去,用file
和checksec
查看一下,可以发现该程序是64位
,如下图所示:
2、将程序拖入到IDA
中去,在main
函数中,首先调用alarm
函数设置了0x3C
秒后关闭程序,然后给变量v4
申请了8个字节
的空间,并且给v4[0]
赋值为68
、v4[1]
赋值为85
,之后就是调用puts
函数打印一些信息,然后就调用sub_400D72
函数,并且将v4
数组作为参数传入,之后main
函数就结束退出了,如下图所示:
3、跟进sub_400D72
中去,该函数首先要求输入一个名字,如果长度小于等于0xC
,则创建一个角色,然后依次调用sub_400A7D
、sub_400BB9
、sub_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]
,然后写入shellcode
来getshell
,首先我们来寻找一下偏移量,执行程序,输入名字之后,输入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
已经给出了,为0x14
到ebp
,那么我们覆盖0x18
字节之后即可覆盖返回地址,在该程序中,还存在一个直接获取flag
的函数what_is_this
,我们直接将返回地址覆盖为这个函数地址即可拿到flag
,exp
执行结果如下图所示:
八、题目: cgpwn2
1、下载好题目之后,拖入kali
中简单查看一下程序信息,可以发现该程序为32位
,并且开了NX
,如下图所示:
2、将程序拖入到IDA
中,首先查看main
函数,该函数没什么可疑的,如下图所示:
3、跟进到hello
函数中去,可以发现在函数末尾调用了gets
函数,很明显的栈溢出,并且从IDA
反编译的结果我们可以知道数组s
距离ebp
为0x26
,也就是说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
距离ebp
为0x88
,那么覆盖0x88 + 4 = 0x8C
个字节之后即可覆盖返回地址,如下图所示:
4、仔细观察该程序,可以发现没有system
等现成的函数可以让我们直接getshell
,但是存在libc
和已经调用过的write
函数,并且题目还给了libc.so
文件,那么思路就很明显了,首先栈溢出调用write
函数输出write
函数的地址,进而获取到libc
的基地址,因为libc.so
中存在system
函数和/bin/sh
字符串的偏移地址,加上基地址就可以得到对应的绝对地址,之后再栈溢出调用write
时将返回地址设置为vulnerable_function
函数的首地址,再次栈溢出覆盖返回地址为前面计算出的system
的绝对地址即可getshell
,exp
执行结果如下图所示:
十、题目: 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
执行结果如下图所示:
十二、相关链接
题目和exp
的github
链接: https://github.com/windy-purple/XCTF_PWN
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK