From 8503a7559ac13b5c3f1df1befcff670e87d01398 Mon Sep 17 00:00:00 2001 From: "kihwan.song" Date: Mon, 13 Jul 2026 17:05:35 +0900 Subject: [PATCH] =?UTF-8?q?vpn=20=EC=84=B8=ED=8C=85=20=EC=8A=A4=ED=81=AC?= =?UTF-8?q?=EB=A6=BD=ED=8A=B8=20=EC=88=98=EC=A0=95=209?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- connect-vpn/action.yml | 66 ++++++++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 25 deletions(-) diff --git a/connect-vpn/action.yml b/connect-vpn/action.yml index 46fb8fe..81482f9 100644 --- a/connect-vpn/action.yml +++ b/connect-vpn/action.yml @@ -136,7 +136,7 @@ runs: trap cleanup EXIT totp() { - python3 - "$OTP_SEED" "$OTP_SEED_FORMAT" <<'PY' + python3 - "$OTP_SEED" "$OTP_SEED_FORMAT" "${1:-0}" <<'PY' import base64 import hashlib import hmac @@ -144,7 +144,7 @@ runs: import sys import time - seed, fmt = sys.argv[1], sys.argv[2] + seed, fmt, offset_windows = sys.argv[1], sys.argv[2], int(sys.argv[3]) seed = "".join(seed.split()) def decode_base32(value): @@ -169,7 +169,7 @@ runs: else: raise SystemExit(f"잘못된 otp-seed-format: {fmt}") - counter = int(time.time() // 30) + counter = int(time.time() // 30) + offset_windows digest = hmac.new(raw, struct.pack(">Q", counter), hashlib.sha1).digest() offset = digest[-1] & 0x0f code = (struct.unpack(">I", digest[offset:offset + 4])[0] & 0x7fffffff) % 1000000 @@ -215,37 +215,53 @@ runs: exit 1 fi - while [ $(( $(date +%s) % 30 )) -gt 22 ]; do - sleep 1 - done - - curl_common -L -b "$COOKIE_JAR" -c "$COOKIE_JAR" \ - -X POST "$VPN_HOST/my.policy" \ - --data-urlencode "ga_code_attempt=$(totp)" \ - --data-urlencode "vhost=standard" \ - -o "$WORKDIR/03-webtop.html" - host_no_scheme="${VPN_HOST#https://}" host_no_scheme="${host_no_scheme#http://}" host_no_scheme="${host_no_scheme%%/*}" webtop_path="/vdesk/webtop.eui?z=$RESOURCE_NAME&webtop=/Common/dw_webtop&webtop_type=webtop_na_only" TOKEN_HEADERS="$WORKDIR/04-token.headers" - curl_common -b "$COOKIE_JAR" -c "$COOKIE_JAR" \ - -D "$TOKEN_HEADERS" \ - -H "X-Requested-With: XMLHttpRequest" \ - -H "Accept: */*" \ - -e "$VPN_HOST$webtop_path" \ - "$VPN_HOST/vdesk/get_token_for_sessid.php3" \ - -o "$WORKDIR/04-token.body" + otc="" + while [ $(( $(date +%s) % 30 )) -gt 22 ]; do + sleep 1 + done + + for otp_offset in 0 -1 1; do + echo "OTP 제출 시도 (time-window offset=${otp_offset})" + rm -f "$TOKEN_HEADERS" "$WORKDIR/04-token.body" + + curl_common -L -b "$COOKIE_JAR" -c "$COOKIE_JAR" \ + -X POST "$VPN_HOST/my.policy" \ + --data-urlencode "ga_code_attempt=$(totp "$otp_offset")" \ + --data-urlencode "vhost=standard" \ + -o "$WORKDIR/03-webtop-${otp_offset}.html" + + curl_common -b "$COOKIE_JAR" -c "$COOKIE_JAR" \ + -D "$TOKEN_HEADERS" \ + -H "X-Requested-With: XMLHttpRequest" \ + -H "Accept: */*" \ + -e "$VPN_HOST$webtop_path" \ + "$VPN_HOST/vdesk/get_token_for_sessid.php3" \ + -o "$WORKDIR/04-token.body" + + otc="$( + awk 'BEGIN{IGNORECASE=1} /^X-ACCESS-Session-Token:/ { sub(/\r$/, ""); print substr($0, index($0, ":") + 2) }' "$TOKEN_HEADERS" | + tail -n 1 + )" + if [ -n "$otc" ]; then + break + fi + + if ! grep -q "ga_code_attempt" "$WORKDIR/03-webtop-${otp_offset}.html"; then + break + fi + done - otc="$( - awk 'BEGIN{IGNORECASE=1} /^X-ACCESS-Session-Token:/ { sub(/\r$/, ""); print substr($0, index($0, ":") + 2) }' "$TOKEN_HEADERS" | - tail -n 1 - )" if [ -z "$otc" ]; then echo "F5 session token 획득 실패" - summarize_html "$WORKDIR/03-webtop.html" + for page in "$WORKDIR"/03-webtop-*.html; do + summarize_html "$page" + done summarize_html "$WORKDIR/04-token.body" exit 1 fi