HITCTF 2022 的两个pwn题 time 和 doc
HITCTF两个pwn题练习
pwn2 TIME
题目附件:pwn2.zip
漏洞点
1、prirntf格式化字符串 - 信息泄露
global_name是我们输入的字符串,通过%p可以泄露栈上的信息。
这个字符串的长度限制是0xff,所以还是可以泄露挺多东西的
2、条件竞争race condition
pthread_create起子进程执行display(v1)
重点看这个位置,a1为1表示我们输入的是想访问flag.txt,否则就是访问old_flag.txt。is_secret_file是bss段的全局变量,不同的线程根据输入的不同,会将is_secret_file的值改成0或者1
a1和is_secret_file是在check_file_name()中设置的,这个函数的设置保护了flag.txt不会被直接读取到
但是is_secret_file是全局变量,所有子线程都会访问并改变该变量。考虑下面这种条件竞争时的情况
线程1本来a1为1,is_secret_file为1,file_name为”flag.txt”,是不满足进入dispaly_file_content()这一分支中的。但是由于有多个线程,且is_secret_file是共享变量。如果线程2此时正好运行到将is_secret_file赋值为0这里。当再次切换回到线程1时,由于is_secret_file为0,进入dispaly_file_content()这一分支。此时就会读取”flag.txt”继续处理。
虽然直接打印出来的内容时MD4哈希过的,根据这个内容无法恢复出原本的flag内容
但是,在dispaly_file_content()函数中,可以看到会将flag.txt的内容拷贝到栈上。
于是结合第一个格式化字符串,可以将flag泄露出来。
利用
完整exp如下
1 | ##!/usr/bin/env python |
从栈中dump出flag.txt的信息
利用脚本快速解析
1 | from pwn import * |
得到flag
pwn3 DOC
题目附件:pwn3.zip
简单解析
漏洞点在这里
max的初始值是0x800(2048 bytes),我们只需关注最后两轮的情况。当前面已转换2045 bytes的utf-8字符,而最后一个utf-16转成utf-8后是4字节时,就会覆盖到2049字节处。而2049位置处正好是flag.doc的mode,将mode改为0,在网页上通过http://122.114.225.168:10052/doc/extract_many?files=user0.doc|flag.doc
就能查看到flag内容。
构造的doc文档内容是:"a"*512 + "b"*512 + "c"*512 + "嘀"*167 + "特殊字符"*3
,这串utf-16字符转成utf-8后,正好是2049字节。
以上描述中的特殊字符是指4字节的utf-8字符,从以下链接中随意找一个使用即可
1 | >>> a = "嘀" |
167个”嘀”+3个”𝄔”,转换成UTF-8后,占据167*3+3*4 = 513
,正好覆盖到flag.txt
的mode,将其改成非0值。
什么是CGI
如何使用 CGI 脚本生成网页 这篇文章讲了静态html网页到动态html网页的发展过程,引入了CGI。
转!!常用的4种动态网页技术—CGI、ASP、JSP、PHP 这篇文章描述了CGI的概念:客户端可以向web服务器上指定的CGI程序发起请求。web服务器收到该请求后会启动一个新的进程执行这个CGI程序,最后将程序运行的结果以网页的形式回给客户端。可以用c/c++/vb/perl等语言编写。
字符编码
A Short History Of Character Encoding
字符编码的历史:EBDIC -> ASCII(7 bits) -> ISO/IEC 8859 family & Windows 12xx family(8 bits) -> Unicode
细说:Unicode, UTF-8, UTF-16, UTF-32, UCS-2, UCS-4