这篇博客用来记录攻防世界pwn新手区刷题过程。。。
0x01 get_shell
题目描述: 运行就能拿到shell呢,真的
直接使用nc连接远程端口就可返回shell
0x02 CGfsb
题目描述: 菜鸡面对着pringf发愁,他不知道prinf除了输出还有什么作用
首先使用checksec
查看文件安全机制
关于checksec的使用可以参考checksec工具使用
将程序拖入IDA查看反汇编代码
显然在程序的第23行存在格式化字符串漏洞
,而且发现关键代码system("cat flag)
,条件是使得pwnme
值为8;
关于格式化字符串漏洞可参考格式化字符串漏洞
利用格式化字符串漏洞修改pwnme
的值
解题脚本:
1 | #!/usr/bin/python |
关于pwn工具的使用可参考pwntools使用
0x03 when_did_you_born
题目描述: 只要知道你的年龄就能获得flag,但菜鸡发现无论如何输入都不正确,怎么办
查看安全机制
拖入IDA查看反汇编代码
发现危险函数gets
,存在溢出漏洞,通过v4溢出修改v5的值
解题脚本:
1 | #!/usr/bin/python |
0x04 hello_pwn
题目描述: pwn!,segment fault!菜鸡陷入了深思
查看安全机制
拖入IDA查看反汇编代码
read函数处可能造成溢出
由源代码可知只需使if
中等式成立便可以得到flag
跟进变量unk_601068
,发现dword_60106C
就在下面将,则可以通过read修改其值
解题脚本:
1 | #!/usr/bin/python |
0x05 level0
题目描述: 菜鸡了解了什么是溢出,他相信自己能得到shell
查看安全机制
拖入IDA查看反汇编代码
直接进入vulnerable_function()
由于read函数所能读入的最大字节要大于buf与栈底的距离,所以存在栈溢出漏洞
解题脚本:
1 | #!/usr/bin/python |
0x06 level2
题目描述: 菜鸡请教大神如何获得flag,大神告诉他‘使用
面向返回的编程
(ROP)就可以了’
查看保护机制
拖入IDA查看反汇编代码
与level0
同样的溢出漏洞,只不过在程序里找不到现成的可以获取shell的函数了,所以需要将程序中的字符串当做system
的参数传入
在IDA中使用shift+F12
可以查看程序中的所有字符串及其位置
看到有/bin/sh
字符串,地址为0x0804A024
溢出原理图
解题脚本:
1 | #!/usr/bin/python |
0x07 guess_num
菜鸡在玩一个猜数字的游戏,但他无论如何都银不了,你能帮助他么
查看安全机制
可以看到这次安全机制基本上都开了
拖入IDA查看反汇编代码
gets存在溢出漏洞,可以通过gets修改随即种子seed
的值
整个程序的逻辑就是猜数字,猜中十次才可以的到flag;
这里使用rand来生成随机数,然而rand生成的随机数并不是真正的随机数,只是在一定范围内随机,实际上是一段数字的循环,这些数字取决于随机种子。在调用rand()函数时,必须先利用srand()设好随机数种子,如果未设随机数种子,rand()在调用时会自动设随机数种子为1;
正常情况下应该使种子随生成的随机数而变化,即每生成一次随机数更改一次种子
使用python自带的ctypes模块进行python和c混合编程
使用ldd查看guss_num所使用的共享库libc
可以看到libc.so.6
指向的文件/lib/x86_64-linux-gnu/libc.so.6
可当做共享库载入python中,载入之后就可以通过python调用共享库中的函数,实现混合编程
解题脚本:
1 | #!/usr/bin/python |
注: 最后的print io.recvall()
可以用io.interactive()
代替,不过使用后者会返回一个无效的命令行
0x08 cgpwn2
题目描述: 菜鸡认为自己需要一个字符串
查看安全机制
拖入IDA查看反汇编代码
直接跟进hello
显然在gets()函数存在溢出
然而程序中有现成system
函数,却找不到可以利用的字符串,考率到前面的fgets
函数,可以尝试将所需要的字符串参数传入name
变量中,在将name
作为system
的参数传入
解题脚本:
1 | #!/usr/bin/python |
0x09 string
题目描述: 菜鸡遇到了Dragon,有一位巫师可以帮助他逃离危险,但似乎需要一些要求
查看程序安全机制
拖入IDA查看反汇编代码
输出了V4的值,其他暂未发现异常,跟进查看
创建了一个新的游戏人物,同时调用了三个函数,依次跟进查看
在第一个函数中碰到了一个循环,必须输入east才能跳出循环
在第二个函数中发现了格式化字符串漏洞,触发条件为v1==1
在第三个函数中发现了关键代码,程序将用户输入的字符强制转化成函数执行,执行的条件就是*a1 == a1[1]
,逆推发现a1
就是V3
,所以条件就是V3[0]=V3[1]
就是这里可以用来输入shellcode
.
攻击思路: 利用格式化字符创漏洞修改V3[0]
的值,再输入一个shellcode
获取shell,可以在http://shell-storm.org/shellcode/网站上找到对应的shellcode
来获取shell
解题脚本:
1 | #!/usr/bin/python |
0x0A int_overflow
题目描述: 菜鸡感觉这题似乎没有办法溢出,真的么?
查看安全机制
拖入IDA查看反汇编代码
跟近查看,进入到chek_passwd
出现危险函数strcpy
,存在栈溢出漏洞,但是要想触发漏洞,必须使得v3在3和8之间
v3的值为s字符串的长度,根据题目提示想到整数溢出,利用整数溢出触发漏洞
解题脚本:
1 | #!/usr/bin/python |
0x0B level3
题目描述: libc!libc!这次没有system,你能帮菜鸡解决这个难题么?
题目提供的文件是一个压缩包,解压之后有两个文件,一个是可执行文件,还有一个动态链接库文件
关于plt、got、动态链接之间的关系可以参考
libc_32.so.6
中存放的是程序运行时所用到的外部函数,通过PLT表和GOT表连接到主程序中
查看安全机制
没有开启PIE
,所以libc
中函数的相对地址不发生变化(程序自带函数地址也不会发生变化),也就是说只要知道libc
在程序中的的基址,根据偏移地址就可以知道任何函数在程序中的实际地址
拖入IDA查看反汇编代码
在vulnerable_function()
中read()
函数存在溢出,然而程序中并没有现成的system函数,所以必须想办法调用动态连接库中的函数
攻击思路: 利用栈溢出返回到write
函数(注意:只能通过plt调用函数,不能直接跳转到got表),同时传入write
函数的got
表的地址,由于程序没有开启PIE
保护,所以程序中plt
表和got
表的位置都是不会变化的,函数的相对地址也是固定的,所以可以通过本地的程序获取write
函数got
表的地址,然后输出write
函数实际地址。
将得到的实际地址与libc
中的write
的偏移地址相减,则可以得到libc
的基地址,加上system
函数在libc
里面的偏移地址,就可以得到system
函数在程序中的实际地址
此时利用溢出再次控制返回函数到main
函数,二次攻击溢出返回到system
函数,传入/bin/sh
参数,就可以得到shell
了
注: 字符串/bin/sh
可以在libc中找到,查找方法如下
1 | strings -a -t x libc_32.so.6 | grep "/bin/sh" |
解题脚本:
1 | #!/usr/bin/python |
参考链接
https://www.cnblogs.com/at0de/p/11269120.html
https://bbs.pediy.com/thread-254858.htm
https://www.jianshu.com/p/457520f97a76