Dùng python + regular expression duyệt links từ data.ceh.vn/CEHv9-TV

Tại daynhauhoc.com, mình thấy có rất nhiều bạn muốn trở thành hắc-cờ nên mình muốn chia sẻ link tài liệu CEH version 9 tiếng Việt :wink: . Nhưng các bạn đừng lo lắng, đống tài liệu này chỉ giúp các bạn trở thành 1 script kiddie (hoặc nhỉnh hơn nếu các bạn chịu khó tìm hiểu và tư duy blablabla thêm). Mục đích là biết cách tấn công để bảo vệ bản thân.

Đường link sẽ dẫn bạn tới 1 trang chỉ mục và bạn phải ngồi duyệt từng link, copy link và tải. Nên sẵn tiện, mình làm 1 cái script (kpfetchlinks.py) dùng để get links, còn phần tải là thuộc về bạn :slight_smile: ahihi (dùng urllib tải lâu chết luôn) . (Xin cảm ơn stackoverflow đã giúp mình phần regular expression). 1 điều nữa là bạn có muốn bắt bẻ tiếng anh của mình thì xin nhẹ tay (mình gà và khoái xài tiếng anh).

  • kpfetchlinks.py (main)
#!/usr/bin/python 

from __future__ import print_function, absolute_import
import os, sys
import urllib2, re
import kpstd

target_root = "http://data.ceh.vn/CEHv9-TV"        # Change if nessessary
target_ext  = ['pdf', 'mp4', 'avi']
target_output = 'ceh_links.txt'

fout = open(target_output, "w")

links = []

rule_a   = re.compile("""<a\s+(?:[^>]*?\s+)?href="([^"]*)["]""")
#rule_pdf = re.compile("""<a\s+(?:[^>]*?\s+)?href="([^"]+.pdf)["]""")
#rule_mp4 = re.compile("""<a\s+(?:[^>]*?\s+)?href="([^"]+.mp4)["]""")
def fetch_alink(strings):
    if strings == None:
        return []
    
    l = []
    for t in rule_a.findall(strings):
        if type(t) == tuple:
            l.append(t[0])
        elif type(t) == str:
            l.append(t)
    return l
#

def get_data(url, verbose=True):
    try:
        src = urllib2.urlopen(url).read()
    except Exception as e:
        if verbose:
            print("Failed")
            kpstd.error("Exception: %s\n" %str(e))
        return None
    else:
        return src
#

def loop_getlinks(url):
    global links, scanned
    for item in fetch_alink(get_data(url, verbose=False)):
        item = item.strip('/').strip('/').strip('/')
        if item.endswith(".pdf") or item.endswith(".mp4") or item.endswith(".avi"):
            if item not in links:
                links.append(''.join([url, '/', item]))
                kpstd.info('Found: %3d\r' %len(links))
        else:
            if ''.join([url, '/', item]) not in scanned:
                scanned.append(''.join([url, '/', item]))
                if not item.startswith('?'):
                    loop_getlinks(''.join([url, '/', item]))
#

scanned = []
def main():
    global links, scanned
    
    kpstd.norm('Get source from root target: ')
    src = get_data(target_root); print("OK")
    
    scanned.append(target_root)
    scanned.append("http://data.ceh.vn/CEHv9-TV/")
    for item in fetch_alink(src):
        item = item.strip('/').strip('/').strip('/')
        if item.endswith(".pdf") or item.endswith(".mp4") or item.endswith(".avi"):
            links.append(''.join([target_root, '/', item]))
            kpstd.info('Found: %3d links\r' %len(links))
        else:
            if ''.join([target_root, '/', item]) not in scanned:
                if not item.startswith('?'):
                    loop_getlinks(''.join([target_root, '/', item]))
                scanned.append(''.join([target_root, '/', item]))
    
    kpstd.norm('Scan done. Analyzing results.\n')
    
    pdf_links = []
    mp4_links = []
    avi_links = []
    for item in links:
        if item.endswith('.pdf'):
            pdf_links.append(item)
        elif item.endswith('.mp4'):
            mp4_links.append(item)
        else:
            avi_links.append(item)
    
    kpstd.norm('Analyzed results.\n')
    kpstd.info('Scanned: %3d links\n' %len(scanned))
    kpstd.info('Found: %3d pdf | %3d mp4 | %3d avi\n' %(len(pdf_links), len(mp4_links), len(avi_links)))
    kpstd.info('Writing data to file: ')
    for i in pdf_links:
        fout.write('%s\n' %i)
        fout.flush()
    
    fout.write('\n')
    for i in mp4_links:
        fout.write('%s\n' %i)
        fout.flush()
    
    fout.write('\n')
    for i in avi_links:
        fout.write('%s\n' %i)
        fout.flush()
    
    print(" OK")
    
#

try:
    main()
except KeyboardInterrupt:   
    print
    kpstd.error('User quit\n')
  • kpstd.py (phần phụ, làm màu mè cho đẹp, đặt file này cùng chỗ với file ở trên)
#!/usr/bin/python2

import os, sys

if os.name == 'posix':
    try:
        import colorama
    except ImportError as e:
        print('[-] kpstd: can not import colorama library.')
        print('[-] Exception info: ' + str(e))
        import_failed = True
        class colorama:
            class Style:    
                BRIGHT = RESET_ALL = ''
            class Fore:
                BLUE = GREEN = YELLOW = RED = ''
    else:
        colorama.init()
        import_failed = False

    progname = os.path.split(sys.argv[0])[1]

    def kpout(msg, str_col):
        if not import_failed:
            sys.stdout.write(''.join([str_col, colorama.Style.RESET_ALL, msg]))
            sys.stdout.flush()
        else:
            sys.stdout.write(''.join([str_col, msg]))
            sys.stdout.flush()

    def norm(msg):
        kpout(msg, ''.join([colorama.Style.BRIGHT, colorama.Fore.BLUE, '[*] ']))

    def info(msg):
        kpout(msg, ''.join([colorama.Style.BRIGHT, colorama.Fore.GREEN, '[*] ']))

    def warn(msg):
        kpout(msg, ''.join([colorama.Style.BRIGHT, colorama.Fore.YELLOW, '[-] ']))

    def error(msg):
        kpout(msg, ''.join([colorama.Style.BRIGHT, colorama.Fore.RED, '[-] ']))

################################################################################
elif os.name == 'nt':
    from ctypes import windll

    class color:
        black    = 0
        blue    = 1
        green    = 2
        cyan    = 3
        red        = 4
        pink    = 5
        yellow    = 6
        white    = 7
        gray    = 8
        class light:    # ~ bright :))
            blue    = 9
            green    = 0xA
            cyan    = 0xB
            red        = 0xC
            pink    = 0xD
            yellow    = 0xE
            white    = 0xF

    def set_color(color):
        if type(color) != int:
            return False;
        STD_OUTPUT_HANDLE = -11;
        stdout_handle = windll.kernel32.GetStdHandle(STD_OUTPUT_HANDLE);
        windll.kernel32.SetConsoleTextAttribute(stdout_handle, color);
        return True;

    default_color = color.white;
    def reset_color():
        return set_color(default_color);

    out = lambda msg: sys.stdout.write(msg);
    mod_name = "";
    mod_name_color = color.light.cyan;

    def norm(msg):
        set_color(color.light.cyan);
        out('[*]');
        reset_color();
        if mod_name:
            set_color(mod_name_color);
            out(mod_name); reset_color();
        out(msg);
        return "";

    def info(msg):
        set_color(color.light.green);
        out('[*]');
        reset_color();
        if mod_name:
            set_color(mod_name_color);
            out(mod_name); reset_color();
        out(msg);
        return "";

    def warn(msg):
        set_color(color.light.yellow);
        out('[!]');
        reset_color();
        if mod_name:
            set_color(mod_name_color);
            out(mod_name); reset_color();
        out(msg);
        return "";

    def error(msg):
        set_color(color.light.red);
        out('[-]');
        reset_color();
        if mod_name:
            set_color(mod_name_color);
            out(mod_name); reset_color();
        out(msg);
        return "";

    def exception(msg):
        if True:
            raise Exception(msg);

    def red(msg):
        set_color(color.light.red);
        out(msg);
        reset_color();
        return "";

    def cyan(msg):
        set_color(color.light.cyan);
        out(msg);
        reset_color();
        return " ";

    def yellow(msg):
        set_color(color.light.yellow);
        out(msg);
        reset_color();
        return " ";

    def green(msg):
        set_color(color.light.green);
        out(msg);
        reset_color();
        return " ";

    def white(msg):
        set_color(color.light.white);
        out(msg);
        reset_color();
        return " ";

Sau khi chạy thành công, nó sẽ tạo 1 file tên là “ceh_links.txt”. Mình đã test trên Kali linux và thành công. Nếu bạn thấy code dư thừa / code lỗi hay bạn có ý kiến tối ưu hơn thì post lên, tụi mình thảo lựn :)) mình rất mù mờ phần regular expression.
Chào thân ái, quyết thắng.

9 Likes

Mình xin góp đoạn code của mình để làm công việc bạn cần đối với link trên:

def is_dir(link):
    return True if link.endswith('/') else False


def get_links(link):
    res = requests.get(link)
    if res.status_code == 200:
        soup = BeautifulSoup(res.text, 'lxml')
    else:
        return None
    links = soup.find_all('a')[5:]
    for sublink in links:
        if is_dir(sublink.attrs['href']):
            get_links('{}{}'.format(link, sublink.attrs['href']))
        else:
            result.append('{}{}'.format(link, sublink.attrs['href']))
    return result

result = []
resources = [link for link in get_links('http://data.ceh.vn/CEHv9-TV/')
             if link[-3:] in ['pdf', 'mp4', 'avi']]


print(len(resources))
# 170

Dùng requestsBeautifulSoup4 mình thấy code dễ đọc hơn là dùng urllibre
Và có vẻ là ngắn hơn nữa :smile:
Cheers!

6 Likes

Mình xin sửa thêm một chút code của bạn

def is_dir(link):
    return link.endswith('/')
def get_links(link):
...

ở đây bạn viết kiểu recursive thì nên đặt biến result = [] trước khi định nghĩa hàm cho dễ đọc (dễ tìm tại sao có cái biến result trong function), nếu có thể nên viết theo kiểu return giá trị thay vì sửa trạng thái của biến result.
Do bạn dùng cách thay đổi trạng thái của list result nên các đoạn “return…” khá khó hiểu vì function này vừa sửa trạng thái biến result, vừa trả về kết quả.

resources = [link for link in get_links('http://data.ceh.vn/CEHv9-TV/')
             if link[-3:] in ['pdf', 'mp4', 'avi']]

đoạn code này sẽ gặp exception khi if res.status_code != 200, vì lúc đó get_links trả về None.
for ... in None sẽ lỗi.

 if link[-3:] in ['pdf', 'mp4', 'avi']]

đoạn này có thể viết là

if link.endswith(('pdf', 'mp4', 'avi'))

Btw, mình đồng ý với việc dùng lib requests và BS4 dễ đọc, dễ hiểu hơn. Cách dùng urllibre khá cũ / khó - chỉ dành cho các hacker :blush:

Double cheers!

3 Likes

Mình còn thiếu nhiều kinh nghiệm lắm, cảm ơn bạn và bạn @hvn_familug đã quan tâm và góp ý :smile: Đúng là mình code hơi bị dài với cách dùng urllibre bị cũ, một phần là do mình chưa biết nhiều thư viện.

1 Like

nếu dùng các hệ điều hành *NIX, bạn có thể dùng wget để mirror bằng một câu lệnh:

wget -m data.ceh.vn/CEHv9-TV/

Thanks and RIP ceh server :smile:

5 Likes

Tốc độ mạng nhanh quá :scream:

2 Likes

Quào @@ Mạng nhà mình xài chùa với hàng xóm, tối đa có 1MB/s thôi :’( Không thể bì kịp.

1 Like
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?