『CTF』pwnable 学习笔记

admin 2024年5月17日20:08:03评论2 views字数 2066阅读6分53秒阅读模式

点击蓝字,关注我们

日期: 2023-09-19
作者: Mr-hello
介绍: 之前做pwn练习时记录的几个题目的笔记。

0x00 前言

翻了好久,才发现自己之前学习过一段时间的 pwnable 题目练习,趁着书写本次公众号文章,重新整理并复习了一下上面的几道题目。

0x01 coin1

知识点

socket编程 && 二分查找法

打开题目如下图所示。

『CTF』pwnable 学习笔记

分析题目意思,每次游戏会给出两个数NC分别代表硬币总个数、验证机会。在给出的N个硬币中存在一枚假币。只有通过称重的方式进行检验,真硬币重量为10,假硬币重量为9。一次可以称重的硬币数量不限,在到达验证次数之前给出假硬币编号即可算为一次过关。需要在一分钟之内进行一百次游戏。即可获取flag。由于时间太短,所以需要网络编程进行解决。算法使用二分查找法。

import socket, syssock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)address = ('127.0.0.1', 9007)sock.connect(address)print sock.recv(2048)for i in range(100):    recv = sock.recv(100)    N = int(recv.strip().split(' ')[0].split('=')[1])    C = int(recv.strip().split(' ')[1].split('=')[1])    low = 0    high = N    for j in range(C+1):        mid = int((low+high) / 2)        li = [str(k) for k in range(low, mid+1)]        buf = " ".join(li)        sock.send(buf + 'n')        coins = mid - low + 1 #number of sent coin        recv = sock.recv(100)        if recv[:8] == 'Correct!':            print recv            break        weight = int(recv)        if coins * 10 == weight:            low = mid + 1        else:            high = midrecv = sock.recv(1024)print recv

0x02 random

知识点

rand() 函数随机数种子

连上ssh,cat random.c文件,拿到源程序,在本地编译测试。发现代码没加随机种子,所以随机值根本不会改变,直接进入gdb看随机值。

『CTF』pwnable 学习笔记

也就是说rand()函数每次生成的数值不会随机,只需要对得到的数值进行异或。

『CTF』pwnable 学习笔记

接下来就是在服务器上测试,输入3039230856

『CTF』pwnable 学习笔记

0x03 passcode

知识点

got表函数覆写

使用GDB动态调试时发现在调用welcome函数和login函数时ebp地址一样。

『CTF』pwnable 学习笔记

『CTF』pwnable 学习笔记

这样就可以导致栈溢出。在welcome函数中输入的v1变量长度可以达到100。地址为ebp-70h。在login函数中passcode1地址为ebp-10h。两者相差0x70h - 0x10h96位,v1变量长度100,也即最后四位可以覆盖掉passcode1。本题溢出点是由scanf函数未加&导致的。输入scanf(“%d”,&passcode)时读取的是passcode的地址0x70707070,当输入scanf(“%d”,passcode)时读取的是passcode这个地址的存储内容即0x80808080,如果我们可以控制0x80808080这个内容,那我们就可以利用这个漏洞进行GOT表的覆写。刚好在输入name变量时可以对该处进行覆盖。我们可以覆写掉fflush函数。fflush函数地址为0x0804A010

『CTF』pwnable 学习笔记

即我们输入的最后四位应该是x10xA0x04x08。这样我们就将scanf()函数处的初始内容改为了x10xA0x04x08,然后这一步我们只是将覆写函数的地址传了进去,我们还要通过passcode1来将函数内容写进去,在输入passcode1的时候,通过scanf()函数取出的便成为fflush函数的地址,然后我们的输入就覆盖掉了fflush函数地址上的内容。这里我们已经有了system函数,我们直接将system函数内容写入即可。system函数传了参数bin/cat flag,所以我们需要从传参数的那个地址写过来。即0x0804862D,并且由于自接受passcode1时需要以int类型输入,即将0x0804862D转换为134514221输入。

payloadpython -c print"'a'*96 + 'x10xa0x04x08'+ 'n' + '134514221n'" | ./passcode

0x04 结尾

这些内容是我刚接触逆向时学习留下的一些笔记,后面在写文章时苦于不知道写什么内容,于是就翻了出来,大体看了一看,发现有部分笔记记得很模糊,所以趁着这次写文章,又去记录了一遍,也发现了一些新东西,也算是整理一下自己的记忆了。

『CTF』pwnable 学习笔记

免责声明:本文仅供安全研究与讨论之用,严禁用于非法用途,违者后果自负。

点此亲启

原文始发于微信公众号(宸极实验室):『CTF』pwnable 学习笔记

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年5月17日20:08:03
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   『CTF』pwnable 学习笔记http://cn-sec.com/archives/2049939.html

发表评论

匿名网友 填写信息