음.. 또 개발 중국어 번역..
대충 www.tar.gz를 받아야 할거 같다
받아보면 3003개의 php파일이 있다.
이런 난독화?된 php 소스들이 3003개인건데, system, eval 과 같이 웹쉘로 이용될 수 있는 함수들이 보인다.
한마디로 문제의 논지는 해커가 웹서버를 해킹하여 웹쉘을 올려놨는데 3003개중에서 웹쉘로 이용될 수 있는 아이를 찾아 실행시켜야 하는것이다.
솔직히 말하자면 이문제에 삽질 너무 했다..(많이는 아니지만)
코드를 보면 함수도 선언되어있고 system에 $_GET으로 user input을 받는데 3항 연산자로 선언하여 결국엔 user input이 system과 같은 함수에 도달하지 못하는 경우도 있고.. 주석 안에 코드가 있는 경우도 있고 뭐 이런 여러가지 난독화 기법이 걸려있었다.
나는 이를 optimization해야 하는 문제라 생각하여 주석을 지우고 쓸데없는 함수(선언되지 않고 정의만 된 함수)를 삭제하고 뭐 이런걸 했는데 optimizing을 어느정도 다 했는데 시스템 명령을 실행할 수 있는 함수가 없는것이다 (..!)
사실 optimizing을 하면서도 뭔가 '아 이렇게 고생할거면 그냥 get,post user input만 파싱해와서 쭉 브포때리면 되지 않을까' 생각은 했었는데 optimizing 자체에 목표가 생겨버려서(?) 하다보니 해답과는 멀어진것 같다.
쨌든
optimization을 하는 코드만 첨부하고 이번 문제는 마무리하겠당.
뭐 이 코드에서 get,post 파싱하는 부분도 있으니 이거 가져와서 쭉쭉 짜면 될거같은데 귀찮아서 그냥 라업보고 풀었다
#-*-coding: utf-8-*-
import requests
import sys
import urllib
import time
import sys
import struct
import os
import locale
import re
locale.getpreferredencoding()
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
with open('eval_var.txt','rb') as f:
eval_vars = f.read().split('\n')
fun_re = re.compile('function \w{1,15}\(.+\)\{.+\}',re.DOTALL)
cnt = 0
for x in os.walk('src/'):
x[2].sort()
for files in x[2]:
#print '[+] doing this.. {}'.format(files)
with open('./src/'+files,'rb') as f:
lines = f.read()
tr = ''
# removing comment
if '/*' in lines:
tr += lines.split('/*')[0]
#print lines.split('/*')
for i in lines.split('/*')[1:]:
try:
tr += i.split('*/')[1]
except:
print 1-2
lines = tr
tr = ''
# removing unuse functions
p = re.compile('function (\w|\d){1,20}\(\)')
if p.findall(lines):
tr += lines.split('function ')[0]
for i in lines.split('function ')[1:]:
fn = i.split('()')[0]
if len(re.compile(fn).findall(lines)) > 1:
tr += 'function {}\n'.format('}'.join(i.split('}\n \n')))
else:
tr += '}'.join(i.split('\n \n}')[1:])
lines = tr
# removing unuse $_GET / $_POST
p = re.compile("\$_((GET)|(POST))\[\\'.*\\'\]")
tr = ''
if p.findall(lines):
t = lines.split('\n')
for i in t:
if p.findall(i):
if re.compile("\$_((GET)|(POST))\[.*\] \?\? ' '").findall(i):
pass
elif re.compile("\$_((GET)|(POST))\[.*\] = ' ';").findall(i):
pass
elif re.compile("\$_((GET)|(POST))\[\\'.*\\'\] \?\? \\' \\'").findall(i):
pass
else:
if re.compile("echo `{\$_GET\['.*'\]}`;").findall(i):
varname = re.compile("echo `{\$_GET\['").split(i)[1].split("'")[0]
if len(re.compile(varname).findall(lines)) == 1:
print 'high availability - {} : {}'.format(files, i)
print len(re.compile(varname).findall(tr))
exit(1)
else:
for jj in tr.split('\n'):
if varname in jj:
print files
print jj
print '--------------\n'
else:
print'-----------------'
print i
print'-----------------'
print lines
exit(1)
tr += i+'\n'
else:
tr += i+'\n'
lines = tr
'Web > BUUCTF' 카테고리의 다른 글
[BUUCTF] - [SUCTF 2019]CheckIn1 (1) | 2020.02.15 |
---|---|
[BUUCTF] - [RoarCTF 2019]Easy Calc1 (0) | 2020.02.14 |
[BUUCTF] - [HCTF 2018]admin1 (0) | 2020.02.13 |
[BUUCTF] - [SUCTF 2019]EasySQL1 (0) | 2020.02.13 |
[BUUCTF] - [护网杯 2018]easy_tornado1 (0) | 2020.02.13 |