Skip to content

Instantly share code, notes, and snippets.

@zTrix
Last active December 2, 2023 09:49
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save zTrix/135740a8709cbca461e6 to your computer and use it in GitHub Desktop.
Save zTrix/135740a8709cbca461e6 to your computer and use it in GitHub Desktop.
A simple script to check US Visa state
#!/usr/bin/env python2
import os, sys, datetime, re, urllib, httplib, time
reload(sys)
sys.setdefaultencoding('utf8')
if not sys.stdout.isatty():
import codecs
sys.stdout = codecs.getwriter('utf8')(sys.stdout)
sys.stderr = codecs.getwriter('utf8')(sys.stderr)
import requests
requests.packages.urllib3.disable_warnings()
try:
from termcolor import colored
except:
ATTRIBUTES = dict( list(zip([ 'bold', 'dark', '', 'underline', 'blink', '', 'reverse', 'concealed' ], list(range(1, 9)))))
del ATTRIBUTES['']
HIGHLIGHTS = dict( list(zip([ 'on_grey', 'on_red', 'on_green', 'on_yellow', 'on_blue', 'on_magenta', 'on_cyan', 'on_white' ], list(range(40, 48)))))
COLORS = dict(list(zip(['grey', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white', ], list(range(30, 38)))))
RESET = '\033[0m'
def colored(text, color=None, on_color=None, attrs=None):
fmt_str = '\033[%dm%s'
if color is not None: text = fmt_str % (COLORS[color], text)
if on_color is not None: text = fmt_str % (HIGHLIGHTS[on_color], text)
if attrs is not None:
for attr in attrs:
text = fmt_str % (ATTRIBUTES[attr], text)
text += RESET
return text
def log(s, color = None, on_color = None, attrs = None, new_line = True, timestamp = True, f = sys.stderr):
if timestamp is True:
now = datetime.datetime.now().strftime('[%Y-%m-%d_%H:%M:%S]')
elif timestamp is False:
now = None
elif timestamp:
now = timestamp
if not color:
s = str(s)
else:
s = colored(str(s), color, on_color, attrs)
if now:
f.write(now)
f.write(' ')
f.write(s)
if new_line:
f.write('\n')
f.flush()
def visa_niv_status(location, application_id):
if not location or not application_id:
return None, None, None
target_url = 'https://ceac.state.gov/CEACStatTracker/Status.aspx'
log('[ II ] looking up visa status for %s %s' % (location, application_id))
headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.93 Safari/537.36',
'Cookie': 'ASP.NET_SessionId=mxrhq2454x2cwgueyvmoikqu; ceac.state.gov=1888921792.20480.0000',
'Origin': 'https://ceac.state.gov',
'Referer': 'https://ceac.state.gov/CEACStatTracker/Status.aspx',
'Pragma': 'no-cache',
}
session = requests.Session()
r = session.get(target_url, headers=headers, verify=False)
log('[ II ] [ %s ] %s - %d %s, %d bytes in %fs' % (r.request.method, r.url, r.status_code, r.reason, len(r.text), r.elapsed.total_seconds()))
viewstate_m = re.compile('<input\s+type="hidden"\s+name="__VIEWSTATE"\s+id="__VIEWSTATE"\s+value="([a-z0-9/=+:]+)"\s*/>', re.I).search(r.text)
viewstate = ''
if viewstate_m:
viewstate = viewstate_m.group(1)
valid_m = re.compile('<input\s+type="hidden"\s+name="__EVENTVALIDATION"\s+id="__EVENTVALIDATION"\s+value="([a-z0-9/=+:]+)"\s*/>', re.I).search(r.text)
valid = ''
if valid_m:
valid = valid_m.group(1)
if not valid or not viewstate:
log('[ EE ] cannot extract viewstate or valid: viewstate = %r, valid = %r' % (viewstate, valid), 'red')
return None, None, None
param = urllib.urlencode({
'ctl00$ContentPlaceHolder1$ddlApplications': 'NIV',
'__ASYNCPOST': 'true',
'ctl00_ToolkitScriptManager1_HiddenField': ';;AjaxControlToolkit, Version=3.5.51116.0, Culture=neutral, PublicKeyToken=28f01b0e84b6d53e:en-US:2a06c7e2-728e-4b15-83d6-9b269fb7261e:de1feab2:f2c8e708:8613aea7:f9cec9bc:3202a5a2:a67c2700:720a52bf:589eaa30:ab09e3fe:87104b7c:be6fb298;',
'ctl00$ToolkitScriptManager1': 'ctl00$ContentPlaceHolder1$UpdatePanel1|ctl00$ContentPlaceHolder1$btnSubmit',
'ctl00$ContentPlaceHolder1$btnSubmit.x': 75,
'ctl00$ContentPlaceHolder1$btnSubmit.y': 67,
'__EVENTTARGET': 'ctl00$ContentPlaceHolder1$ddlApplications',
'ctl00$ContentPlaceHolder1$txbCase': '',
'__VIEWSTATE': viewstate,
'__EVENTVALIDATION': valid,
'__EVENTARGUMENT': '',
'__LASTFOCUS': '',
})
headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8'
headers['X-MicrosoftAjax:Delta'] = 'true'
headers['X-Requested-With'] = 'XMLHttpRequest'
r = session.post(target_url, data=param, headers=headers, verify=False)
log('[ II ] [ %s ] %s - %d %s, %d bytes in %fs' % (r.request.method, r.url, r.status_code, r.reason, len(r.text), r.elapsed.total_seconds()))
viewstate_m = re.compile(r'\|__VIEWSTATE\|([a-z0-9/=+]+)\|', re.I).search(r.text)
viewstate = ''
if viewstate_m:
viewstate = viewstate_m.group(1)
valid_m = re.compile(r'\|__EVENTVALIDATION\|([a-z0-9/=+]+)\|', re.I).search(r.text)
valid = ''
if valid_m:
valid = valid_m.group(1)
if not valid or not viewstate:
log('[ EE ] cannot extract viewstate or valid: viewstate = %r, valid = %r' % (viewstate, valid), 'red')
return None, None, None
param = urllib.urlencode({
'ctl00$ContentPlaceHolder1$ddlApplications': 'NIV',
'ctl00$ContentPlaceHolder1$ddlLocation': location,
'ctl00$ContentPlaceHolder1$txbCase': application_id,
'__ASYNCPOST': 'true',
'ctl00_ToolkitScriptManager1_HiddenField': ';;AjaxControlToolkit, Version=3.5.51116.0, Culture=neutral, PublicKeyToken=28f01b0e84b6d53e:en-US:2a06c7e2-728e-4b15-83d6-9b269fb7261e:de1feab2:f2c8e708:8613aea7:f9cec9bc:3202a5a2:a67c2700:720a52bf:589eaa30:ab09e3fe:87104b7c:be6fb298;',
'ctl00$ToolkitScriptManager1': 'ctl00$ContentPlaceHolder1$UpdatePanel1|ctl00$ContentPlaceHolder1$btnSubmit',
'ctl00$ContentPlaceHolder1$btnSubmit.x': 99,
'ctl00$ContentPlaceHolder1$btnSubmit.y': 9,
'__EVENTTARGET': '',
'__EVENTARGUMENT': '',
'__LASTFOCUS': '',
'__VIEWSTATE': viewstate,
'__EVENTVALIDATION': valid
})
r = session.post(target_url, data=param, headers=headers, verify=False)
log('[ II ] [ %s ] %s - %d %s, %d bytes in %fs' % (r.request.method, r.url, r.status_code, r.reason, len(r.text), r.elapsed.total_seconds()))
pivot_m = re.compile(r'<span\s+id="ctl00_ContentPlaceHolder1_ucApplicationStatusView_lblStatus">([-a-z0-9_+\s=:]+)</span>', re.I).search(r.text)
pivot = ''
if pivot_m:
pivot = pivot_m.group(1)
update_m = re.compile(r'<span\s+id="ctl00_ContentPlaceHolder1_ucApplicationStatusView_lblStatusDate">([-a-z0-9_+\s=:]+)</span>', re.I).search(r.text)
update_date = ''
if update_m:
update_date = update_m.group(1)
case_m = re.compile(r'<span\s+id="ctl00_ContentPlaceHolder1_ucApplicationStatusView_lblCaseNo"\s+class="case-number">\s*([-a-z0-9_+=/:]+)\s*</span>', re.I).search(r.text)
case = ''
if case_m:
case = case_m.group(1)
return case, update_date, pivot
def passport_status(passport):
log('[ II ] looking up passport status: %s' % (passport))
headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.93 Safari/537.36',
'Origin': 'http://cgifederal.force.com',
'Referer': 'http://cgifederal.force.com/passporttracker?country=China&language=zh_CN',
'Host': 'cgifederal.force.com',
}
session = requests.Session()
viewstate = ''
mac = ''
version = ''
for x in range(3):
r = session.get('http://cgifederal.force.com/passporttracker?country=China&language=en', headers=headers)
log('[ II ] [ %s ] %s - %d %s, %d bytes in %fs' % (r.request.method, r.url, r.status_code, r.reason, len(r.text), r.elapsed.total_seconds()))
viewstate_m = re.compile(r'<input\s+type="hidden"\s+id="com\.salesforce\.visualforce\.ViewState"\s+name="com\.salesforce\.visualforce\.ViewState"\s+value="\s*([-a-z0-9_+=/:]+)\s*"\s*/?>', re.I).search(r.text)
if viewstate_m:
viewstate = viewstate_m.group(1)
mac_m = re.compile(r'<input\s+type="hidden"\s+id="com\.salesforce\.visualforce\.ViewStateMAC"\s+name="com\.salesforce\.visualforce\.ViewStateMAC"\s+value="([-a-z0-9_+=/:]+)"\s*/?>', re.I).search(r.text)
if mac_m:
mac = mac_m.group(1)
version_m = re.compile(r'<input\s+type="hidden"\s+id="com\.salesforce\.visualforce\.ViewStateVersion"\s+name="com\.salesforce\.visualforce\.ViewStateVersion"\s+value="([-a-z0-9_+=/:]+)"\s*/?>', re.I).search(r.text)
if version_m:
version = version_m.group(1)
if viewstate and mac and version:
break
else:
log('[ II ] viewstate or mac not found, retrying...')
time.sleep(1 << x)
if not viewstate or not mac or not version:
log('[ EE ] cannot extract viewstate or viewstatemac: viewstate = %r, mac = %r, version = %r' % (viewstate, mac, version), 'red')
return None
param = urllib.urlencode({
'AJAXREQUEST': '_viewRoot',
'passportTrackerPage:psptTrackerForm': 'passportTrackerPage:psptTrackerForm',
'passportTrackerPage:psptTrackerForm:j_id34:j_id35:passportNo': passport,
'passportTrackerPage:psptTrackerForm:trackButton': 'passportTrackerPage:psptTrackerForm:trackButton',
'com.salesforce.visualforce.ViewState': viewstate,
'com.salesforce.visualforce.ViewStateMAC': mac,
'com.salesforce.visualforce.ViewStateVersion': version,
})
headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8'
headers['X-MicrosoftAjax:Delta'] = 'true'
headers['X-Requested-With'] = 'XMLHttpRequest'
r = session.post('http://cgifederal.force.com/passporttracker', data=param, headers=headers)
log('[ II ] [ %s ] %s - %d %s, %d bytes in %fs' % (r.request.method, r.url, r.status_code, r.reason, len(r.text), r.elapsed.total_seconds()))
result_m = re.compile(r'<span\s+class="result">([^<>]+)</span>', re.I).search(r.text)
result = ''
if result_m:
result = result_m.group(1)
return result
if __name__ == '__main__':
if len(sys.argv) < 2:
print 'usage: %s <location> <application_id> <passport>' % sys.argv[0]
print 'usage: %s <location> <application_id>' % sys.argv[0]
print 'usage: %s <passport>' % sys.argv[0]
print ''
print 'example:'
print ' # BEJ for beijing'
print ' $ %s BEJ AA01234T8S G12345678' % sys.argv[0]
print ' # GUZ for guangzhou'
print ' $ %s GUZ AA01234T8S' % sys.argv[0]
print ' $ %s G12345678' % sys.argv[0]
sys.exit(10)
if len(sys.argv) >= 4:
location = sys.argv[1]
app_id = sys.argv[2]
passport = sys.argv[3]
caseid, update_date, state = visa_niv_status(location, app_id)
print caseid, update_date, state
print passport_status(passport)
elif len(sys.argv) == 3:
location = sys.argv[1]
app_id = sys.argv[2]
caseid, update_date, state = visa_niv_status(location, app_id)
print caseid, update_date, state
elif len(sys.argv) == 2:
passport = sys.argv[1]
print passport_status(passport)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment